Skip to content

Commit 9e9b3f0

Browse files
committed
---
yaml --- r: 15222 b: refs/heads/try c: b420f46 h: refs/heads/master v: v3
1 parent c956430 commit 9e9b3f0

File tree

5 files changed

+91
-12
lines changed

5 files changed

+91
-12
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
refs/heads/master: 61b1875c16de39c166b0f4d54bba19f9c6777d1a
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
5-
refs/heads/try: 3a7a408386b8b1fbeb82cf6d695a168296c02793
5+
refs/heads/try: b420f46f0309ff9fe681fc7f6b4d5412ab40a439
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105

branches/try/src/libuv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Subproject commit 1d6aec9d54c7a684ade521f71a4d538a6a88b14f
1+
Subproject commit 1170ffba3ac5191930b40c897d4569a9d8a296a3

branches/try/src/rustc/middle/trans/base.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3640,15 +3640,27 @@ fn raw_block(fcx: fn_ctxt, llbb: BasicBlockRef) -> block {
36403640
// need to make sure those variables go out of scope when the block ends. We
36413641
// do that by running a 'cleanup' function for each variable.
36423642
// trans_block_cleanups runs all the cleanup functions for the block.
3643-
fn trans_block_cleanups(bcx: block, cleanup_cx: block) ->
3643+
fn trans_block_cleanups(bcx: block, cleanup_cx: block) -> block {
3644+
trans_block_cleanups_(bcx, cleanup_cx, false)
3645+
}
3646+
3647+
fn trans_block_cleanups_(bcx: block, cleanup_cx: block, is_lpad: bool) ->
36443648
block {
36453649
let _icx = bcx.insn_ctxt("trans_block_cleanups");
36463650
if bcx.unreachable { ret bcx; }
36473651
let mut bcx = bcx;
36483652
alt check cleanup_cx.kind {
36493653
block_scope({cleanups, _}) {
36503654
vec::riter(copy cleanups) {|cu|
3651-
alt cu { clean(cfn) | clean_temp(_, cfn) { bcx = cfn(bcx); } }
3655+
alt cu {
3656+
clean(cfn, cleanup_type) | clean_temp(_, cfn, cleanup_type) {
3657+
// Some types don't need to be cleaned up during
3658+
// landing pads because they can be freed en mass later
3659+
if cleanup_type == normal_exit_and_unwind || !is_lpad {
3660+
bcx = cfn(bcx);
3661+
}
3662+
}
3663+
}
36523664
}
36533665
}
36543666
}
@@ -3662,6 +3674,7 @@ fn cleanup_and_leave(bcx: block, upto: option<BasicBlockRef>,
36623674
leave: option<BasicBlockRef>) {
36633675
let _icx = bcx.insn_ctxt("cleanup_and_leave");
36643676
let mut cur = bcx, bcx = bcx;
3677+
let is_lpad = leave == none;
36653678
loop {
36663679
alt cur.kind {
36673680
block_scope(info) if info.cleanups.len() > 0u {
@@ -3674,7 +3687,7 @@ fn cleanup_and_leave(bcx: block, upto: option<BasicBlockRef>,
36743687
let sub_cx = sub_block(bcx, "cleanup");
36753688
Br(bcx, sub_cx.llbb);
36763689
info.cleanup_paths += [{target: leave, dest: sub_cx.llbb}];
3677-
bcx = trans_block_cleanups(sub_cx, cur);
3690+
bcx = trans_block_cleanups_(sub_cx, cur, is_lpad);
36783691
}
36793692
_ {}
36803693
}

branches/try/src/rustc/middle/trans/common.rs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,14 @@ fn warn_not_to_commit(ccx: @crate_ctxt, msg: str) {
201201
}
202202
}
203203

204+
enum cleantype {
205+
normal_exit_only,
206+
normal_exit_and_unwind
207+
}
208+
204209
enum cleanup {
205-
clean(fn@(block) -> block),
206-
clean_temp(ValueRef, fn@(block) -> block),
210+
clean(fn@(block) -> block, cleantype),
211+
clean_temp(ValueRef, fn@(block) -> block, cleantype),
207212
}
208213

209214
// Used to remember and reuse existing cleanup paths
@@ -216,15 +221,26 @@ fn scope_clean_changed(info: scope_info) {
216221
info.landing_pad = none;
217222
}
218223

224+
fn cleanup_type(cx: ty::ctxt, ty: ty::t) -> cleantype {
225+
if ty::type_needs_unwind_cleanup(cx, ty) {
226+
normal_exit_and_unwind
227+
} else {
228+
normal_exit_only
229+
}
230+
}
231+
219232
fn add_clean(cx: block, val: ValueRef, ty: ty::t) {
220233
if !ty::type_needs_drop(cx.tcx(), ty) { ret; }
234+
let cleanup_type = cleanup_type(cx.tcx(), ty);
221235
in_scope_cx(cx) {|info|
222-
info.cleanups += [clean(bind base::drop_ty(_, val, ty))];
236+
info.cleanups += [clean(bind base::drop_ty(_, val, ty),
237+
cleanup_type)];
223238
scope_clean_changed(info);
224239
}
225240
}
226241
fn add_clean_temp(cx: block, val: ValueRef, ty: ty::t) {
227242
if !ty::type_needs_drop(cx.tcx(), ty) { ret; }
243+
let cleanup_type = cleanup_type(cx.tcx(), ty);
228244
fn do_drop(bcx: block, val: ValueRef, ty: ty::t) ->
229245
block {
230246
if ty::type_is_immediate(ty) {
@@ -234,22 +250,26 @@ fn add_clean_temp(cx: block, val: ValueRef, ty: ty::t) {
234250
}
235251
}
236252
in_scope_cx(cx) {|info|
237-
info.cleanups += [clean_temp(val, bind do_drop(_, val, ty))];
253+
info.cleanups += [clean_temp(val, bind do_drop(_, val, ty),
254+
cleanup_type)];
238255
scope_clean_changed(info);
239256
}
240257
}
241258
fn add_clean_temp_mem(cx: block, val: ValueRef, ty: ty::t) {
242259
if !ty::type_needs_drop(cx.tcx(), ty) { ret; }
260+
let cleanup_type = cleanup_type(cx.tcx(), ty);
243261
in_scope_cx(cx) {|info|
244-
info.cleanups += [clean_temp(val, bind base::drop_ty(_, val, ty))];
262+
info.cleanups += [clean_temp(val, bind base::drop_ty(_, val, ty),
263+
cleanup_type)];
245264
scope_clean_changed(info);
246265
}
247266
}
248267
fn add_clean_free(cx: block, ptr: ValueRef, shared: bool) {
249268
let free_fn = if shared { bind base::trans_shared_free(_, ptr) }
250269
else { bind base::trans_free(_, ptr) };
251270
in_scope_cx(cx) {|info|
252-
info.cleanups += [clean_temp(ptr, free_fn)];
271+
info.cleanups += [clean_temp(ptr, free_fn,
272+
normal_exit_and_unwind)];
253273
scope_clean_changed(info);
254274
}
255275
}
@@ -263,7 +283,7 @@ fn revoke_clean(cx: block, val: ValueRef) {
263283
let mut i = 0u;
264284
for cu in info.cleanups {
265285
alt cu {
266-
clean_temp(v, _) if v == val {
286+
clean_temp(v, _, _) if v == val {
267287
info.cleanups =
268288
vec::slice(info.cleanups, 0u, i) +
269289
vec::slice(info.cleanups, i + 1u, info.cleanups.len());

branches/try/src/rustc/middle/ty.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ export type_structurally_contains;
121121
export type_structurally_contains_uniques;
122122
export type_autoderef;
123123
export type_param;
124+
export type_needs_unwind_cleanup;
124125
export canon_mode;
125126
export resolved_mode;
126127
export arg_mode;
@@ -201,6 +202,7 @@ type ctxt =
201202
rcache: creader_cache,
202203
short_names_cache: hashmap<t, @str>,
203204
needs_drop_cache: hashmap<t, bool>,
205+
needs_unwind_cleanup_cache: hashmap<t, bool>,
204206
kind_cache: hashmap<t, kind>,
205207
ast_ty_to_ty_cache: hashmap<@ast::ty, ast_ty_to_ty_cache_entry>,
206208
enum_var_cache: hashmap<def_id, @[variant_info]>,
@@ -388,6 +390,7 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map,
388390
rcache: mk_rcache(),
389391
short_names_cache: new_ty_hash(),
390392
needs_drop_cache: new_ty_hash(),
393+
needs_unwind_cleanup_cache: new_ty_hash(),
391394
kind_cache: new_ty_hash(),
392395
ast_ty_to_ty_cache: map::hashmap(
393396
ast_util::hash_ty, ast_util::eq_ty),
@@ -902,6 +905,48 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
902905
ret result;
903906
}
904907

908+
// Some things don't need cleanups during unwinding because the
909+
// task can free them all at once later. Currently only things
910+
// that only contain scalars and shared boxes can avoid unwind
911+
// cleanups.
912+
fn type_needs_unwind_cleanup(cx: ctxt, ty: t) -> bool {
913+
alt cx.needs_unwind_cleanup_cache.find(ty) {
914+
some(result) { ret result; }
915+
none { }
916+
}
917+
918+
// Prevent infinite recursion
919+
cx.needs_unwind_cleanup_cache.insert(ty, false);
920+
921+
let mut needs_unwind_cleanup = false;
922+
maybe_walk_ty(ty) {|ty|
923+
alt get(ty).struct {
924+
ty_nil | ty_bot | ty_bool |
925+
ty_int(_) | ty_uint(_) | ty_float(_) |
926+
ty_box(_) | ty_rec(_) | ty_tup(_) {
927+
true
928+
}
929+
ty_enum(did, tps) {
930+
for v in *enum_variants(cx, did) {
931+
for aty in v.args {
932+
let t = substitute_type_params(cx, tps, aty);
933+
needs_unwind_cleanup |= type_needs_unwind_cleanup(cx, t);
934+
}
935+
}
936+
!needs_unwind_cleanup
937+
}
938+
_ {
939+
needs_unwind_cleanup = true;
940+
false
941+
}
942+
}
943+
}
944+
945+
cx.needs_unwind_cleanup_cache.insert(ty, needs_unwind_cleanup);
946+
947+
ret needs_unwind_cleanup;
948+
}
949+
905950
enum kind { kind_sendable, kind_copyable, kind_noncopyable, }
906951

907952
// Using these query functons is preferable to direct comparison or matching
@@ -2323,6 +2368,7 @@ fn ast_constr_to_constr<T>(tcx: ctxt, c: @ast::constr_general<T>) ->
23232368
}
23242369
}
23252370

2371+
23262372
// Local Variables:
23272373
// mode: rust
23282374
// fill-column: 78;

0 commit comments

Comments
 (0)