From f74250e3a970f81388a73aeb8f3d53304d77c34b Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Tue, 9 Jul 2013 21:59:30 -0400 Subject: [PATCH 1/2] vec::with_capacity: do one alloc for non-managed --- src/libstd/vec.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 2d730b7a6a200..0b29caacb7a35 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -27,7 +27,7 @@ use option::{None, Option, Some}; use ptr::to_unsafe_ptr; use ptr; use ptr::RawPtr; -use rt::global_heap::realloc_raw; +use rt::global_heap::{malloc_raw, realloc_raw}; use sys; use sys::size_of; use uint; @@ -101,12 +101,31 @@ pub fn to_owned(t: &[T]) -> ~[T] { } /// Creates a new vector with a capacity of `capacity` +#[cfg(stage0)] pub fn with_capacity(capacity: uint) -> ~[T] { let mut vec = ~[]; vec.reserve(capacity); vec } +/// Creates a new vector with a capacity of `capacity` +#[cfg(not(stage0))] +pub fn with_capacity(capacity: uint) -> ~[T] { + unsafe { + if contains_managed::() { + let mut vec = ~[]; + vec.reserve(capacity); + vec + } else { + let alloc = capacity * sys::nonzero_size_of::(); + let ptr = malloc_raw(alloc + size_of::()) as *mut raw::VecRepr; + (*ptr).unboxed.alloc = alloc; + (*ptr).unboxed.fill = 0; + cast::transmute(ptr) + } + } +} + /** * Builds a vector by calling a provided function with an argument * function that pushes an element to the back of a vector. From 6f5be9063ddbfe18ce5321817f782abcd2f55110 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Tue, 9 Jul 2013 15:22:18 -0400 Subject: [PATCH 2/2] ptr: optimize {swap,replace,read}_ptr --- src/libstd/ptr.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index 2b42c085009df..a9db3cd27b369 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -14,6 +14,7 @@ use cast; use option::{Option, Some, None}; use sys; use unstable::intrinsics; +use util::swap; #[cfg(not(test))] use cmp::{Eq, Ord}; use uint; @@ -177,9 +178,9 @@ pub unsafe fn swap_ptr(x: *mut T, y: *mut T) { let t: *mut T = &mut tmp; // Perform the swap - copy_memory(t, x, 1); - copy_memory(x, y, 1); - copy_memory(y, t, 1); + copy_nonoverlapping_memory(t, x, 1); + copy_memory(x, y, 1); // `x` and `y` may overlap + copy_nonoverlapping_memory(y, t, 1); // y and t now point to the same thing, but we need to completely forget `tmp` // because it's no longer relevant. @@ -192,7 +193,7 @@ pub unsafe fn swap_ptr(x: *mut T, y: *mut T) { */ #[inline] pub unsafe fn replace_ptr(dest: *mut T, mut src: T) -> T { - swap_ptr(dest, &mut src); + swap(cast::transmute(dest), &mut src); // cannot overlap src } @@ -202,8 +203,7 @@ pub unsafe fn replace_ptr(dest: *mut T, mut src: T) -> T { #[inline(always)] pub unsafe fn read_ptr(src: *mut T) -> T { let mut tmp: T = intrinsics::uninit(); - let t: *mut T = &mut tmp; - copy_memory(t, src, 1); + copy_nonoverlapping_memory(&mut tmp, src, 1); tmp }