Skip to content

Commit 040ac2a

Browse files
committed
auto merge of #7495 : thestinger/rust/exchange, r=cmr
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.
2 parents ca835f4 + 4a29d6e commit 040ac2a

20 files changed

+207
-261
lines changed

src/librustc/middle/lang_items.rs

Lines changed: 71 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -32,63 +32,64 @@ use syntax::visit::visit_crate;
3232
use std::hashmap::HashMap;
3333

3434
pub enum LangItem {
35-
FreezeTraitLangItem, // 0
36-
CopyTraitLangItem, // 1
37-
SendTraitLangItem, // 2
38-
SizedTraitLangItem, // 3
39-
40-
DropTraitLangItem, // 4
41-
42-
AddTraitLangItem, // 5
43-
SubTraitLangItem, // 6
44-
MulTraitLangItem, // 7
45-
DivTraitLangItem, // 8
46-
RemTraitLangItem, // 9
47-
NegTraitLangItem, // 10
48-
NotTraitLangItem, // 11
49-
BitXorTraitLangItem, // 11
50-
BitAndTraitLangItem, // 13
51-
BitOrTraitLangItem, // 14
52-
ShlTraitLangItem, // 15
53-
ShrTraitLangItem, // 16
54-
IndexTraitLangItem, // 17
55-
56-
EqTraitLangItem, // 18
57-
OrdTraitLangItem, // 19
58-
59-
StrEqFnLangItem, // 20
60-
UniqStrEqFnLangItem, // 21
61-
AnnihilateFnLangItem, // 22
62-
LogTypeFnLangItem, // 23
63-
FailFnLangItem, // 24
64-
FailBoundsCheckFnLangItem, // 25
65-
ExchangeMallocFnLangItem, // 26
66-
ExchangeFreeFnLangItem, // 27
67-
MallocFnLangItem, // 28
68-
FreeFnLangItem, // 29
69-
BorrowAsImmFnLangItem, // 30
70-
BorrowAsMutFnLangItem, // 31
71-
ReturnToMutFnLangItem, // 32
72-
CheckNotBorrowedFnLangItem, // 33
73-
StrDupUniqFnLangItem, // 34
74-
RecordBorrowFnLangItem, // 35
75-
UnrecordBorrowFnLangItem, // 36
76-
77-
StartFnLangItem, // 37
78-
79-
TyDescStructLangItem, // 38
80-
TyVisitorTraitLangItem, // 39
81-
OpaqueStructLangItem, // 40
35+
FreezeTraitLangItem, // 0
36+
CopyTraitLangItem, // 1
37+
SendTraitLangItem, // 2
38+
SizedTraitLangItem, // 3
39+
40+
DropTraitLangItem, // 4
41+
42+
AddTraitLangItem, // 5
43+
SubTraitLangItem, // 6
44+
MulTraitLangItem, // 7
45+
DivTraitLangItem, // 8
46+
RemTraitLangItem, // 9
47+
NegTraitLangItem, // 10
48+
NotTraitLangItem, // 11
49+
BitXorTraitLangItem, // 11
50+
BitAndTraitLangItem, // 13
51+
BitOrTraitLangItem, // 14
52+
ShlTraitLangItem, // 15
53+
ShrTraitLangItem, // 16
54+
IndexTraitLangItem, // 17
55+
56+
EqTraitLangItem, // 18
57+
OrdTraitLangItem, // 19
58+
59+
StrEqFnLangItem, // 20
60+
UniqStrEqFnLangItem, // 21
61+
AnnihilateFnLangItem, // 22
62+
LogTypeFnLangItem, // 23
63+
FailFnLangItem, // 24
64+
FailBoundsCheckFnLangItem, // 25
65+
ExchangeMallocFnLangItem, // 26
66+
ClosureExchangeMallocFnLangItem, // 27
67+
ExchangeFreeFnLangItem, // 28
68+
MallocFnLangItem, // 29
69+
FreeFnLangItem, // 30
70+
BorrowAsImmFnLangItem, // 31
71+
BorrowAsMutFnLangItem, // 32
72+
ReturnToMutFnLangItem, // 33
73+
CheckNotBorrowedFnLangItem, // 34
74+
StrDupUniqFnLangItem, // 35
75+
RecordBorrowFnLangItem, // 36
76+
UnrecordBorrowFnLangItem, // 37
77+
78+
StartFnLangItem, // 38
79+
80+
TyDescStructLangItem, // 39
81+
TyVisitorTraitLangItem, // 40
82+
OpaqueStructLangItem, // 41
8283
}
8384

8485
pub struct LanguageItems {
85-
items: [Option<def_id>, ..41]
86+
items: [Option<def_id>, ..42]
8687
}
8788

