Skip to content

small changes to dynamic allocations #17280

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

Closed
wants to merge 3 commits into from
Closed
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
31 changes: 7 additions & 24 deletions src/liballoc/heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// FIXME: #13994: port to the sized deallocation API when available
// FIXME: #13996: mark the `allocate` and `reallocate` return value as `noalias`
// and `nonnull`

#[cfg(not(test))] use core::raw;
#[cfg(stage0, not(test))] use core::raw;
#[cfg(stage0, not(test))] use util;

/// Returns a pointer to `size` bytes of memory.
Expand Down Expand Up @@ -88,18 +86,19 @@ pub fn stats_print() {
imp::stats_print();
}

// The compiler never calls `exchange_free` on Box<ZeroSizeType>, so zero-size
// allocations can point to this `static`. It would be incorrect to use a null
// pointer, due to enums assuming types like unique pointers are never null.
pub static mut EMPTY: uint = 12345;
/// An arbitrary non-null address to represent zero-size allocations.
///
/// This preserves the non-null invariant for types like `Box<T>`. The address may overlap with
/// non-zero-size memory allocations.
pub static EMPTY: *mut () = 0x1 as *mut ();

/// The allocator for unique pointers.
#[cfg(not(test))]
#[lang="exchange_malloc"]
#[inline]
unsafe fn exchange_malloc(size: uint, align: uint) -> *mut u8 {
if size == 0 {
&EMPTY as *const uint as *mut u8
EMPTY as *mut u8
} else {
allocate(size, align)
}
Expand All @@ -112,7 +111,6 @@ unsafe fn exchange_free(ptr: *mut u8, size: uint, align: uint) {
deallocate(ptr, size, align);
}

// FIXME: #7496
#[cfg(stage0, not(test))]
#[lang="closure_exchange_malloc"]
#[inline]
Expand All @@ -128,21 +126,6 @@ unsafe fn closure_exchange_malloc(drop_glue: fn(*mut u8), size: uint,
alloc as *mut u8
}

// FIXME: #7496
#[cfg(not(stage0), not(test))]
#[lang="closure_exchange_malloc"]
#[inline]
#[allow(deprecated)]
unsafe fn closure_exchange_malloc(drop_glue: fn(*mut u8), size: uint,
align: uint) -> *mut u8 {
let p = allocate(size, align);

let alloc = p as *mut raw::Box<()>;
(*alloc).drop_glue = drop_glue;

alloc as *mut u8
}

// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values. In practice, the alignment is a
// constant at the call site and the branch will be optimized out.
Expand Down
10 changes: 3 additions & 7 deletions src/libcollections/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

use core::prelude::*;

use alloc::heap::{allocate, reallocate, deallocate};
use alloc::heap::{EMPTY, allocate, reallocate, deallocate};
use core::cmp::max;
use core::default::Default;
use core::fmt;
Expand All @@ -26,10 +26,6 @@ use {Mutable, MutableSeq};
use slice::{MutableOrdSlice, MutableSliceAllocating, CloneableVector};
use slice::{Items, MutItems};


#[doc(hidden)]
pub static PTR_MARKER: u8 = 0;

/// An owned, growable vector.
///
/// # Examples
Expand Down Expand Up @@ -122,7 +118,7 @@ impl<T> Vec<T> {
// non-null value which is fine since we never call deallocate on the ptr
// if cap is 0. The reason for this is because the pointer of a slice
// being NULL would break the null pointer optimization for enums.
Vec { len: 0, cap: 0, ptr: &PTR_MARKER as *const _ as *mut T }
Vec { len: 0, cap: 0, ptr: EMPTY as *mut T }
}

/// Constructs a new, empty `Vec` with the specified capacity.
Expand Down Expand Up @@ -155,7 +151,7 @@ impl<T> Vec<T> {
#[inline]
pub fn with_capacity(capacity: uint) -> Vec<T> {
if mem::size_of::<T>() == 0 {
Vec { len: 0, cap: uint::MAX, ptr: &PTR_MARKER as *const _ as *mut T }
Vec { len: 0, cap: uint::MAX, ptr: EMPTY as *mut T }
} else if capacity == 0 {
Vec::new()
} else {
Expand Down
1 change: 0 additions & 1 deletion src/librustc/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,6 @@ lets_do_this! {
BeginUnwindLangItem, "begin_unwind", begin_unwind;

ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn;
ClosureExchangeMallocFnLangItem, "closure_exchange_malloc", closure_exchange_malloc_fn;
ExchangeFreeFnLangItem, "exchange_free", exchange_free_fn;
MallocFnLangItem, "malloc", malloc_fn;
FreeFnLangItem, "free", free_fn;
Expand Down
27 changes: 10 additions & 17 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,14 +383,10 @@ pub fn malloc_raw_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
Result::new(r.bcx, PointerCast(r.bcx, r.val, llty_ptr))
}

pub fn malloc_raw_dyn_proc<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
t: ty::t, alloc_fn: LangItem)
-> Result<'blk, 'tcx> {
pub fn malloc_raw_dyn_proc<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: ty::t) -> Result<'blk, 'tcx> {
let _icx = push_ctxt("malloc_raw_dyn_proc");
let ccx = bcx.ccx();

let langcall = require_alloc_fn(bcx, t, alloc_fn);

// Grab the TypeRef type of ptr_ty.
let ptr_ty = ty::mk_uniq(bcx.tcx(), t);
let ptr_llty = type_of(ccx, ptr_ty);
Expand All @@ -399,18 +395,15 @@ pub fn malloc_raw_dyn_proc<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let size = llsize_of(bcx.ccx(), llty);
let llalign = C_uint(ccx, llalign_of_min(bcx.ccx(), llty) as uint);

// Allocate space:
let drop_glue = glue::get_drop_glue(ccx, ty::mk_uniq(bcx.tcx(), t));
let r = callee::trans_lang_call(
bcx,
langcall,
[
PointerCast(bcx, drop_glue, Type::glue_fn(ccx, Type::i8p(ccx)).ptr_to()),
size,
llalign
],
None);
Result::new(r.bcx, PointerCast(r.bcx, r.val, ptr_llty))
// Allocate space and store the destructor pointer:
let Result {bcx: bcx, val: llbox} = malloc_raw_dyn(bcx, ptr_llty, t, size, llalign);
let dtor_ptr = GEPi(bcx, llbox, [0u, abi::box_field_drop_glue]);
let drop_glue_field_ty = type_of(ccx, ty::mk_nil_ptr(bcx.tcx()));
let drop_glue = PointerCast(bcx, glue::get_drop_glue(ccx, ty::mk_uniq(bcx.tcx(), t)),
drop_glue_field_ty);
Store(bcx, drop_glue, dtor_ptr);

Result::new(bcx, llbox)
}


Expand Down
3 changes: 1 addition & 2 deletions src/librustc/middle/trans/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use driver::config::FullDebugInfo;
use llvm::ValueRef;
use middle::def;
use middle::freevars;
use middle::lang_items::ClosureExchangeMallocFnLangItem;
use middle::trans::adt;
use middle::trans::base::*;
use middle::trans::build::*;
Expand Down Expand Up @@ -146,7 +145,7 @@ fn allocate_cbox<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let cbox_ty = tuplify_box_ty(tcx, cdata_ty);
match store {
ty::UniqTraitStore => {
malloc_raw_dyn_proc(bcx, cbox_ty, ClosureExchangeMallocFnLangItem)
malloc_raw_dyn_proc(bcx, cbox_ty)
}
ty::RegionTraitStore(..) => {
let llbox = alloc_ty(bcx, cbox_ty, "__closure");
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: ty::t)
let env_ptr_ty = Type::at_box(bcx.ccx(), Type::i8(bcx.ccx())).ptr_to();
let env = PointerCast(bcx, env, env_ptr_ty);
with_cond(bcx, IsNotNull(bcx, env), |bcx| {
let dtor_ptr = GEPi(bcx, env, [0u, abi::box_field_tydesc]);
let dtor_ptr = GEPi(bcx, env, [0u, abi::box_field_drop_glue]);
let dtor = Load(bcx, dtor_ptr);
Call(bcx, dtor, [PointerCast(bcx, box_cell_v, Type::i8p(bcx.ccx()))], None);
bcx
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_back/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// except according to those terms.

pub static box_field_refcnt: uint = 0u;
pub static box_field_tydesc: uint = 1u;
pub static box_field_drop_glue: uint = 1u;
pub static box_field_body: uint = 4u;

pub static tydesc_field_visit_glue: uint = 3u;
Expand Down
4 changes: 2 additions & 2 deletions src/libsyntax/owned_slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use std::fmt;
use std::default::Default;
use std::hash;
use std::{mem, raw, ptr, slice, vec};
use std::rt::heap::EMPTY;
use serialize::{Encodable, Decodable, Encoder, Decoder};

/// A non-growable owned slice. This would preferably become `~[T]`
Expand Down Expand Up @@ -81,10 +82,9 @@ impl<T> OwnedSlice<T> {
}

pub fn as_slice<'a>(&'a self) -> &'a [T] {
static PTR_MARKER: u8 = 0;
let ptr = if self.data.is_null() {
// length zero, i.e. this will never be read as a T.
&PTR_MARKER as *const u8 as *const T
EMPTY as *const T
} else {
self.data as *const T
};
Expand Down