Skip to content

Commit 0e838f7

Browse files
committed
libcollections: move Vec::push slow path out
Makes Vec::push considerably smaller: 25 instructions, rather than 42, on x86_64.
1 parent 28a0b25 commit 0e838f7

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

src/libcollections/vec.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -639,23 +639,30 @@ impl<T> Vec<T> {
639639
#[inline]
640640
#[stable(feature = "rust1", since = "1.0.0")]
641641
pub fn push(&mut self, value: T) {
642+
#[cold]
643+
#[inline(never)]
644+
fn resize<T>(vec: &mut Vec<T>) {
645+
let old_size = vec.cap * mem::size_of::<T>();
646+
let size = max(old_size, 2 * mem::size_of::<T>()) * 2;
647+
if old_size > size { panic!("capacity overflow") }
648+
unsafe {
649+
let ptr = alloc_or_realloc(*vec.ptr, old_size, size);
650+
if ptr.is_null() { ::alloc::oom() }
651+
vec.ptr = Unique::new(ptr);
652+
}
653+
vec.cap = max(vec.cap, 2) * 2;
654+
}
655+
642656
if mem::size_of::<T>() == 0 {
643657
// zero-size types consume no memory, so we can't rely on the
644658
// address space running out
645659
self.len = self.len.checked_add(1).expect("length overflow");
646660
unsafe { mem::forget(value); }
647661
return
648662
}
663+
649664
if self.len == self.cap {
650-
let old_size = self.cap * mem::size_of::<T>();
651-
let size = max(old_size, 2 * mem::size_of::<T>()) * 2;
652-
if old_size > size { panic!("capacity overflow") }
653-
unsafe {
654-
let ptr = alloc_or_realloc(*self.ptr, old_size, size);
655-
if ptr.is_null() { ::alloc::oom() }
656-
self.ptr = Unique::new(ptr);
657-
}
658-
self.cap = max(self.cap, 2) * 2;
665+
resize(self);
659666
}
660667

661668
unsafe {

0 commit comments

Comments
 (0)