8889
impl LanguageItems {
8990
pub fn new() -> LanguageItems {
9091
LanguageItems {
91-
items: [ None, ..41 ]
92+
items: [ None, ..42 ]
9293
}
9394
}
9495

@@ -128,22 +129,23 @@ impl LanguageItems {
128129
24 => "fail_",
129130
25 => "fail_bounds_check",
130131
26 => "exchange_malloc",
131-
27 => "exchange_free",
132-
28 => "malloc",
133-
29 => "free",
134-
30 => "borrow_as_imm",
135-
31 => "borrow_as_mut",
136-
32 => "return_to_mut",
137-
33 => "check_not_borrowed",
138-
34 => "strdup_uniq",
139-
35 => "record_borrow",
140-
36 => "unrecord_borrow",
141-
142-
37 => "start",
143-
144-
38 => "ty_desc",
145-
39 => "ty_visitor",
146-
40 => "opaque",
132+
27 => "closure_exchange_malloc",
133+
28 => "exchange_free",
134+
29 => "malloc",
135+
30 => "free",
136+
31 => "borrow_as_imm",
137+
32 => "borrow_as_mut",
138+
33 => "return_to_mut",
139+
34 => "check_not_borrowed",
140+
35 => "strdup_uniq",
141+
36 => "record_borrow",
142+
37 => "unrecord_borrow",
143+
144+
38 => "start",
145+
146+
39 => "ty_desc",
147+
40 => "ty_visitor",
148+
41 => "opaque",
147149

148150
_ => "???"
149151
}
@@ -236,6 +238,9 @@ impl LanguageItems {
236238
pub fn exchange_malloc_fn(&self) -> def_id {
237239
self.items[ExchangeMallocFnLangItem as uint].get()
238240
}
241+
pub fn closure_exchange_malloc_fn(&self) -> def_id {
242+
self.items[ClosureExchangeMallocFnLangItem as uint].get()
243+
}
239244
pub fn exchange_free_fn(&self) -> def_id {
240245
self.items[ExchangeFreeFnLangItem as uint].get()
241246
}
@@ -326,6 +331,7 @@ impl<'self> LanguageItemCollector<'self> {
326331
item_refs.insert(@"fail_bounds_check",
327332
FailBoundsCheckFnLangItem as uint);
328333
item_refs.insert(@"exchange_malloc", ExchangeMallocFnLangItem as uint);
334+
item_refs.insert(@"closure_exchange_malloc", ClosureExchangeMallocFnLangItem as uint);
329335
item_refs.insert(@"exchange_free", ExchangeFreeFnLangItem as uint);
330336
item_refs.insert(@"malloc", MallocFnLangItem as uint);
331337
item_refs.insert(@"free", FreeFnLangItem as uint);

src/librustc/middle/trans/base.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,9 @@ pub fn malloc_raw_dyn(bcx: block,
253253
heap_exchange => {
254254
(ty::mk_imm_uniq, bcx.tcx().lang_items.exchange_malloc_fn())
255255
}
256+
heap_exchange_closure => {
257+
(ty::mk_imm_uniq, bcx.tcx().lang_items.closure_exchange_malloc_fn())
258+
}
256259
};
257260

258261
// Grab the TypeRef type of box_ptr_ty.

src/librustc/middle/trans/closure.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,14 @@ pub fn mk_closure_tys(tcx: ty::ctxt,
159159
return cdata_ty;
160160
}
161161

162+
fn heap_for_unique_closure(bcx: block, t: ty::t) -> heap {
163+
if ty::type_contents(bcx.tcx(), t).contains_managed() {
164+
heap_managed_unique
165+
} else {
166+
heap_exchange_closure
167+
}
168+
}
169+
162170
pub fn allocate_cbox(bcx: block, sigil: ast::Sigil, cdata_ty: ty::t)
163171
-> Result {
164172
let _icx = push_ctxt("closure::allocate_cbox");
@@ -181,7 +189,7 @@ pub fn allocate_cbox(bcx: block, sigil: ast::Sigil, cdata_ty: ty::t)
181189
malloc_raw(bcx, cdata_ty, heap_managed)
182190
}
183191
ast::OwnedSigil => {
184-
malloc_raw(bcx, cdata_ty, heap_for_unique(bcx, cdata_ty))
192+
malloc_raw(bcx, cdata_ty, heap_for_unique_closure(bcx, cdata_ty))
185193
}
186194
ast::BorrowedSigil => {
187195
let cbox_ty = tuplify_box_ty(tcx, cdata_ty);
@@ -526,7 +534,7 @@ pub fn make_opaque_cbox_take_glue(
526534
let rval = alloca(bcx, Type::i8p());
527535
let bcx = callee::trans_lang_call(
528536
bcx,
529-
bcx.tcx().lang_items.exchange_malloc_fn(),
537+
bcx.tcx().lang_items.closure_exchange_malloc_fn(),
530538
[opaque_tydesc, sz],
531539
expr::SaveIn(rval));
532540
let cbox_out = PointerCast(bcx, Load(bcx, rval), llopaquecboxty);

src/librustc/middle/trans/common.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ pub enum heap {
275275
heap_managed,
276276
heap_managed_unique,
277277
heap_exchange,
278+
heap_exchange_closure
278279
}
279280

280281
#[deriving(Eq)]
@@ -384,7 +385,7 @@ pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) {
384385
let f: @fn(block) -> block = |a| glue::trans_free(a, ptr);
385386
f
386387
}
387-
heap_exchange => {
388+
heap_exchange | heap_exchange_closure => {
388389
let f: @fn(block) -> block = |a| glue::trans_exchange_free(a, ptr);
389390
f
390391
}

src/librustc/middle/trans/foreign.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,12 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
750750
C_bool(ty::type_needs_drop(ccx.tcx, tp_ty)),
751751
fcx.llretptr.get());
752752
}
753+
"contains_managed" => {
754+
let tp_ty = substs.tys[0];
755+
Store(bcx,
756+
C_bool(ty::type_contents(ccx.tcx, tp_ty).contains_managed()),
757+
fcx.llretptr.get());
758+
}
753759
"visit_tydesc" => {
754760
let td = get_param(decl, first_real_arg);
755761
let visitor = get_param(decl, first_real_arg + 1u);

src/librustc/middle/trans/tvec.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, heap: heap, vstore_expr: @ast::e
321321
_ => {}
322322
}
323323
}
324+
heap_exchange_closure => fail!("vectors are not allocated with closure_exchange_alloc"),
324325
heap_managed | heap_managed_unique => {}
325326
}
326327

src/librustc/middle/trans/type_use.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint)
127127
"uninit" | "init" | "transmute" | "move_val" |
128128
"move_val_init" => use_repr,
129129

