about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-03-25 07:47:30 +0000
committerbors <bors@rust-lang.org>2015-03-25 07:47:30 +0000
commit928e2e23945493a18bfc658a0adf2c06cb764e83 (patch)
tree83a3522899dc71b360f2da0d886a8578f89c328c
parent593db005d4dbce2ff72009c1ba03477b031b2c0f (diff)
parent0e838f749fd0d532f0cde45ce35a5a9ff8f89533 (diff)
downloadrust-928e2e23945493a18bfc658a0adf2c06cb764e83.tar.gz
rust-928e2e23945493a18bfc658a0adf2c06cb764e83.zip
Auto merge of #23670 - cmr:vec-push-slowpath, r=pcwalton
Makes Vec::push considerably smaller: 25 instructions, rather than 42, on
x86_64.
-rw-r--r--src/libcollections/vec.rs25
1 files changed, 16 insertions, 9 deletions
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index af2daabc2d0..e71077c96c7 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -646,6 +646,20 @@ impl<T> Vec<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn push(&mut self, value: T) {
+        #[cold]
+        #[inline(never)]
+        fn resize<T>(vec: &mut Vec<T>) {
+            let old_size = vec.cap * mem::size_of::<T>();
+            let size = max(old_size, 2 * mem::size_of::<T>()) * 2;
+            if old_size > size { panic!("capacity overflow") }
+            unsafe {
+                let ptr = alloc_or_realloc(*vec.ptr, old_size, size);
+                if ptr.is_null() { ::alloc::oom() }
+                vec.ptr = Unique::new(ptr);
+            }
+            vec.cap = max(vec.cap, 2) * 2;
+        }
+
         if mem::size_of::<T>() == 0 {
             // zero-size types consume no memory, so we can't rely on the
             // address space running out
@@ -653,16 +667,9 @@ impl<T> Vec<T> {
             unsafe { mem::forget(value); }
             return
         }
+
         if self.len == self.cap {
-            let old_size = self.cap * mem::size_of::<T>();
-            let size = max(old_size, 2 * mem::size_of::<T>()) * 2;
-            if old_size > size { panic!("capacity overflow") }
-            unsafe {
-                let ptr = alloc_or_realloc(*self.ptr, old_size, size);
-                if ptr.is_null() { ::alloc::oom() }
-                self.ptr = Unique::new(ptr);
-            }
-            self.cap = max(self.cap, 2) * 2;
+            resize(self);
         }
 
         unsafe {