std: Rewrite vec_reserve_shared_actual in Rust
This commit is contained in:
@@ -23,20 +23,6 @@ use vec;
|
|||||||
/// Code for dealing with @-vectors. This is pretty incomplete, and
|
/// Code for dealing with @-vectors. This is pretty incomplete, and
|
||||||
/// contains a bunch of duplication from the code for ~-vectors.
|
/// 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
|
/// Returns the number of elements the vector can hold without reallocating
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn capacity<T>(v: @[T]) -> uint {
|
pub fn capacity<T>(v: @[T]) -> uint {
|
||||||
@@ -189,7 +175,7 @@ pub mod traits {
|
|||||||
pub mod traits {}
|
pub mod traits {}
|
||||||
|
|
||||||
pub mod raw {
|
pub mod raw {
|
||||||
use at_vec::{capacity, rustrt};
|
use at_vec::capacity;
|
||||||
use cast::{transmute, transmute_copy};
|
use cast::{transmute, transmute_copy};
|
||||||
use libc;
|
use libc;
|
||||||
use ptr;
|
use ptr;
|
||||||
@@ -197,6 +183,8 @@ pub mod raw {
|
|||||||
use uint;
|
use uint;
|
||||||
use unstable::intrinsics::{move_val_init};
|
use unstable::intrinsics::{move_val_init};
|
||||||
use vec;
|
use vec;
|
||||||
|
use vec::UnboxedVecRepr;
|
||||||
|
use sys::TypeDesc;
|
||||||
|
|
||||||
pub type VecRepr = vec::raw::VecRepr;
|
pub type VecRepr = vec::raw::VecRepr;
|
||||||
pub type SliceRepr = vec::raw::SliceRepr;
|
pub type SliceRepr = vec::raw::SliceRepr;
|
||||||
@@ -257,9 +245,47 @@ pub mod raw {
|
|||||||
pub unsafe fn reserve<T>(v: &mut @[T], n: uint) {
|
pub unsafe fn reserve<T>(v: &mut @[T], n: uint) {
|
||||||
// Only make the (slow) call into the runtime if we have to
|
// Only make the (slow) call into the runtime if we have to
|
||||||
if capacity(*v) < n {
|
if capacity(*v) < n {
|
||||||
let ptr: **VecRepr = transmute(v);
|
let ptr: *mut *mut VecRepr = transmute(v);
|
||||||
rustrt::vec_reserve_shared_actual(sys::get_type_desc::<T>(),
|
let ty = sys::get_type_desc::<T>();
|
||||||
ptr, n as libc::size_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) {
|
pub fn free(&mut self, box: *OpaqueBox) {
|
||||||
unsafe {
|
unsafe {
|
||||||
return rust_boxed_region_free(self.boxed_region, box);
|
return rust_boxed_region_free(self.boxed_region, box);
|
||||||
@@ -76,5 +82,8 @@ extern {
|
|||||||
fn rust_boxed_region_malloc(region: *BoxedRegion,
|
fn rust_boxed_region_malloc(region: *BoxedRegion,
|
||||||
td: *TypeDesc,
|
td: *TypeDesc,
|
||||||
size: size_t) -> *OpaqueBox;
|
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);
|
fn rust_boxed_region_free(region: *BoxedRegion, box: *OpaqueBox);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,12 +48,8 @@ pub mod rustrt {
|
|||||||
// to ~[] and reserve_shared_actual applies to @[].
|
// to ~[] and reserve_shared_actual applies to @[].
|
||||||
#[fast_ffi]
|
#[fast_ffi]
|
||||||
unsafe fn vec_reserve_shared(t: *sys::TypeDesc,
|
unsafe fn vec_reserve_shared(t: *sys::TypeDesc,
|
||||||
v: **raw::VecRepr,
|
v: *mut *mut raw::VecRepr,
|
||||||
n: libc::size_t);
|
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;
|
use managed;
|
||||||
if capacity(v) < n {
|
if capacity(v) < n {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr: **raw::VecRepr = cast::transmute(v);
|
let ptr: *mut *mut raw::VecRepr = cast::transmute(v);
|
||||||
let td = sys::get_type_desc::<T>();
|
let td = sys::get_type_desc::<T>();
|
||||||
if ((**ptr).box_header.ref_count ==
|
if ((**ptr).box_header.ref_count ==
|
||||||
managed::raw::RC_MANAGED_UNIQUE) {
|
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 {
|
} else {
|
||||||
rustrt::vec_reserve_shared(td, ptr, n as libc::size_t);
|
rustrt::vec_reserve_shared(td, ptr, n as libc::size_t);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,11 +68,10 @@ rust_env_pairs() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern "C" CDECL void
|
extern "C" CDECL void *
|
||||||
vec_reserve_shared_actual(type_desc* ty, rust_vec_box** vp,
|
rust_local_realloc(rust_opaque_box *ptr, size_t size) {
|
||||||
size_t n_elts) {
|
|
||||||
rust_task *task = rust_get_current_task();
|
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.
|
// 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);
|
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
|
extern "C" CDECL void
|
||||||
rust_boxed_region_free(boxed_region *region, rust_opaque_box *box) {
|
rust_boxed_region_free(boxed_region *region, rust_opaque_box *box) {
|
||||||
region->free(box);
|
region->free(box);
|
||||||
|
|||||||
@@ -57,16 +57,6 @@ vec_data(rust_vec *v) {
|
|||||||
return reinterpret_cast<T*>(v->data);
|
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,
|
inline void reserve_vec_exact(rust_vec_box** vpp,
|
||||||
size_t size) {
|
size_t size) {
|
||||||
if (size > (*vpp)->body.alloc) {
|
if (size > (*vpp)->body.alloc) {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ rust_get_stack_segment
|
|||||||
rust_get_c_stack
|
rust_get_c_stack
|
||||||
rust_log_str
|
rust_log_str
|
||||||
start_task
|
start_task
|
||||||
vec_reserve_shared_actual
|
rust_local_realloc
|
||||||
vec_reserve_shared
|
vec_reserve_shared
|
||||||
task_clear_event_reject
|
task_clear_event_reject
|
||||||
task_wait_event
|
task_wait_event
|
||||||
@@ -231,6 +231,7 @@ rust_delete_memory_region
|
|||||||
rust_new_boxed_region
|
rust_new_boxed_region
|
||||||
rust_delete_boxed_region
|
rust_delete_boxed_region
|
||||||
rust_boxed_region_malloc
|
rust_boxed_region_malloc
|
||||||
|
rust_boxed_region_realloc
|
||||||
rust_boxed_region_free
|
rust_boxed_region_free
|
||||||
rust_try
|
rust_try
|
||||||
rust_begin_unwind
|
rust_begin_unwind
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
use std::libc;
|
use std::libc;
|
||||||
use std::sys;
|
|
||||||
use std::vec;
|
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc,
|
pub unsafe fn debug_get_stk_seg() -> *libc::c_void;
|
||||||
v: **vec::raw::VecRepr,
|
|
||||||
n: libc::size_t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
|||||||
Reference in New Issue
Block a user