130-
"get_tydesc" | "needs_drop" => use_tydesc,
130+
"get_tydesc" | "needs_drop" | "contains_managed" => use_tydesc,
131131

132132
"visit_tydesc" | "forget" | "frame_address" |
133133
"morestack_addr" => 0,

src/librustc/middle/trans/uniq.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,5 @@ pub fn duplicate(bcx: block, src_box: ValueRef, src_ty: ty::t) -> Result {
5252
} = malloc_unique(bcx, body_datum.ty);
5353
body_datum.copy_to(bcx, datum::INIT, dst_body);
5454

55-
// Copy the type descriptor
56-
let src_tydesc_ptr = GEPi(bcx, src_box,
57-
[0u, back::abi::box_field_tydesc]);
58-
let dst_tydesc_ptr = GEPi(bcx, dst_box,
59-
[0u, back::abi::box_field_tydesc]);
60-
let td = Load(bcx, src_tydesc_ptr);
61-
Store(bcx, td, dst_tydesc_ptr);
62-
63-
return rslt(bcx, dst_box);
55+
rslt(bcx, dst_box)
6456
}

src/librustc/middle/typeck/check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3539,7 +3539,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
35393539
ty::mk_nil())
35403540
}
35413541
"needs_drop" => (1u, ~[], ty::mk_bool()),
3542-
3542+
"contains_managed" => (1u, ~[], ty::mk_bool()),
35433543
"atomic_xchg" | "atomic_xadd" | "atomic_xsub" |
35443544
"atomic_xchg_acq" | "atomic_xadd_acq" | "atomic_xsub_acq" |
35453545
"atomic_xchg_rel" | "atomic_xadd_rel" | "atomic_xsub_rel" => {

src/libstd/managed.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use ptr::to_unsafe_ptr;
1717
pub mod raw {
1818
use std::unstable::intrinsics::TyDesc;
1919

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

src/libstd/os.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ pub fn list_dir(p: &Path) -> ~[~str] {
730730
#[cfg(windows)]
731731
unsafe fn get_list(p: &Path) -> ~[~str] {
732732
use libc::consts::os::extra::INVALID_HANDLE_VALUE;
733-
use libc::wcslen;
733+
use libc::{wcslen, free};
734734
use libc::funcs::extra::kernel32::{
735735
FindFirstFileW,
736736
FindNextFileW,
@@ -739,7 +739,7 @@ pub fn list_dir(p: &Path) -> ~[~str] {
739739
use os::win32::{
740740
as_utf16_p
741741
};
742-
use rt::global_heap::{malloc_raw, free_raw};
742+
use rt::global_heap::malloc_raw;
743743
#[nolink]
744744
extern {
745745
unsafe fn rust_list_dir_wfd_size() -> libc::size_t;
@@ -772,7 +772,7 @@ pub fn list_dir(p: &Path) -> ~[~str] {
772772
::cast::transmute(wfd_ptr));
773773
}
774774
FindClose(find_handle);
775-
free_raw(wfd_ptr);
775+
free(wfd_ptr)
776776
}
777777
strings
778778
}

0 commit comments

Comments
 (0)