about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2013-06-21 19:40:00 -0700
committerBrian Anderson <banderson@mozilla.com>2013-06-24 17:07:01 -0700
commitaa9210d25afb3779e1d95722b73b62a7be6274fe (patch)
treed15d99ce3ef4e28d96b5301e79f1d02fc91ef2fd
parent95eb01957bf23922abdf083f677c6c2d6927713a (diff)
downloadrust-aa9210d25afb3779e1d95722b73b62a7be6274fe.tar.gz
rust-aa9210d25afb3779e1d95722b73b62a7be6274fe.zip
std: Rewrite vec_reserve_shared_actual in Rust
-rw-r--r--src/libstd/at_vec.rs62
-rw-r--r--src/libstd/rt/local_heap.rs9
-rw-r--r--src/libstd/vec.rs10
-rw-r--r--src/rt/rust_builtin.cpp12
-rw-r--r--src/rt/rust_util.h10
-rw-r--r--src/rt/rustrt.def.in3
-rw-r--r--src/test/run-pass/extern-pub.rs6
7 files changed, 67 insertions, 45 deletions
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs
index 3875847ff9b..18dfbd82c5a 100644
--- a/src/libstd/at_vec.rs
+++ b/src/libstd/at_vec.rs
@@ -23,20 +23,6 @@ use vec;
 /// Code for dealing with @-vectors. This is pretty incomplete, and
 /// contains a bunch of duplication from the code for ~-vectors.
 
