std: Rewrite vec_reserve_shared_actual in Rust

This commit is contained in:
Brian Anderson 2013-06-21 19:40:00 -07:00
parent 95eb01957b
commit aa9210d25a
7 changed files with 67 additions and 45 deletions

View File

@ -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 *()
}
}
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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) {

View File

@ -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

View File

@ -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() {