Skip to content

Commit 48ad726

Browse files
committed
auto merge of #7605 : thestinger/rust/vec, r=Aatch
This is work continued from the now landed #7495 and #7521 pulls. Removing the headers from unique vectors is another project, so I've separated the allocator.
2 parents 44770ae + 90f1db1 commit 48ad726

19 files changed

+235
-132
lines changed

src/librustc/middle/lang_items.rs

+42-36
Original file line numberDiff line numberDiff line change
@@ -63,33 +63,34 @@ pub enum LangItem {
6363
FailFnLangItem, // 24
6464
FailBoundsCheckFnLangItem, // 25
6565
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
66+
VectorExchangeMallocFnLangItem, // 27
67+
ClosureExchangeMallocFnLangItem, // 28
68+
ExchangeFreeFnLangItem, // 29
69+
MallocFnLangItem, // 30
70+
FreeFnLangItem, // 31
71+
BorrowAsImmFnLangItem, // 32
72+
BorrowAsMutFnLangItem, // 33
73+
ReturnToMutFnLangItem, // 34
74+
CheckNotBorrowedFnLangItem, // 35
75+
StrDupUniqFnLangItem, // 36
76+
RecordBorrowFnLangItem, // 37
77+
UnrecordBorrowFnLangItem, // 38
78+
79+
StartFnLangItem, // 39
80+
81+
TyDescStructLangItem, // 40
82+
TyVisitorTraitLangItem, // 41
83+
OpaqueStructLangItem, // 42
8384
}
8485

8586
pub struct LanguageItems {
86-
items: [Option<def_id>, ..42]
87+
items: [Option<def_id>, ..43]
8788
}
8889