-pub mod rustrt {
-    use libc;
-    use sys;
-    use vec;
-
-    #[abi = "cdecl"]
-    #[link_name = "rustrt"]
-    pub extern {
-        pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc,
-                                                v: **vec::raw::VecRepr,
-                                                n: libc::size_t);
-    }
-}
-
 /// Returns the number of elements the vector can hold without reallocating
 #[inline]
 pub fn capacity<T>(v: @[T]) -> uint {
@@ -189,7 +175,7 @@ pub mod traits {
 pub mod traits {}
 
 pub mod raw {
-    use at_vec::{capacity, rustrt};
+    use at_vec::capacity;
     use cast::{transmute, transmute_copy};
     use libc;
     use ptr;
@@ -197,6 +183,8 @@ pub mod raw {
     use uint;
     use unstable::intrinsics::{move_val_init};
     use vec;
+    use vec::UnboxedVecRepr;
+    use sys::TypeDesc;
 
     pub type VecRepr = vec::raw::VecRepr;
     pub type SliceRepr = vec::raw::SliceRepr;
@@ -257,9 +245,47 @@ pub mod raw {
     pub unsafe fn reserve<T>(v: &mut @[T], n: uint) {
         // Only make the (slow) call into the runtime if we have to
         if capacity(*v) < n {
-            let ptr: **VecRepr = transmute(v);
-            rustrt::vec_reserve_shared_actual(sys::get_type_desc::<T>(),
-                                              ptr, n as libc::size_t);
+            let ptr: *mut *mut VecRepr = transmute(v);
+            let ty = sys::get_type_desc::<T>();
+            return reserve_raw(ty, ptr, n);
+        }
+    }
+
+    // Implementation detail. Shouldn't be public
+    #[allow(missing_doc)]
+    pub fn reserve_raw(ty: *TypeDesc, ptr: *mut *mut VecRepr, n: uint) {
+
+        unsafe {
+            let size_in_bytes = n * (*ty).size;
+            if size_in_bytes > (**ptr).unboxed.alloc {
+                let total_size = size_in_bytes + sys::size_of::<UnboxedVecRepr>();
+                // XXX: UnboxedVecRepr has an extra u8 at the end
+                let total_size = total_size - sys::size_of::<u8>();
+                (*ptr) = local_realloc(*ptr as *(), total_size) as *mut VecRepr;
+                (**ptr).unboxed.alloc = size_in_bytes;
+            }
+        }
+
+        fn local_realloc(ptr: *(), size: uint) -> *() {
+            use rt;
+            use rt::OldTaskContext;
+            use rt::local::Local;
+            use rt::task::Task;
+
+            if rt::context() == OldTaskContext {
+                unsafe {
+                    return rust_local_realloc(ptr, size as libc::size_t);
+                }
+
+                extern {
+                    #[fast_ffi]
+                    fn rust_local_realloc(ptr: *(), size: libc::size_t) -> *();
+                }
+            } else {
+                do Local::borrow::<Task, *()> |task| {
+                    task.heap.realloc(ptr as *libc::c_void, size) as *()
+                }
+            }
         }
     }
 
diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs
index 6bf228a1b22..38cd25f9da5 100644
--- a/src/libstd/rt/local_heap.rs
+++ b/src/libstd/rt/local_heap.rs
@@ -49,6 +49,12 @@ impl LocalHeap {
         }
     }
 
+    pub fn realloc(&mut self, ptr: *OpaqueBox, size: uint) -> *OpaqueBox {
+        unsafe {
+            return rust_boxed_region_realloc(self.boxed_region, ptr, size as size_t);
+        }
+    }
+
     pub fn free(&mut self, box: *OpaqueBox) {
         unsafe {
             return rust_boxed_region_free(self.boxed_region, box);
@@ -76,5 +82,8 @@ extern {
     fn rust_boxed_region_malloc(region: *BoxedRegion,
                                 td: *TypeDesc,
                                 size: size_t) -> *OpaqueBox;
+    fn rust_boxed_region_realloc(region: *BoxedRegion,
+                                 ptr: *OpaqueBox,
+                                 size: size_t) -> *OpaqueBox;
     fn rust_boxed_region_free(region: *BoxedRegion, box: *OpaqueBox);
 }
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 7f683d0070f..4339153c43e 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -48,12 +48,8 @@ pub mod rustrt {
         // to ~[] and reserve_shared_actual applies to @[].
         #[fast_ffi]
         unsafe fn vec_reserve_shared(t: *sys::TypeDesc,
-                                     v: **raw::VecRepr,
+                                     v: *mut *mut raw::VecRepr,
                                      n: libc::size_t);
-        #[fast_ffi]
-        unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc,
-                                            v: **raw::VecRepr,
-                                            n: libc::size_t);
     }
 }
 
@@ -79,11 +75,11 @@ pub fn reserve<T>(v: &mut ~[T], n: uint) {
     use managed;
     if capacity(v) < n {
         unsafe {
-            let ptr: **raw::VecRepr = cast::transmute(v);
+            let ptr: *mut *mut raw::VecRepr = cast::transmute(v);
             let td = sys::get_type_desc::<T>();
             if ((**ptr).box_header.ref_count ==
                 managed::raw::RC_MANAGED_UNIQUE) {
-                rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t);
+                ::at_vec::raw::reserve_raw(td, ptr, n);
             } else {
                 rustrt::vec_reserve_shared(td, ptr, n as libc::size_t);
             }
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index f0b68d4a156..9ed389b178a 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -68,11 +68,10 @@ rust_env_pairs() {
 }
 #endif
 
-extern "C" CDECL void
-vec_reserve_shared_actual(type_desc* ty, rust_vec_box** vp,
-                          size_t n_elts) {
+extern "C" CDECL void *
+rust_local_realloc(rust_opaque_box *ptr, size_t size) {
     rust_task *task = rust_get_current_task();
-    reserve_vec_exact_shared(task, vp, n_elts * ty->size);
+    return task->boxed.realloc(ptr, size);
 }
 
 // This is completely misnamed.
@@ -899,6 +898,11 @@ rust_boxed_region_malloc(boxed_region *region, type_desc *td, size_t size) {
     return region->malloc(td, size);
 }
 
+extern "C" CDECL rust_opaque_box*
+rust_boxed_region_realloc(boxed_region *region, rust_opaque_box *ptr, size_t size) {
+    return region->realloc(ptr, size);
+}
+
 extern "C" CDECL void
 rust_boxed_region_free(boxed_region *region, rust_opaque_box *box) {
     region->free(box);
diff --git a/src/rt/rust_util.h b/src/rt/rust_util.h
index 5b8378b0ad3..242c2ef0a81 100644
--- a/src/rt/rust_util.h
+++ b/src/rt/rust_util.h
@@ -57,16 +57,6 @@ vec_data(rust_vec *v) {
     return reinterpret_cast<T*>(v->data);
 }
 
-inline void reserve_vec_exact_shared(rust_task* task, rust_vec_box** vpp,
-                                     size_t size) {
-    rust_opaque_box** ovpp = (rust_opaque_box**)vpp;
-    if (size > (*vpp)->body.alloc) {
-        *vpp = (rust_vec_box*)task->boxed.realloc(
-            *ovpp, size + sizeof(rust_vec));
-        (*vpp)->body.alloc = size;
-    }
-}
-
 inline void reserve_vec_exact(rust_vec_box** vpp,
                               size_t size) {
     if (size > (*vpp)->body.alloc) {
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index 950662b91f8..9add8d537af 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -53,7 +53,7 @@ rust_get_stack_segment
 rust_get_c_stack
 rust_log_str
 start_task
-vec_reserve_shared_actual
+rust_local_realloc
 vec_reserve_shared
 task_clear_event_reject
 task_wait_event
@@ -231,6 +231,7 @@ rust_delete_memory_region
 rust_new_boxed_region
 rust_delete_boxed_region
 rust_boxed_region_malloc
+rust_boxed_region_realloc
 rust_boxed_region_free
 rust_try
 rust_begin_unwind
diff --git a/src/test/run-pass/extern-pub.rs b/src/test/run-pass/extern-pub.rs
index 29b0457fc05..e722c4f5c6a 100644
--- a/src/test/run-pass/extern-pub.rs
+++ b/src/test/run-pass/extern-pub.rs
@@ -1,11 +1,7 @@
 use std::libc;
-use std::sys;
-use std::vec;
 
 extern {
-    pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc,
-                                            v: **vec::raw::VecRepr,
-                                            n: libc::size_t);
+    pub unsafe fn debug_get_stk_seg() -> *libc::c_void;
 }
 
 pub fn main() {