Skip to content

Commit 90f1db1

Browse files
committed
remove headers from exchange allocations
1 parent 0aedecf commit 90f1db1

File tree

16 files changed

+166
-76
lines changed

16 files changed

+166
-76
lines changed

src/librustc/middle/trans/_match.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,8 +1395,12 @@ pub fn compile_submatch(bcx: block,
13951395
}
13961396

13971397
if any_uniq_pat(m, col) {
1398+
let pat_ty = node_id_type(bcx, pat_id);
13981399
let llbox = Load(bcx, val);
1399-
let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]);
1400+
let unboxed = match ty::get(pat_ty).sty {
1401+
ty::ty_uniq(*) if !ty::type_contents(bcx.tcx(), pat_ty).contains_managed() => llbox,
1402+
_ => GEPi(bcx, llbox, [0u, abi::box_field_body])
1403+
};
14001404
compile_submatch(bcx, enter_uniq(bcx, dm, m, col, val),
14011405
vec::append(~[unboxed], vals_left), chk);
14021406
return;
@@ -1868,8 +1872,12 @@ pub fn bind_irrefutable_pat(bcx: block,
18681872
}
18691873
}
18701874
ast::pat_box(inner) | ast::pat_uniq(inner) => {
1875+
let pat_ty = node_id_type(bcx, pat.id);
18711876
let llbox = Load(bcx, val);
1872-
let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]);
1877+
let unboxed = match ty::get(pat_ty).sty {
1878+
ty::ty_uniq(*) if !ty::type_contents(bcx.tcx(), pat_ty).contains_managed() => llbox,
1879+
_ => GEPi(bcx, llbox, [0u, abi::box_field_body])
1880+
};
18731881
bcx = bind_irrefutable_pat(bcx,
18741882
inner,
18751883
unboxed,

src/librustc/middle/trans/base.rs

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -289,24 +289,25 @@ pub fn malloc_raw_dyn(bcx: block,
289289
let _icx = push_ctxt("malloc_raw");
290290
let ccx = bcx.ccx();
291291

292-
let (mk_fn, langcall) = match heap {
293-
heap_managed | heap_managed_unique => {
294-
(ty::mk_imm_box, bcx.tcx().lang_items.malloc_fn())
295-
}
296-
heap_exchange => {
297-
(ty::mk_imm_uniq, bcx.tcx().lang_items.exchange_malloc_fn())
298-
}
299-
heap_exchange_vector => {
300-
(ty::mk_imm_uniq, bcx.tcx().lang_items.vector_exchange_malloc_fn())
301-
}
302-
heap_exchange_closure => {
303-
(ty::mk_imm_uniq, bcx.tcx().lang_items.closure_exchange_malloc_fn())
304-
}
305-
};
292+
if heap == heap_exchange {
293+
let llty_value = type_of::type_of(ccx, t);
294+
let llalign = llalign_of_min(ccx, llty_value);
306295

307-
if heap == heap_exchange || heap == heap_exchange_vector {
296+
// Allocate space:
297+
let rval = alloca(bcx, Type::i8p());
298+
let bcx = callee::trans_lang_call(
299+
bcx,
300+
bcx.tcx().lang_items.exchange_malloc_fn(),
301+
[C_i32(llalign as i32), size],
302+
expr::SaveIn(rval));
303+
rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty_value.ptr_to()))
304+
} else if heap == heap_exchange_vector {
308305
// Grab the TypeRef type of box_ptr_ty.
309-
let box_ptr_ty = mk_fn(bcx.tcx(), t);
306+
let element_type = match ty::get(t).sty {
307+
ty::ty_unboxed_vec(e) => e,
308+
_ => fail!("not a vector body")
309+
};
310+
let box_ptr_ty = ty::mk_evec(bcx.tcx(), element_type, ty::vstore_uniq);
310311
let llty = type_of(ccx, box_ptr_ty);
311312

312313
let llty_value = type_of::type_of(ccx, t);
@@ -316,11 +317,22 @@ pub fn malloc_raw_dyn(bcx: block,
316317
let rval = alloca(bcx, Type::i8p());
317318
let bcx = callee::trans_lang_call(
318319
bcx,
319-
langcall,
320+
bcx.tcx().lang_items.vector_exchange_malloc_fn(),
320321
[C_i32(llalign as i32), size],
321322
expr::SaveIn(rval));
322323
rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty))
323324
} else {
325+
// we treat ~fn, @fn and @[] as @ here, which isn't ideal
326+
let (mk_fn, langcall) = match heap {
327+
heap_managed | heap_managed_unique => {
328+
(ty::mk_imm_box, bcx.tcx().lang_items.malloc_fn())
329+
}
330+
heap_exchange_closure => {
331+
(ty::mk_imm_box, bcx.tcx().lang_items.closure_exchange_malloc_fn())
332+
}
333+
_ => fail!("heap_exchange/heap_exchange_vector already handled")
334+
};
335+
324336
// Grab the TypeRef type of box_ptr_ty.
325337
let box_ptr_ty = mk_fn(bcx.tcx(), t);
326338
let llty = type_of(ccx, box_ptr_ty);
@@ -362,16 +374,17 @@ pub struct MallocResult {
362374
// and pulls out the body
363375
pub fn malloc_general_dyn(bcx: block, t: ty::t, heap: heap, size: ValueRef)
364376
-> MallocResult {
377+
assert!(heap != heap_exchange);
365378
let _icx = push_ctxt("malloc_general");
366379
let Result {bcx: bcx, val: llbox} = malloc_raw_dyn(bcx, t, heap, size);
367380
let body = GEPi(bcx, llbox, [0u, abi::box_field_body]);
368381

369382
MallocResult { bcx: bcx, box: llbox, body: body }
370383
}
371384

372-
pub fn malloc_general(bcx: block, t: ty::t, heap: heap)
373-
-> MallocResult {
374-
let ty = type_of(bcx.ccx(), t);
385+
pub fn malloc_general(bcx: block, t: ty::t, heap: heap) -> MallocResult {
386+
let ty = type_of(bcx.ccx(), t);
387+
assert!(heap != heap_exchange);
375388
malloc_general_dyn(bcx, t, heap, llsize_of(bcx.ccx(), ty))
376389
}
377390
pub fn malloc_boxed(bcx: block, t: ty::t)
@@ -388,6 +401,7 @@ pub fn heap_for_unique(bcx: block, t: ty::t) -> heap {
388401
}
389402

390403
pub fn maybe_set_managed_unique_rc(bcx: block, bx: ValueRef, heap: heap) {
404+
assert!(heap != heap_exchange);
391405
if heap == heap_managed_unique {
392406
// In cases where we are looking at a unique-typed allocation in the
393407
// managed heap (thus have refcount 1 from the managed allocator),
@@ -399,11 +413,6 @@ pub fn maybe_set_managed_unique_rc(bcx: block, bx: ValueRef, heap: heap) {
399413
}
400414
}
401415

402-
pub fn malloc_unique(bcx: block, t: ty::t)
403-
-> MallocResult {
404-
malloc_general(bcx, t, heap_for_unique(bcx, t))
405-
}
406-
407416
// Type descriptor and type glue stuff
408417

409418
pub fn get_tydesc_simple(ccx: &mut CrateContext, t: ty::t) -> ValueRef {

src/librustc/middle/trans/datum.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ use middle::trans::glue;
100100
use middle::trans::tvec;
101101
use middle::trans::type_of;
102102
use middle::trans::write_guard;
103+
use middle::trans::type_::Type;
103104
use middle::ty;
104105
use util::common::indenter;
105106
use util::ppaux::ty_to_str;
@@ -567,18 +568,31 @@ impl Datum {
567568
* This datum must represent an @T or ~T box. Returns a new
568569
* by-ref datum of type T, pointing at the contents. */
569570

570-
let content_ty = match ty::get(self.ty).sty {
571-
ty::ty_box(mt) | ty::ty_uniq(mt) => mt.ty,
571+
let (content_ty, header) = match ty::get(self.ty).sty {
572+
ty::ty_box(mt) => (mt.ty, true),
573+
ty::ty_uniq(mt) => (mt.ty, false),
574+
ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) => {
575+
let unit_ty = ty::sequence_element_type(bcx.tcx(), self.ty);
576+
let unboxed_vec_ty = ty::mk_mut_unboxed_vec(bcx.tcx(), unit_ty);
577+
(unboxed_vec_ty, true)
578+
}
572579
_ => {
573580
bcx.tcx().sess.bug(fmt!(
574581
"box_body() invoked on non-box type %s",
575582
ty_to_str(bcx.tcx(), self.ty)));
576583
}
577584
};
578585

579-
let ptr = self.to_value_llval(bcx);
580-
let body = opaque_box_body(bcx, content_ty, ptr);
581-
Datum {val: body, ty: content_ty, mode: ByRef(ZeroMem)}
586+
if !header && !ty::type_contents(bcx.tcx(), content_ty).contains_managed() {
587+
let ptr = self.to_value_llval(bcx);
588+
let ty = type_of(bcx.ccx(), content_ty);
589+
let body = PointerCast(bcx, ptr, ty.ptr_to());
590+
Datum {val: body, ty: content_ty, mode: ByRef(ZeroMem)}
591+
} else { // has a header
592+
let ptr = self.to_value_llval(bcx);
593+
let body = opaque_box_body(bcx, content_ty, ptr);
594+
Datum {val: body, ty: content_ty, mode: ByRef(ZeroMem)}
595+
}
582596
}
583597

584598
pub fn to_rptr(&self, bcx: block) -> Datum {

src/librustc/middle/trans/expr.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn,
150150
use middle::ty;
151151
use util::common::indenter;
152152
use util::ppaux::Repr;
153+
use middle::trans::machine::llsize_of;
153154

154155
use middle::trans::type_::Type;
155156

@@ -1329,12 +1330,23 @@ fn trans_unary_datum(bcx: block,
13291330
contents_ty: ty::t,
13301331
heap: heap) -> DatumBlock {
13311332
let _icx = push_ctxt("trans_boxed_expr");
1332-
let base::MallocResult { bcx, box: bx, body } =
1333-
base::malloc_general(bcx, contents_ty, heap);
1334-
add_clean_free(bcx, bx, heap);
1335-
let bcx = trans_into(bcx, contents, SaveIn(body));
1336-
revoke_clean(bcx, bx);
1337-
return immediate_rvalue_bcx(bcx, bx, box_ty);
1333+
if heap == heap_exchange {
1334+
let llty = type_of(bcx.ccx(), contents_ty);
1335+
let size = llsize_of(bcx.ccx(), llty);
1336+
let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, contents_ty,
1337+
heap_exchange, size);
1338+
add_clean_free(bcx, val, heap_exchange);
1339+
let bcx = trans_into(bcx, contents, SaveIn(val));
1340+
revoke_clean(bcx, val);
1341+
return immediate_rvalue_bcx(bcx, val, box_ty);
1342+
} else {
1343+
let base::MallocResult { bcx, box: bx, body } =
1344+
base::malloc_general(bcx, contents_ty, heap);
1345+
add_clean_free(bcx, bx, heap);
1346+
let bcx = trans_into(bcx, contents, SaveIn(body));
1347+
revoke_clean(bcx, bx);
1348+
return immediate_rvalue_bcx(bcx, bx, box_ty);
1349+
}
13381350
}
13391351
}
13401352

src/librustc/middle/trans/glue.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,9 @@ pub fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) {
386386
ty::ty_uniq(*) => {
387387
uniq::make_free_glue(bcx, v, t)
388388
}
389-
ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) |
389+
ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) => {
390+
tvec::make_uniq_free_glue(bcx, v, t)
391+
}
390392
ty::ty_evec(_, ty::vstore_box) | ty::ty_estr(ty::vstore_box) => {
391393
make_free_glue(bcx, v,
392394
tvec::expand_boxed_vec_ty(bcx.tcx(), t));

src/librustc/middle/trans/meth.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,7 @@ pub fn trans_trait_callee_from_llval(bcx: block,
548548

549549
let _icx = push_ctxt("impl::trans_trait_callee");
550550
let ccx = bcx.ccx();
551+
let mut bcx = bcx;
551552

552553
// Load the vtable from the @Trait pair
553554
debug!("(translating trait callee) loading vtable from pair %s",
@@ -576,6 +577,10 @@ pub fn trans_trait_callee_from_llval(bcx: block,
576577
}
577578
ast::sty_region(*) => {
578579
match store {
580+
ty::UniqTraitStore
581+
if !ty::type_contents(bcx.tcx(), callee_ty).contains_managed() => {
582+
llself = llbox;
583+
}
579584
ty::BoxTraitStore |
580585
ty::UniqTraitStore => {
581586
llself = GEPi(bcx, llbox, [0u, abi::box_field_body]);

src/librustc/middle/trans/reflect.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,11 @@ impl Reflector {
194194
}
195195
ty::ty_uniq(ref mt) => {
196196
let extra = self.c_mt(mt);
197-
self.visit("uniq", extra)
197+
if ty::type_contents(bcx.tcx(), t).contains_managed() {
198+
self.visit("uniq_managed", extra)
199+
} else {
200+
self.visit("uniq", extra)
201+
}
198202
}
199203
ty::ty_ptr(ref mt) => {
200204
let extra = self.c_mt(mt);

src/librustc/middle/trans/tvec.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,23 @@ use std::option::None;
3333
use syntax::ast;
3434
use syntax::codemap;
3535

36+
pub fn make_uniq_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t)
37+
-> block {
38+
let box_datum = immediate_rvalue(Load(bcx, vptrptr), box_ty);
39+
40+
let not_null = IsNotNull(bcx, box_datum.val);
41+
do with_cond(bcx, not_null) |bcx| {
42+
let body_datum = box_datum.box_body(bcx);
43+
let bcx = glue::drop_ty(bcx, body_datum.to_ref_llval(bcx),
44+
body_datum.ty);
45+
if ty::type_contents(bcx.tcx(), box_ty).contains_managed() {
46+
glue::trans_free(bcx, box_datum.val)
47+
} else {
48+
glue::trans_exchange_free(bcx, box_datum.val)
49+
}
50+
}
51+
}
52+
3653
// Boxed vector types are in some sense currently a "shorthand" for a box
3754
// containing an unboxed vector. This expands a boxed vector type into such an
3855
// expanded type. It doesn't respect mutability, but that doesn't matter at
@@ -42,7 +59,7 @@ pub fn expand_boxed_vec_ty(tcx: ty::ctxt, t: ty::t) -> ty::t {
4259
let unboxed_vec_ty = ty::mk_mut_unboxed_vec(tcx, unit_ty);
4360
match ty::get(t).sty {
4461
ty::ty_estr(ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_uniq) => {
45-
ty::mk_imm_uniq(tcx, unboxed_vec_ty)
62+
fail!("cannot treat vectors/strings as exchange allocations yet");
4663
}
4764
ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) => {
4865
ty::mk_imm_box(tcx, unboxed_vec_ty)

src/librustc/middle/trans/type_of.rs

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -72,29 +72,6 @@ pub fn type_of_fn_from_ty(cx: &mut CrateContext, fty: ty::t) -> Type {
7272
}
7373
}
7474

75-
pub fn type_of_non_gc_box(cx: &mut CrateContext, t: ty::t) -> Type {
76-
assert!(!ty::type_needs_infer(t));
77-
78-
let t_norm = ty::normalize_ty(cx.tcx, t);
79-
if t != t_norm {
80-
type_of_non_gc_box(cx, t_norm)
81-
} else {
82-
match ty::get(t).sty {
83-
ty::ty_box(mt) => {
84-
let ty = type_of(cx, mt.ty);
85-
Type::box(cx, &ty).ptr_to()
86-
}
87-
ty::ty_uniq(mt) => {
88-
let ty = type_of(cx, mt.ty);
89-
Type::unique(cx, &ty).ptr_to()
90-
}
91-
_ => {
92-
cx.sess.bug("non-box in type_of_non_gc_box");
93-
}
94-
}
95-
}
96-
}
97-
9875
// A "sizing type" is an LLVM type, the size and alignment of which are
9976
// guaranteed to be equivalent to what you would get out of `type_of()`. It's
10077
// useful because:
@@ -231,7 +208,11 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
231208
ty::ty_opaque_box => Type::opaque_box(cx).ptr_to(),
232209
ty::ty_uniq(ref mt) => {
233210
let ty = type_of(cx, mt.ty);
234-
Type::unique(cx, &ty).ptr_to()
211+
if ty::type_contents(cx.tcx, mt.ty).contains_managed() {
212+
Type::unique(cx, &ty).ptr_to()
213+
} else {
214+
ty.ptr_to()
215+
}
235216
}
236217
ty::ty_evec(ref mt, ty::vstore_uniq) => {
237218
let ty = type_of(cx, mt.ty);

src/librustc/middle/trans/uniq.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ use middle::trans::datum::immediate_rvalue;
1717
use middle::trans::datum;
1818
use middle::trans::glue;
1919
use middle::ty;
20+
use middle::trans::machine::llsize_of;
21+
use middle::trans::type_of;
22+
use middle::trans::type_of::*;
2023

2124
pub fn make_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t)
2225
-> block {
@@ -44,12 +47,21 @@ pub fn duplicate(bcx: block, src_box: ValueRef, src_ty: ty::t) -> Result {
4447
let body_datum = src_datum.box_body(bcx);
4548

4649
// Malloc space in exchange heap and copy src into it
47-
let MallocResult {
48-
bcx: bcx,
49-
box: dst_box,
50-
body: dst_body
51-
} = malloc_unique(bcx, body_datum.ty);
52-
body_datum.copy_to(bcx, datum::INIT, dst_body);
53-
54-
rslt(bcx, dst_box)
50+
if ty::type_contents(bcx.tcx(), src_ty).contains_managed() {
51+
let MallocResult {
52+
bcx: bcx,
53+
box: dst_box,
54+
body: dst_body
55+
} = malloc_general(bcx, body_datum.ty, heap_managed_unique);
56+
body_datum.copy_to(bcx, datum::INIT, dst_body);
57+
58+
rslt(bcx, dst_box)
59+
} else {
60+
let body_datum = body_datum.to_value_datum(bcx);
61+
let llty = type_of(bcx.ccx(), body_datum.ty);
62+
let size = llsize_of(bcx.ccx(), llty);
63+
let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, body_datum.ty, heap_exchange, size);
64+
body_datum.copy_to(bcx, datum::INIT, val);
65+
Result { bcx: bcx, val: val }
66+
}
5567
}

src/libstd/reflect.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,14 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
248248
true
249249
}
250250

251+
#[cfg(not(stage0))]
252+
fn visit_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool {
253+
self.align_to::<~u8>();
254+
if ! self.inner.visit_uniq_managed(mtbl, inner) { return false; }
255+
self.bump_past::<~u8>();
256+
true
257+
}
258+
251259
fn visit_ptr(&self, mtbl: uint, inner: *TyDesc) -> bool {
252260
self.align_to::<*u8>();
253261
if ! self.inner.visit_ptr(mtbl, inner) { return false; }

0 commit comments

Comments
 (0)