Skip to content

Commit

Permalink
auto merge of #7495 : thestinger/rust/exchange, r=cmr
Browse files Browse the repository at this point in the history
With these changes, exchange allocator headers are never initialized, read or written to. Removing the header will now just involve updating the code in trans using an offset to only do it if the type contained is managed.

The only thing blocking removing the initialization of the last field in the header was ~fn since it uses it to store the dynamic size/types due to captures. I temporarily switched it to a `closure_exchange_alloc` lang item (it uses the same `exchange_free`) and #7496 is filed about removing that.

Since the `exchange_free` call is now inlined all over the codebase, I don't think we should have an assert for null. It doesn't currently ever happen, but it would be fine if we started generating code that did do it. The `exchange_free` function also had a comment declaring that it must not fail, but a regular assert would cause a failure. I also removed the atomic counter because valgrind can already find these leaks, and we have valgrind bots now.

Note that exchange free does not currently print an error an out-of-memory when it aborts, because our `io` code may allocate. We could probably get away with a `#[rust_stack]` call to a `stdio` function but it would be better to make a write system call.
  • Loading branch information
bors committed Jun 30, 2013
2 parents ca835f4 + 4a29d6e commit 040ac2a
Show file tree
Hide file tree
Showing 20 changed files with 207 additions and 261 deletions.
136 changes: 71 additions & 65 deletions src/librustc/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,63 +32,64 @@ use syntax::visit::visit_crate;
use std::hashmap::HashMap;

pub enum LangItem {
FreezeTraitLangItem, // 0
CopyTraitLangItem, // 1
SendTraitLangItem, // 2
SizedTraitLangItem, // 3

DropTraitLangItem, // 4

AddTraitLangItem, // 5
SubTraitLangItem, // 6
MulTraitLangItem, // 7
DivTraitLangItem, // 8
RemTraitLangItem, // 9
NegTraitLangItem, // 10
NotTraitLangItem, // 11
BitXorTraitLangItem, // 11
BitAndTraitLangItem, // 13
BitOrTraitLangItem, // 14
ShlTraitLangItem, // 15
ShrTraitLangItem, // 16
IndexTraitLangItem, // 17

EqTraitLangItem, // 18
OrdTraitLangItem, // 19

StrEqFnLangItem, // 20
UniqStrEqFnLangItem, // 21
AnnihilateFnLangItem, // 22
LogTypeFnLangItem, // 23
FailFnLangItem, // 24
FailBoundsCheckFnLangItem, // 25
ExchangeMallocFnLangItem, // 26
ExchangeFreeFnLangItem, // 27
MallocFnLangItem, // 28
FreeFnLangItem, // 29
BorrowAsImmFnLangItem, // 30
BorrowAsMutFnLangItem, // 31
ReturnToMutFnLangItem, // 32
CheckNotBorrowedFnLangItem, // 33
StrDupUniqFnLangItem, // 34
RecordBorrowFnLangItem, // 35
UnrecordBorrowFnLangItem, // 36

StartFnLangItem, // 37

TyDescStructLangItem, // 38
TyVisitorTraitLangItem, // 39
OpaqueStructLangItem, // 40
FreezeTraitLangItem, // 0
CopyTraitLangItem, // 1
SendTraitLangItem, // 2
SizedTraitLangItem, // 3

DropTraitLangItem, // 4

AddTraitLangItem, // 5
SubTraitLangItem, // 6
MulTraitLangItem, // 7
DivTraitLangItem, // 8
RemTraitLangItem, // 9
NegTraitLangItem, // 10
NotTraitLangItem, // 11
BitXorTraitLangItem, // 11
BitAndTraitLangItem, // 13
BitOrTraitLangItem, // 14
ShlTraitLangItem, // 15
ShrTraitLangItem, // 16
IndexTraitLangItem, // 17

EqTraitLangItem, // 18
OrdTraitLangItem, // 19

StrEqFnLangItem, // 20
UniqStrEqFnLangItem, // 21
AnnihilateFnLangItem, // 22
LogTypeFnLangItem, // 23
FailFnLangItem, // 24
FailBoundsCheckFnLangItem, // 25
ExchangeMallocFnLangItem, // 26
ClosureExchangeMallocFnLangItem, // 27
ExchangeFreeFnLangItem, // 28
MallocFnLangItem, // 29
FreeFnLangItem, // 30
BorrowAsImmFnLangItem, // 31
BorrowAsMutFnLangItem, // 32
ReturnToMutFnLangItem, // 33
CheckNotBorrowedFnLangItem, // 34
StrDupUniqFnLangItem, // 35
RecordBorrowFnLangItem, // 36
UnrecordBorrowFnLangItem, // 37

StartFnLangItem, // 38

TyDescStructLangItem, // 39
TyVisitorTraitLangItem, // 40
OpaqueStructLangItem, // 41
}

