std: Rewrite vec_reserve_shared_actual in Rust
This commit is contained in:
parent
95eb01957b
commit
aa9210d25a
@ -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 *()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user