diff options
| author | Corey Richardson <corey@octayn.net> | 2015-03-24 16:17:15 -0400 |
|---|---|---|
| committer | Corey Richardson <corey@octayn.net> | 2015-03-24 17:12:58 -0400 |
| commit | 0e838f749fd0d532f0cde45ce35a5a9ff8f89533 (patch) | |
| tree | 7261d40c1e6f51f048bd51597b43ccd1333893d2 | |
| parent | 28a0b25f424090255966273994748a9f9901059f (diff) | |
| download | rust-0e838f749fd0d532f0cde45ce35a5a9ff8f89533.tar.gz rust-0e838f749fd0d532f0cde45ce35a5a9ff8f89533.zip | |
libcollections: move Vec::push slow path out
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 b0e8dc7d0b6..91179691d86 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -639,6 +639,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 @@ -646,16 +660,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 { |
