diff options
| author | bors <bors@rust-lang.org> | 2015-03-25 07:47:30 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-03-25 07:47:30 +0000 |
| commit | 928e2e23945493a18bfc658a0adf2c06cb764e83 (patch) | |
| tree | 83a3522899dc71b360f2da0d886a8578f89c328c | |
| parent | 593db005d4dbce2ff72009c1ba03477b031b2c0f (diff) | |
| parent | 0e838f749fd0d532f0cde45ce35a5a9ff8f89533 (diff) | |
| download | rust-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.rs | 25 |
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 { |
