Skip to content

Commit 08edc16

Browse files
committed
---
yaml --- r: 228852 b: refs/heads/try c: dce1c61 h: refs/heads/master v: v3
1 parent add11c2 commit 08edc16

File tree

11 files changed

+260
-71
lines changed

11 files changed

+260
-71
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: aca2057ed5fb7af3f8905b2bc01f72fa001c35c8
33
refs/heads/snap-stage3: 1af31d4974e33027a68126fa5a5a3c2c6491824f
4-
refs/heads/try: d3d552b71b89633fe6692bf2214a2d001683bfa9
4+
refs/heads/try: dce1c61e977deed5e0a499f4247d5da870809692
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/src/librustc_trans/trans/_match.rs

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ use trans::build::{AddCase, And, Br, CondBr, GEPi, InBoundsGEP, Load, PointerCas
205205
use trans::build::{Not, Store, Sub, add_comment};
206206
use trans::build;
207207
use trans::callee;
208-
use trans::cleanup::{self, CleanupMethods};
208+
use trans::cleanup::{self, CleanupMethods, DropHintMethods};
209209
use trans::common::*;
210210
use trans::consts;
211211
use trans::datum::*;
@@ -947,14 +947,14 @@ fn insert_lllocals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
947947
TrByCopy(llbinding) |
948948
TrByMoveIntoCopy(llbinding) => {
949949
let llval = Load(bcx, binding_info.llmatch);
950-
let lval = match binding_info.trmode {
950+
let lvalue = match binding_info.trmode {
951951
TrByCopy(..) =>
952952
Lvalue::new("_match::insert_lllocals"),
953953
TrByMoveIntoCopy(..) =>
954954
Lvalue::match_input("_match::insert_lllocals", bcx, binding_info.id),
955955
_ => unreachable!(),
956956
};
957-
let datum = Datum::new(llval, binding_info.ty, lval);
957+
let datum = Datum::new(llval, binding_info.ty, lvalue);
958958
call_lifetime_start(bcx, llbinding);
959959
bcx = datum.store_to(bcx, llbinding);
960960
if let Some(cs) = cs {
@@ -971,14 +971,15 @@ fn insert_lllocals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
971971
TrByRef => (binding_info.llmatch, true),
972972
};
973973

974-
let lval = Lvalue::local("_match::insert_lllocals",
975-
bcx,
976-
binding_info.id,
977-
aliases_other_state);
978-
let datum = Datum::new(llval, binding_info.ty, lval);
974+
let lvalue = Lvalue::local("_match::insert_lllocals",
975+
bcx,
976+
binding_info.id,
977+
aliases_other_state);
978+
let datum = Datum::new(llval, binding_info.ty, lvalue);
979979
if let Some(cs) = cs {
980+
let opt_datum = lvalue.dropflag_hint(bcx);
980981
bcx.fcx.schedule_lifetime_end(cs, binding_info.llmatch);
981-
bcx.fcx.schedule_drop_and_fill_mem(cs, llval, binding_info.ty);
982+
bcx.fcx.schedule_drop_and_fill_mem(cs, llval, binding_info.ty, opt_datum);
982983
}
983984

984985
debug!("binding {} to {}", binding_info.id, bcx.val_to_string(llval));
@@ -1505,13 +1506,13 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat,
15051506
// but during matching we need to store a *T as explained
15061507
// above
15071508
llmatch = alloca_no_lifetime(bcx,
1508-
llvariable_ty.ptr_to(),
1509-
&bcx.name(name));
1509+
llvariable_ty.ptr_to(),
1510+
&bcx.name(name));
15101511
trmode = TrByMoveRef;
15111512
}
15121513
ast::BindByRef(_) => {
15131514
llmatch = alloca_no_lifetime(bcx,
1514-
llvariable_ty,
1515+
llvariable_ty,
15151516
&bcx.name(name));
15161517
trmode = TrByRef;
15171518
}
@@ -1631,7 +1632,25 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
16311632
bcx = mk_binding_alloca(
16321633
bcx, p_id, path1.node.name, scope, (),
16331634
"_match::store_local::create_dummy_locals",
1634-
|(), bcx, llval, ty| { drop_done_fill_mem(bcx, llval, ty); bcx });
1635+
|(), bcx, Datum { val: llval, ty, kind }| {
1636+
// Dummy-locals start out uninitialized, so set their
1637+
// drop-flag hints (if any) to "moved."
1638+
if let Some(hint) = kind.dropflag_hint(bcx) {
1639+
let moved_hint = adt::DTOR_MOVED_HINT as usize;
1640+
debug!("store moved_hint={} for hint={:?}, uninitialized dummy",
1641+
moved_hint, hint);
1642+
Store(bcx, C_u8(bcx.fcx.ccx, moved_hint), hint.to_value().value());
1643+
}
1644+
1645+
if kind.drop_flag_info.must_zero() {
1646+
// if no drop-flag hint, or the hint requires
1647+
// we maintain the embedded drop-flag, then
1648+
// mark embedded drop-flag(s) as moved
1649+
// (i.e. "already dropped").
1650+
drop_done_fill_mem(bcx, llval, ty);
1651+
}
1652+
bcx
1653+
});
16351654
});
16361655
bcx
16371656
}
@@ -1654,8 +1673,8 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
16541673
return mk_binding_alloca(
16551674
bcx, pat.id, ident.name, var_scope, (),
16561675
"_match::store_local",
1657-
|(), bcx, v, _| expr::trans_into(bcx, &**init_expr,
1658-
expr::SaveIn(v)));
1676+
|(), bcx, Datum { val: v, .. }| expr::trans_into(bcx, &**init_expr,
1677+
expr::SaveIn(v)));
16591678
}
16601679