pub struct LanguageItems {
items: [Option<def_id>, ..41]
items: [Option<def_id>, ..42]
}

impl LanguageItems {
pub fn new() -> LanguageItems {
LanguageItems {
items: [ None, ..41 ]
items: [ None, ..42 ]
}
}

Expand Down Expand Up @@ -128,22 +129,23 @@ impl LanguageItems {
24 => "fail_",
25 => "fail_bounds_check",
26 => "exchange_malloc",
27 => "exchange_free",
28 => "malloc",
29 => "free",
30 => "borrow_as_imm",
31 => "borrow_as_mut",
32 => "return_to_mut",
33 => "check_not_borrowed",
34 => "strdup_uniq",
35 => "record_borrow",
36 => "unrecord_borrow",

37 => "start",

38 => "ty_desc",
39 => "ty_visitor",
40 => "opaque",
27 => "closure_exchange_malloc",
28 => "exchange_free",
29 => "malloc",
30 => "free",
31 => "borrow_as_imm",
32 => "borrow_as_mut",
33 => "return_to_mut",
34 => "check_not_borrowed",
35 => "strdup_uniq",
36 => "record_borrow",
37 => "unrecord_borrow",

38 => "start",

39 => "ty_desc",
40 => "ty_visitor",
41 => "opaque",

_ => "???"
}
Expand Down Expand Up @@ -236,6 +238,9 @@ impl LanguageItems {
pub fn exchange_malloc_fn(&self) -> def_id {
self.items[ExchangeMallocFnLangItem as uint].get()
}
pub fn closure_exchange_malloc_fn(&self) -> def_id {
self.items[ClosureExchangeMallocFnLangItem as uint].get()
}
pub fn exchange_free_fn(&self) -> def_id {
self.items[ExchangeFreeFnLangItem as uint].get()
}
Expand Down Expand Up @@ -326,6 +331,7 @@ impl<'self> LanguageItemCollector<'self> {
item_refs.insert(@"fail_bounds_check",
FailBoundsCheckFnLangItem as uint);
item_refs.insert(@"exchange_malloc", ExchangeMallocFnLangItem as uint);
item_refs.insert(@"closure_exchange_malloc", ClosureExchangeMallocFnLangItem as uint);
item_refs.insert(@"exchange_free", ExchangeFreeFnLangItem as uint);
item_refs.insert(@"malloc", MallocFnLangItem as uint);
item_refs.insert(@"free", FreeFnLangItem as uint);
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,9 @@ pub fn malloc_raw_dyn(bcx: block,
heap_exchange => {
(ty::mk_imm_uniq, bcx.tcx().lang_items.exchange_malloc_fn())
}
heap_exchange_closure => {
(ty::mk_imm_uniq, bcx.tcx().lang_items.closure_exchange_malloc_fn())
}
};

// Grab the TypeRef type of box_ptr_ty.
Expand Down
12 changes: 10 additions & 2 deletions src/librustc/middle/trans/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,14 @@ pub fn mk_closure_tys(tcx: ty::ctxt,
return cdata_ty;
}

fn heap_for_unique_closure(bcx: block, t: ty::t) -> heap {
if ty::type_contents(bcx.tcx(), t).contains_managed() {
heap_managed_unique
} else {
heap_exchange_closure
}
}

pub fn allocate_cbox(bcx: block, sigil: ast::Sigil, cdata_ty: ty::t)
-> Result {
let _icx = push_ctxt("closure::allocate_cbox");
Expand All @@ -181,7 +189,7 @@ pub fn allocate_cbox(bcx: block, sigil: ast::Sigil, cdata_ty: ty::t)
malloc_raw(bcx, cdata_ty, heap_managed)
}
ast::OwnedSigil => {
malloc_raw(bcx, cdata_ty, heap_for_unique(bcx, cdata_ty))
malloc_raw(bcx, cdata_ty, heap_for_unique_closure(bcx, cdata_ty))
}
ast::BorrowedSigil => {
let cbox_ty = tuplify_box_ty(tcx, cdata_ty);
Expand Down Expand Up @@ -526,7 +534,7 @@ pub fn make_opaque_cbox_take_glue(
let rval = alloca(bcx, Type::i8p());
let bcx = callee::trans_lang_call(
bcx,
bcx.tcx().lang_items.exchange_malloc_fn(),
bcx.tcx().lang_items.closure_exchange_malloc_fn(),
[opaque_tydesc, sz],
expr::SaveIn(rval));
let cbox_out = PointerCast(bcx, Load(bcx, rval), llopaquecboxty);
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ pub enum heap {
heap_managed,
heap_managed_unique,
heap_exchange,
heap_exchange_closure
}

#[deriving(Eq)]
Expand Down Expand Up @@ -384,7 +385,7 @@ pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) {
let f: @fn(block) -> block = |a| glue::trans_free(a, ptr);
f
}
heap_exchange => {
heap_exchange | heap_exchange_closure => {
let f: @fn(block) -> block = |a| glue::trans_exchange_free(a, ptr);
f
}
Expand Down
6 changes: 6 additions & 0 deletions src/librustc/middle/trans/foreign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,12 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
C_bool(ty::type_needs_drop(ccx.tcx, tp_ty)),
fcx.llretptr.get());
}
"contains_managed" => {
let tp_ty = substs.tys[0];
Store(bcx,
C_bool(ty::type_contents(ccx.tcx, tp_ty).contains_managed()),
fcx.llretptr.get());
}
"visit_tydesc" => {
let td = get_param(decl, first_real_arg);
let visitor = get_param(decl, first_real_arg + 1u);
Expand Down
1 change: 1 addition & 0 deletions src/librustc/middle/trans/tvec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, heap: heap, vstore_expr: @ast::e
_ => {}
}
}
heap_exchange_closure => fail!("vectors are not allocated with closure_exchange_alloc"),
heap_managed | heap_managed_unique => {}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/type_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint)
"uninit" | "init" | "transmute" | "move_val" |
"move_val_init" => use_repr,

"get_tydesc" | "needs_drop" => use_tydesc,
"get_tydesc" | "needs_drop" | "contains_managed" => use_tydesc,

"visit_tydesc" | "forget" | "frame_address" |
"morestack_addr" => 0,
Expand Down
10 changes: 1 addition & 9 deletions src/librustc/middle/trans/uniq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,5 @@ pub fn duplicate(bcx: block, src_box: ValueRef, src_ty: ty::t) -> Result {
} = malloc_unique(bcx, body_datum.ty);
body_datum.copy_to(bcx, datum::INIT, dst_body);

// Copy the type descriptor
let src_tydesc_ptr = GEPi(bcx, src_box,
[0u, back::abi::box_field_tydesc]);
let dst_tydesc_ptr = GEPi(bcx, dst_box,
[0u, back::abi::box_field_tydesc]);
let td = Load(bcx, src_tydesc_ptr);
Store(bcx, td, dst_tydesc_ptr);

return rslt(bcx, dst_box);
rslt(bcx, dst_box)
}
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3539,7 +3539,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
ty::mk_nil())
}
"needs_drop" => (1u, ~[], ty::mk_bool()),

