diff options
| author | Brian Anderson <banderson@mozilla.com> | 2013-06-21 19:40:00 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2013-06-24 17:07:01 -0700 |
| commit | aa9210d25afb3779e1d95722b73b62a7be6274fe (patch) | |
| tree | d15d99ce3ef4e28d96b5301e79f1d02fc91ef2fd | |
| parent | 95eb01957bf23922abdf083f677c6c2d6927713a (diff) | |
| download | rust-aa9210d25afb3779e1d95722b73b62a7be6274fe.tar.gz rust-aa9210d25afb3779e1d95722b73b62a7be6274fe.zip | |
std: Rewrite vec_reserve_shared_actual in Rust
| -rw-r--r-- | src/libstd/at_vec.rs | 62 | ||||
| -rw-r--r-- | src/libstd/rt/local_heap.rs | 9 | ||||
| -rw-r--r-- | src/libstd/vec.rs | 10 | ||||
| -rw-r--r-- | src/rt/rust_builtin.cpp | 12 | ||||
| -rw-r--r-- | src/rt/rust_util.h | 10 | ||||
| -rw-r--r-- | src/rt/rustrt.def.in | 3 | ||||
| -rw-r--r-- | src/test/run-pass/extern-pub.rs | 6 |
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() { |