16611680
None => {}
@@ -1684,23 +1703,23 @@ fn mk_binding_alloca<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
16841703
caller_name: &'static str,
16851704
populate: F)
16861705
-> Block<'blk, 'tcx> where
1687-
F: FnOnce(A, Block<'blk, 'tcx>, ValueRef, Ty<'tcx>) -> Block<'blk, 'tcx>,
1706+
F: FnOnce(A, Block<'blk, 'tcx>, Datum<'tcx, Lvalue>) -> Block<'blk, 'tcx>,
16881707
{
16891708
let var_ty = node_id_type(bcx, p_id);
16901709

16911710
// Allocate memory on stack for the binding.
16921711
let llval = alloc_ty(bcx, var_ty, &bcx.name(name));
1712+
let lvalue = Lvalue::binding(caller_name, bcx, p_id, name);
1713+
let datum = Datum::new(llval, var_ty, lvalue);
16931714

16941715
// Subtle: be sure that we *populate* the memory *before*
16951716
// we schedule the cleanup.
1696-
let bcx = populate(arg, bcx, llval, var_ty);
1717+
let bcx = populate(arg, bcx, datum);
16971718
bcx.fcx.schedule_lifetime_end(cleanup_scope, llval);
1698-
bcx.fcx.schedule_drop_mem(cleanup_scope, llval, var_ty);
1719+
bcx.fcx.schedule_drop_mem(cleanup_scope, llval, var_ty, lvalue.dropflag_hint(bcx));
16991720

17001721
// Now that memory is initialized and has cleanup scheduled,
1701-
// create the datum and insert into the local variable map.
1702-
let lval = Lvalue::binding(caller_name, bcx, p_id, name);
1703-
let datum = Datum::new(llval, var_ty, lval);
1722+
// insert datum into the local variable map.
17041723
bcx.fcx.lllocals.borrow_mut().insert(p_id, datum);
17051724
bcx
17061725
}
@@ -1746,7 +1765,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
17461765
bcx = mk_binding_alloca(
17471766
bcx, pat.id, path1.node.name, cleanup_scope, (),
17481767
"_match::bind_irrefutable_pat",
1749-
|(), bcx, llval, ty| {
1768+
|(), bcx, Datum { val: llval, ty, kind: _ }| {
17501769
match pat_binding_mode {
17511770
ast::BindByValue(_) => {
17521771
// By value binding: move the value that `val`
@@ -1854,10 +1873,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
18541873
ast::PatBox(ref inner) => {
18551874
let llbox = Load(bcx, val.val);
18561875
bcx = bind_irrefutable_pat(
1857-
bcx,
1858-
&**inner,
1859-
MatchInput::from_val(llbox),
1860-
cleanup_scope);
1876+
bcx, &**inner, MatchInput::from_val(llbox), cleanup_scope);
18611877
}
18621878
ast::PatRegion(ref inner, _) => {
18631879
let loaded_val = Load(bcx, val.val);
@@ -1884,13 +1900,13 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
18841900
.chain(slice.iter())
18851901
.chain(after.iter())
18861902
.zip(extracted.vals)
1887-
.fold(bcx, |bcx, (inner, elem)|
1903+
.fold(bcx, |bcx, (inner, elem)| {
18881904
bind_irrefutable_pat(
18891905
bcx,
18901906
&**inner,
18911907
MatchInput::from_val(elem),
18921908
cleanup_scope)
1893-
);
1909+
});
18941910
}
18951911
ast::PatMac(..) => {
18961912
bcx.sess().span_bug(pat.span, "unexpanded macro");

branches/try/src/librustc_trans/trans/adt.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,20 @@ macro_rules! repeat_u8_as_u64 {
163163
(repeat_u8_as_u32!($name) as u64)) }
164164
}
165165

166+
/// `DTOR_NEEDED_HINT` is a stack-local hint that just means
167+
/// "we do not know whether the destructor has run or not; check the
168+
/// drop-flag embedded in the value itself."
169+
pub const DTOR_NEEDED_HINT: u8 = 0x3d;
170+
171+
/// `DTOR_MOVED_HINT` is a stack-local hint that means "this value has
172+
/// definitely been moved; you do not need to run its destructor."
173+
///
174+
/// (However, for now, such values may still end up being explicitly
175+
/// zeroed by the generated code; this is the distinction between
176+
/// `datum::DropFlagInfo::ZeroAndMaintain` versus
177+
/// `datum::DropFlagInfo::DontZeroJustUse`.)
178+
pub const DTOR_MOVED_HINT: u8 = 0x2d;
179+
166180
pub const DTOR_NEEDED: u8 = 0xd4;
167181
pub const DTOR_NEEDED_U32: u32 = repeat_u8_as_u32!(DTOR_NEEDED);
168182
pub const DTOR_NEEDED_U64: u64 = repeat_u8_as_u64!(DTOR_NEEDED);

branches/try/src/librustc_trans/trans/base.rs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ use trans::attributes;
5151
use trans::build::*;
5252
use trans::builder::{Builder, noname};
5353
use trans::callee;
54-
use trans::cleanup::CleanupMethods;
55-
use trans::cleanup;
54+
use trans::cleanup::{self, CleanupMethods, DropHint};
5655
use trans::closure;
5756
use trans::common::{Block, C_bool, C_bytes_in_context, C_i32, C_int, C_integral};
5857
use trans::common::{C_null, C_struct_in_context, C_u64, C_u8, C_undef};
@@ -88,7 +87,7 @@ use arena::TypedArena;
8887
use libc::c_uint;
8988
use std::ffi::{CStr, CString};
9089
use std::cell::{Cell, RefCell};
91-
use std::collections::HashSet;
90+
use std::collections::{HashMap, HashSet};
9291
use std::mem;
9392
use std::str;
9493
use std::{i8, i16, i32, i64};
@@ -1284,6 +1283,54 @@ pub fn init_function<'a, 'tcx>(fcx: &'a FunctionContext<'a, 'tcx>,
12841283
}
12851284
}
12861285

1286+
// Create the drop-flag hints for every unfragmented path in the function.
1287+
let tcx = fcx.ccx.tcx();
1288+
let fn_did = ast::DefId { krate: ast::LOCAL_CRATE, node: fcx.id };
1289+
let mut hints = fcx.lldropflag_hints.borrow_mut();
1290+
let fragment_infos = tcx.fragment_infos.borrow();
1291+
1292+
// Intern table for drop-flag hint datums.
1293+
let mut seen = HashMap::new();
1294+
1295+
if let Some(fragment_infos) = fragment_infos.get(&fn_did) {
1296+
for &info in fragment_infos {
1297+
1298+
let make_datum = |id| {
1299+
let init_val = C_u8(fcx.ccx, adt::DTOR_NEEDED_HINT as usize);
1300+
let llname = &format!("dropflag_hint_{}", id);
1301+
debug!("adding hint {}", llname);
1302+
let ptr = alloc_ty(entry_bcx, tcx.types.u8, llname);
1303+
Store(entry_bcx, init_val, ptr);
1304+
let ty = tcx.mk_ptr(ty::TypeAndMut { ty: tcx.types.u8, mutbl: ast::MutMutable });
1305+
let flag = datum::Lvalue::new_dropflag_hint("base::init_function");
1306+
let datum = datum::Datum::new(ptr, ty, flag);
1307+
datum
1308+
};
1309+
1310+
let (var, datum) = match info {
1311+
ty::FragmentInfo::Moved { var, .. } |
1312+
ty::FragmentInfo::Assigned { var, .. } => {
1313+
let datum = seen.get(&var).cloned().unwrap_or_else(|| {
1314+
let datum = make_datum(var);
1315+
seen.insert(var, datum.clone());
1316+
datum
1317+
});
1318+
(var, datum)
1319+
}
1320+
};
1321+
match info {
1322+
ty::FragmentInfo::Moved { move_expr: expr_id, .. } => {
1323+
debug!("FragmentInfo::Moved insert drop hint for {}", expr_id);
1324+
hints.insert(expr_id, DropHint::new(var, datum));
1325+
}
1326+
ty::FragmentInfo::Assigned { assignee_id: expr_id, .. } => {
1327+
debug!("FragmentInfo::Assigned insert drop hint for {}", expr_id);
1328+
hints.insert(expr_id, DropHint::new(var, datum));
1329+
}
1330+
}
1331+
}
1332+
}
1333+
12871334
entry_bcx
12881335
}
12891336

0 commit comments

Comments
 (0)