Skip to content

more work leading up to exchange allocation header removal #7521

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 1, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 37 additions & 19 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,25 +258,43 @@ pub fn malloc_raw_dyn(bcx: block,
}
};

// Grab the TypeRef type of box_ptr_ty.
let box_ptr_ty = mk_fn(bcx.tcx(), t);
let llty = type_of(ccx, box_ptr_ty);

// Get the tydesc for the body:
let static_ti = get_tydesc(ccx, t);
glue::lazily_emit_all_tydesc_glue(ccx, static_ti);

// Allocate space:
let tydesc = PointerCast(bcx, static_ti.tydesc, Type::i8p());
let rval = alloca(bcx, Type::i8p());
let bcx = callee::trans_lang_call(
bcx,
langcall,
[tydesc, size],
expr::SaveIn(rval));
let r = rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty));
maybe_set_managed_unique_rc(r.bcx, r.val, heap);
r
if heap == heap_exchange {
// Grab the TypeRef type of box_ptr_ty.
let box_ptr_ty = mk_fn(bcx.tcx(), t);
let llty = type_of(ccx, box_ptr_ty);

let llty_value = type_of::type_of(ccx, t);
let llalign = llalign_of_min(ccx, llty_value);

// Allocate space:
let rval = alloca(bcx, Type::i8p());
let bcx = callee::trans_lang_call(
bcx,
langcall,
[C_i32(llalign as i32), size],
expr::SaveIn(rval));
rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty))
} else {
// Grab the TypeRef type of box_ptr_ty.
let box_ptr_ty = mk_fn(bcx.tcx(), t);
let llty = type_of(ccx, box_ptr_ty);

// Get the tydesc for the body:
let static_ti = get_tydesc(ccx, t);
glue::lazily_emit_all_tydesc_glue(ccx, static_ti);

// Allocate space:
let tydesc = PointerCast(bcx, static_ti.tydesc, Type::i8p());
let rval = alloca(bcx, Type::i8p());
let bcx = callee::trans_lang_call(
bcx,
langcall,
[tydesc, size],
expr::SaveIn(rval));
let r = rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty));
maybe_set_managed_unique_rc(r.bcx, r.val, heap);
r
}
}

