about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDaniel Micay <danielmicay@gmail.com>2013-07-10 01:06:34 -0700
committerDaniel Micay <danielmicay@gmail.com>2013-07-10 01:06:34 -0700
commitb5e9194836cab666163cf97cfbea6a323edad882 (patch)
tree3eecb13d0262fb05a702f51e0745d3d8c7b47cbe
parent41dcec2fe16e272016ae77d10a6a5ff3a737f192 (diff)
parent6f5be9063ddbfe18ce5321817f782abcd2f55110 (diff)
downloadrust-b5e9194836cab666163cf97cfbea6a323edad882.tar.gz
rust-b5e9194836cab666163cf97cfbea6a323edad882.zip
Merge pull request #7682 from thestinger/vec
vec::with_capacity: do one alloc for non-managed + ptr module improvements
-rw-r--r--src/libstd/ptr.rs12
-rw-r--r--src/libstd/vec.rs21
2 files changed, 26 insertions, 7 deletions
diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs
index 2b42c085009..a9db3cd27b3 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<T>(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<T>(x: *mut T, y: *mut T) {
  */
 #[inline]
 pub unsafe fn replace_ptr<T>(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<T>(dest: *mut T, mut src: T) -> T {
 #[inline(always)]
 pub unsafe fn read_ptr<T>(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
 }
 
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 4b719080f84..825dc4cc187 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -26,7 +26,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;
@@ -95,12 +95,31 @@ pub fn to_owned<T:Copy>(t: &[T]) -> ~[T] {
 }
 
 /// Creates a new vector with a capacity of `capacity`
+#[cfg(stage0)]
 pub fn with_capacity<T>(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<T>(capacity: uint) -> ~[T] {
+    unsafe {
+        if contains_managed::<T>() {
+            let mut vec = ~[];
+            vec.reserve(capacity);
+            vec
+        } else {
+            let alloc = capacity * sys::nonzero_size_of::<T>();
+            let ptr = malloc_raw(alloc + size_of::<raw::VecRepr>()) 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.