"contains_managed" => (1u, ~[], ty::mk_bool()),
"atomic_xchg" | "atomic_xadd" | "atomic_xsub" |
"atomic_xchg_acq" | "atomic_xadd_acq" | "atomic_xsub_acq" |
"atomic_xchg_rel" | "atomic_xadd_rel" | "atomic_xsub_rel" => {
Expand Down
1 change: 0 additions & 1 deletion src/libstd/managed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use ptr::to_unsafe_ptr;
pub mod raw {
use std::unstable::intrinsics::TyDesc;

pub static RC_EXCHANGE_UNIQUE : uint = (-1) as uint;
pub static RC_MANAGED_UNIQUE : uint = (-2) as uint;
pub static RC_IMMORTAL : uint = 0x77777777;

Expand Down
6 changes: 3 additions & 3 deletions src/libstd/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ pub fn list_dir(p: &Path) -> ~[~str] {
#[cfg(windows)]
unsafe fn get_list(p: &Path) -> ~[~str] {
use libc::consts::os::extra::INVALID_HANDLE_VALUE;
use libc::wcslen;
use libc::{wcslen, free};
use libc::funcs::extra::kernel32::{
FindFirstFileW,
FindNextFileW,
Expand All @@ -739,7 +739,7 @@ pub fn list_dir(p: &Path) -> ~[~str] {
use os::win32::{
as_utf16_p
};
use rt::global_heap::{malloc_raw, free_raw};
use rt::global_heap::malloc_raw;
#[nolink]
extern {
unsafe fn rust_list_dir_wfd_size() -> libc::size_t;
Expand Down Expand Up @@ -772,7 +772,7 @@ pub fn list_dir(p: &Path) -> ~[~str] {
::cast::transmute(wfd_ptr));
}
FindClose(find_handle);
free_raw(wfd_ptr);
free(wfd_ptr)
}
strings
}
Expand Down
Loading

0 comments on commit 040ac2a

Please sign in to comment.