// malloc_raw: expects an unboxed type and returns a pointer to
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/libc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1945,7 +1945,7 @@ pub mod funcs {
#[fast_ffi]
unsafe fn malloc(size: size_t) -> *c_void;
#[fast_ffi]
unsafe fn realloc(p: *c_void, size: size_t) -> *c_void;
unsafe fn realloc(p: *mut c_void, size: size_t) -> *mut c_void;
#[fast_ffi]
unsafe fn free(p: *c_void);
unsafe fn abort() -> !;
Expand Down
25 changes: 17 additions & 8 deletions src/libstd/rt/global_heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use libc::{c_char, c_void, size_t, uintptr_t, free, malloc};
use libc::{c_char, c_void, size_t, uintptr_t, free, malloc, realloc};
use managed::raw::{BoxHeaderRepr, BoxRepr};
use unstable::intrinsics::TyDesc;
use sys::size_of;
Expand All @@ -18,6 +18,7 @@ extern {
fn abort();
}

#[inline]
fn get_box_size(body_size: uint, body_align: uint) -> uint {
let header_size = size_of::<BoxHeaderRepr>();
// FIXME (#2699): This alignment calculation is suspicious. Is it right?
Expand All @@ -27,12 +28,14 @@ fn get_box_size(body_size: uint, body_align: uint) -> uint {

// Rounds |size| to the nearest |alignment|. Invariant: |alignment| is a power
// of two.
#[inline]
fn align_to(size: uint, align: uint) -> uint {
assert!(align != 0);
(size + align - 1) & !(align - 1)
}

/// A wrapper around libc::malloc, aborting on out-of-memory
#[inline]
pub unsafe fn malloc_raw(size: uint) -> *c_void {
let p = malloc(size as size_t);
if p.is_null() {
Expand All @@ -42,6 +45,17 @@ pub unsafe fn malloc_raw(size: uint) -> *c_void {
p
}

/// A wrapper around libc::realloc, aborting on out-of-memory
#[inline]
pub unsafe fn realloc_raw(ptr: *mut c_void, size: uint) -> *mut c_void {
let p = realloc(ptr, size as size_t);
if p.is_null() {
// we need a non-allocating way to print an error here
abort();
}
p
}

// FIXME #4942: Make these signatures agree with exchange_alloc's signatures
#[cfg(stage0, not(test))]
#[lang="exchange_malloc"]
Expand All @@ -66,13 +80,8 @@ pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
#[cfg(not(stage0), not(test))]
#[lang="exchange_malloc"]
#[inline]
pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
let td = td as *TyDesc;
let size = size as uint;

assert!(td.is_not_null());

let total_size = get_box_size(size, (*td).align);
pub unsafe fn exchange_malloc(align: u32, size: uintptr_t) -> *c_char {
let total_size = get_box_size(size as uint, align as uint);
malloc_raw(total_size as uint) as *c_char
}

Expand Down
26 changes: 14 additions & 12 deletions src/libstd/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ use iterator::{FromIterator, Iterator, IteratorUtil};
use iter::FromIter;
use kinds::Copy;
use libc;
use libc::c_void;
use num::Zero;
use ops::Add;
use option::{None, Option, Some};
use ptr::to_unsafe_ptr;
use ptr;
use ptr::RawPtr;
use rt::global_heap::realloc_raw;
use sys;
use sys::size_of;
use uint;
Expand All @@ -52,12 +54,6 @@ pub mod rustrt {

#[abi = "cdecl"]
pub extern {
// These names are terrible. reserve_shared applies
// to ~[] and reserve_shared_actual applies to @[].
#[fast_ffi]
unsafe fn vec_reserve_shared(t: *TyDesc,
v: **raw::VecRepr,
n: libc::size_t);
#[fast_ffi]
unsafe fn vec_reserve_shared_actual(t: *TyDesc,
v: **raw::VecRepr,
Expand Down Expand Up @@ -1523,13 +1519,16 @@ impl<T> OwnedVector<T> for ~[T] {
use managed;
if self.capacity() < n {
unsafe {
let ptr: **raw::VecRepr = cast::transmute(self);
let ptr: *mut *mut raw::VecRepr = cast::transmute(self);
let td = get_tydesc::<T>();
if ((**ptr).box_header.ref_count ==
managed::raw::RC_MANAGED_UNIQUE) {
rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t);
rustrt::vec_reserve_shared_actual(td, ptr as **raw::VecRepr, n as libc::size_t);
} else {
rustrt::vec_reserve_shared(td, ptr, n as libc::size_t);
let alloc = n * sys::nonzero_size_of::<T>();
*ptr = realloc_raw(*ptr as *mut c_void, alloc + size_of::<raw::VecRepr>())
as *mut raw::VecRepr;
(**ptr).unboxed.alloc = alloc;
}
}
}
Expand All @@ -1551,12 +1550,15 @@ impl<T> OwnedVector<T> for ~[T] {
// Only make the (slow) call into the runtime if we have to
if self.capacity() < n {
unsafe {
let ptr: **raw::VecRepr = cast::transmute(self);
let ptr: *mut *mut raw::VecRepr = cast::transmute(self);
let td = get_tydesc::<T>();
if contains_managed::<T>() {
rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t);
rustrt::vec_reserve_shared_actual(td, ptr as **raw::VecRepr, n as libc::size_t);
} else {
rustrt::vec_reserve_shared(td, ptr, n as libc::size_t);
let alloc = n * sys::nonzero_size_of::<T>();
*ptr = realloc_raw(*ptr as *mut c_void, alloc + size_of::<raw::VecRepr>())
as *mut raw::VecRepr;
(**ptr).unboxed.alloc = alloc;
}
}
}
Expand Down
7 changes: 0 additions & 7 deletions src/rt/rust_builtin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,6 @@ vec_reserve_shared_actual(type_desc* ty, rust_vec_box** vp,
reserve_vec_exact_shared(task, vp, n_elts * ty->size);
}

// This is completely misnamed.
extern "C" CDECL void
vec_reserve_shared(type_desc* ty, rust_vec_box** vp,
size_t n_elts) {
reserve_vec_exact(vp, n_elts * ty->size);
}

extern "C" CDECL size_t
rand_seed_size() {
return rng_seed_size();
Expand Down
1 change: 0 additions & 1 deletion src/rt/rustrt.def.in
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ rust_get_c_stack
rust_log_str
start_task
vec_reserve_shared_actual
vec_reserve_shared
task_clear_event_reject
task_wait_event
task_signal_event
Expand Down