8990
impl LanguageItems {
9091
pub fn new() -> LanguageItems {
9192
LanguageItems {
92-
items: [ None, ..42 ]
93+
items: [ None, ..43 ]
9394
}
9495
}
9596

@@ -129,23 +130,24 @@ impl LanguageItems {
129130
24 => "fail_",
130131
25 => "fail_bounds_check",
131132
26 => "exchange_malloc",
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",
133+
27 => "vector_exchange_malloc",
134+
28 => "closure_exchange_malloc",
135+
29 => "exchange_free",
136+
30 => "malloc",
137+
31 => "free",
138+
32 => "borrow_as_imm",
139+
33 => "borrow_as_mut",
140+
34 => "return_to_mut",
141+
35 => "check_not_borrowed",
142+
36 => "strdup_uniq",
143+
37 => "record_borrow",
144+
38 => "unrecord_borrow",
145+
146+
39 => "start",
147+
148+
40 => "ty_desc",
149+
41 => "ty_visitor",
150+
42 => "opaque",
149151

150152
_ => "???"
151153
}
@@ -238,6 +240,9 @@ impl LanguageItems {
238240
pub fn exchange_malloc_fn(&self) -> def_id {
239241
self.items[ExchangeMallocFnLangItem as uint].get()
240242
}
243+
pub fn vector_exchange_malloc_fn(&self) -> def_id {
244+
self.items[VectorExchangeMallocFnLangItem as uint].get()
245+
}
241246
pub fn closure_exchange_malloc_fn(&self) -> def_id {
242247
self.items[ClosureExchangeMallocFnLangItem as uint].get()
243248
}
@@ -331,6 +336,7 @@ impl<'self> LanguageItemCollector<'self> {
331336
item_refs.insert(@"fail_bounds_check",
332337
FailBoundsCheckFnLangItem as uint);
333338
item_refs.insert(@"exchange_malloc", ExchangeMallocFnLangItem as uint);
339+
item_refs.insert(@"vector_exchange_malloc", VectorExchangeMallocFnLangItem as uint);
334340
item_refs.insert(@"closure_exchange_malloc", ClosureExchangeMallocFnLangItem as uint);
335341
item_refs.insert(@"exchange_free", ExchangeFreeFnLangItem as uint);
336342
item_refs.insert(@"malloc", MallocFnLangItem as uint);

src/librustc/middle/trans/_match.rs

+10-2
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

+34-22
Original file line numberDiff line numberDiff line change
@@ -289,21 +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_closure => {
300-
(ty::mk_imm_uniq, bcx.tcx().lang_items.closure_exchange_malloc_fn())
301-
}
302-
};
303-
304292
if heap == heap_exchange {
293+
let llty_value = type_of::type_of(ccx, t);
294+
let llalign = llalign_of_min(ccx, llty_value);
295+
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 {
305305
// Grab the TypeRef type of box_ptr_ty.
306-
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);
307311
let llty = type_of(ccx, box_ptr_ty);
308312

309313
let llty_value = type_of::type_of(ccx, t);
@@ -313,11 +317,22 @@ pub fn malloc_raw_dyn(bcx: block,
313317
let rval = alloca(bcx, Type::i8p());
314318
let bcx = callee::trans_lang_call(
315319
bcx,
316-
langcall,
320+
bcx.tcx().lang_items.vector_exchange_malloc_fn(),
317321
[C_i32(llalign as i32), size],
318322
expr::SaveIn(rval));
319323
rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty))
320324
} 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+
321336
// Grab the TypeRef type of box_ptr_ty.
322337
let box_ptr_ty = mk_fn(bcx.tcx(), t);
323338
let llty = type_of(ccx, box_ptr_ty);
@@ -359,16 +374,17 @@ pub struct MallocResult {
359374
// and pulls out the body
360375
pub fn malloc_general_dyn(bcx: block, t: ty::t, heap: heap, size: ValueRef)
361376
-> MallocResult {
377+
assert!(heap != heap_exchange);
362378
let _icx = push_ctxt("malloc_general");
363379
let Result {bcx: bcx, val: llbox} = malloc_raw_dyn(bcx, t, heap, size);
364380
let body = GEPi(bcx, llbox, [0u, abi::box_field_body]);
365381

366382
MallocResult { bcx: bcx, box: llbox, body: body }
367383
}
368384

369-
pub fn malloc_general(bcx: block, t: ty::t, heap: heap)
370-
-> MallocResult {
371-
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);
372388
malloc_general_dyn(bcx, t, heap, llsize_of(bcx.ccx(), ty))
373389
}
374390
pub fn malloc_boxed(bcx: block, t: ty::t)
@@ -385,6 +401,7 @@ pub fn heap_for_unique(bcx: block, t: ty::t) -> heap {
385401
}
386402

387403
pub fn maybe_set_managed_unique_rc(bcx: block, bx: ValueRef, heap: heap) {
404+
assert!(heap != heap_exchange);
388405
if heap == heap_managed_unique {
389406
// In cases where we are looking at a unique-typed allocation in the
390407
// managed heap (thus have refcount 1 from the managed allocator),
@@ -396,11 +413,6 @@ pub fn maybe_set_managed_unique_rc(bcx: block, bx: ValueRef, heap: heap) {
396413
}
397414
}
398415

399-
pub fn malloc_unique(bcx: block, t: ty::t)
400-
-> MallocResult {
401-
malloc_general(bcx, t, heap_for_unique(bcx, t))
402-
}
403-
404416
// Type descriptor and type glue stuff
405417

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

src/librustc/middle/trans/common.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ pub enum heap {
274274
heap_managed,
275275
heap_managed_unique,
276276
heap_exchange,
277+
heap_exchange_vector,
277278
heap_exchange_closure
278279
}
279280

@@ -395,7 +396,7 @@ pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) {
395396
let f: @fn(block) -> block = |a| glue::trans_free(a, ptr);
396397
f
397398
}
398-
heap_exchange | heap_exchange_closure => {
399+
heap_exchange | heap_exchange_vector | heap_exchange_closure => {
399400
let f: @fn(block) -> block = |a| glue::trans_exchange_free(a, ptr);
400401
f
401402
}

src/librustc/middle/trans/datum.rs

+19-5
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

+19-7
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

@@ -464,7 +465,7 @@ fn trans_rvalue_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
464465
expr, contents);
465466
}
466467
ast::expr_vstore(contents, ast::expr_vstore_uniq) => {
467-
let heap = heap_for_unique(bcx, expr_ty(bcx, contents));
468+
let heap = tvec::heap_for_unique_vector(bcx, expr_ty(bcx, contents));
468469
return tvec::trans_uniq_or_managed_vstore(bcx, heap,
469470
expr, contents);
470471
}
@@ -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

+3-1
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

+5
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

+5-1
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);

0 commit comments

Comments
 (0)