diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index 3875847ff9bb..18dfbd82c5ae 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(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(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::(), - ptr, n as libc::size_t); + let ptr: *mut *mut VecRepr = transmute(v); + let ty = sys::get_type_desc::(); + 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::(); + // XXX: UnboxedVecRepr has an extra u8 at the end + let total_size = total_size - sys::size_of::(); + (*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.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 6bf228a1b220..38cd25f9da5d 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 7f683d0070fb..4339153c43ee 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(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::(); 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 f0b68d4a1569..9ed389b178ae 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 5b8378b0ad35..242c2ef0a81a 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(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 950662b91f8e..9add8d537af0 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 29b0457fc050..e722c4f5c6a9 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() {