mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 14:43:24 +00:00
rustc: Don't generate landing pad cleanups for boxy things
This commit is contained in:
parent
3a7a408386
commit
b420f46f03
@ -1 +1 @@
|
||||
Subproject commit 1d6aec9d54c7a684ade521f71a4d538a6a88b14f
|
||||
Subproject commit 1170ffba3ac5191930b40c897d4569a9d8a296a3
|
@ -3640,7 +3640,11 @@ fn raw_block(fcx: fn_ctxt, llbb: BasicBlockRef) -> block {
|
||||
// need to make sure those variables go out of scope when the block ends. We
|
||||
// do that by running a 'cleanup' function for each variable.
|
||||
// trans_block_cleanups runs all the cleanup functions for the block.
|
||||
fn trans_block_cleanups(bcx: block, cleanup_cx: block) ->
|
||||
fn trans_block_cleanups(bcx: block, cleanup_cx: block) -> block {
|
||||
trans_block_cleanups_(bcx, cleanup_cx, false)
|
||||
}
|
||||
|
||||
fn trans_block_cleanups_(bcx: block, cleanup_cx: block, is_lpad: bool) ->
|
||||
block {
|
||||
let _icx = bcx.insn_ctxt("trans_block_cleanups");
|
||||
if bcx.unreachable { ret bcx; }
|
||||
@ -3648,7 +3652,15 @@ fn trans_block_cleanups(bcx: block, cleanup_cx: block) ->
|
||||
alt check cleanup_cx.kind {
|
||||
block_scope({cleanups, _}) {
|
||||
vec::riter(copy cleanups) {|cu|
|
||||
alt cu { clean(cfn) | clean_temp(_, cfn) { bcx = cfn(bcx); } }
|
||||
alt cu {
|
||||
clean(cfn, cleanup_type) | clean_temp(_, cfn, cleanup_type) {
|
||||
// Some types don't need to be cleaned up during
|
||||
// landing pads because they can be freed en mass later
|
||||
if cleanup_type == normal_exit_and_unwind || !is_lpad {
|
||||
bcx = cfn(bcx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3662,6 +3674,7 @@ fn cleanup_and_leave(bcx: block, upto: option<BasicBlockRef>,
|
||||
leave: option<BasicBlockRef>) {
|
||||
let _icx = bcx.insn_ctxt("cleanup_and_leave");
|
||||
let mut cur = bcx, bcx = bcx;
|
||||
let is_lpad = leave == none;
|
||||
loop {
|
||||
alt cur.kind {
|
||||
block_scope(info) if info.cleanups.len() > 0u {
|
||||
@ -3674,7 +3687,7 @@ fn cleanup_and_leave(bcx: block, upto: option<BasicBlockRef>,
|
||||
let sub_cx = sub_block(bcx, "cleanup");
|
||||
Br(bcx, sub_cx.llbb);
|
||||
info.cleanup_paths += [{target: leave, dest: sub_cx.llbb}];
|
||||
bcx = trans_block_cleanups(sub_cx, cur);
|
||||
bcx = trans_block_cleanups_(sub_cx, cur, is_lpad);
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
|
@ -201,9 +201,14 @@ fn warn_not_to_commit(ccx: @crate_ctxt, msg: str) {
|
||||
}
|
||||
}
|
||||
|
||||
enum cleantype {
|
||||
normal_exit_only,
|
||||
normal_exit_and_unwind
|
||||
}
|
||||
|
||||
enum cleanup {
|
||||
clean(fn@(block) -> block),
|
||||
clean_temp(ValueRef, fn@(block) -> block),
|
||||
clean(fn@(block) -> block, cleantype),
|
||||
clean_temp(ValueRef, fn@(block) -> block, cleantype),
|
||||
}
|
||||
|
||||
// Used to remember and reuse existing cleanup paths
|
||||
@ -216,15 +221,26 @@ fn scope_clean_changed(info: scope_info) {
|
||||
info.landing_pad = none;
|
||||
}
|
||||
|
||||
fn cleanup_type(cx: ty::ctxt, ty: ty::t) -> cleantype {
|
||||
if ty::type_needs_unwind_cleanup(cx, ty) {
|
||||
normal_exit_and_unwind
|
||||
} else {
|
||||
normal_exit_only
|
||||
}
|
||||
}
|
||||
|
||||
fn add_clean(cx: block, val: ValueRef, ty: ty::t) {
|
||||
if !ty::type_needs_drop(cx.tcx(), ty) { ret; }
|
||||
let cleanup_type = cleanup_type(cx.tcx(), ty);
|
||||
in_scope_cx(cx) {|info|
|
||||
info.cleanups += [clean(bind base::drop_ty(_, val, ty))];
|
||||
info.cleanups += [clean(bind base::drop_ty(_, val, ty),
|
||||
cleanup_type)];
|
||||
scope_clean_changed(info);
|
||||
}
|
||||
}
|
||||
fn add_clean_temp(cx: block, val: ValueRef, ty: ty::t) {
|
||||
if !ty::type_needs_drop(cx.tcx(), ty) { ret; }
|
||||
let cleanup_type = cleanup_type(cx.tcx(), ty);
|
||||
fn do_drop(bcx: block, val: ValueRef, ty: ty::t) ->
|
||||
block {
|
||||
if ty::type_is_immediate(ty) {
|
||||
@ -234,14 +250,17 @@ fn add_clean_temp(cx: block, val: ValueRef, ty: ty::t) {
|
||||
}
|
||||
}
|
||||
in_scope_cx(cx) {|info|
|
||||
info.cleanups += [clean_temp(val, bind do_drop(_, val, ty))];
|
||||
info.cleanups += [clean_temp(val, bind do_drop(_, val, ty),
|
||||
cleanup_type)];
|
||||
scope_clean_changed(info);
|
||||
}
|
||||
}
|
||||
fn add_clean_temp_mem(cx: block, val: ValueRef, ty: ty::t) {
|
||||
if !ty::type_needs_drop(cx.tcx(), ty) { ret; }
|
||||
let cleanup_type = cleanup_type(cx.tcx(), ty);
|
||||
in_scope_cx(cx) {|info|
|
||||
info.cleanups += [clean_temp(val, bind base::drop_ty(_, val, ty))];
|
||||
info.cleanups += [clean_temp(val, bind base::drop_ty(_, val, ty),
|
||||
cleanup_type)];
|
||||
scope_clean_changed(info);
|
||||
}
|
||||
}
|
||||
@ -249,7 +268,8 @@ fn add_clean_free(cx: block, ptr: ValueRef, shared: bool) {
|
||||
let free_fn = if shared { bind base::trans_shared_free(_, ptr) }
|
||||
else { bind base::trans_free(_, ptr) };
|
||||
in_scope_cx(cx) {|info|
|
||||
info.cleanups += [clean_temp(ptr, free_fn)];
|
||||
info.cleanups += [clean_temp(ptr, free_fn,
|
||||
normal_exit_and_unwind)];
|
||||
scope_clean_changed(info);
|
||||
}
|
||||
}
|
||||
@ -263,7 +283,7 @@ fn revoke_clean(cx: block, val: ValueRef) {
|
||||
let mut i = 0u;
|
||||
for cu in info.cleanups {
|
||||
alt cu {
|
||||
clean_temp(v, _) if v == val {
|
||||
clean_temp(v, _, _) if v == val {
|
||||
info.cleanups =
|
||||
vec::slice(info.cleanups, 0u, i) +
|
||||
vec::slice(info.cleanups, i + 1u, info.cleanups.len());
|
||||
|
@ -121,6 +121,7 @@ export type_structurally_contains;
|
||||
export type_structurally_contains_uniques;
|
||||
export type_autoderef;
|
||||
export type_param;
|
||||
export type_needs_unwind_cleanup;
|
||||
export canon_mode;
|
||||
export resolved_mode;
|
||||
export arg_mode;
|
||||
@ -201,6 +202,7 @@ type ctxt =
|
||||
rcache: creader_cache,
|
||||
short_names_cache: hashmap<t, @str>,
|
||||
needs_drop_cache: hashmap<t, bool>,
|
||||
needs_unwind_cleanup_cache: hashmap<t, bool>,
|
||||
kind_cache: hashmap<t, kind>,
|
||||
ast_ty_to_ty_cache: hashmap<@ast::ty, ast_ty_to_ty_cache_entry>,
|
||||
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,
|
||||
rcache: mk_rcache(),
|
||||
short_names_cache: new_ty_hash(),
|
||||
needs_drop_cache: new_ty_hash(),
|
||||
needs_unwind_cleanup_cache: new_ty_hash(),
|
||||
kind_cache: new_ty_hash(),
|
||||
ast_ty_to_ty_cache: map::hashmap(
|
||||
ast_util::hash_ty, ast_util::eq_ty),
|
||||
@ -902,6 +905,48 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
|
||||
ret result;
|
||||
}
|
||||
|
||||
// Some things don't need cleanups during unwinding because the
|
||||
// task can free them all at once later. Currently only things
|
||||
// that only contain scalars and shared boxes can avoid unwind
|
||||
// cleanups.
|
||||
fn type_needs_unwind_cleanup(cx: ctxt, ty: t) -> bool {
|
||||
alt cx.needs_unwind_cleanup_cache.find(ty) {
|
||||
some(result) { ret result; }
|
||||
none { }
|
||||
}
|
||||
|
||||
// Prevent infinite recursion
|
||||
cx.needs_unwind_cleanup_cache.insert(ty, false);
|
||||
|
||||
let mut needs_unwind_cleanup = false;
|
||||
maybe_walk_ty(ty) {|ty|
|
||||
alt get(ty).struct {
|
||||
ty_nil | ty_bot | ty_bool |
|
||||
ty_int(_) | ty_uint(_) | ty_float(_) |
|
||||
ty_box(_) | ty_rec(_) | ty_tup(_) {
|
||||
true
|
||||
}
|
||||
ty_enum(did, tps) {
|
||||
for v in *enum_variants(cx, did) {
|
||||
for aty in v.args {
|
||||
let t = substitute_type_params(cx, tps, aty);
|
||||
needs_unwind_cleanup |= type_needs_unwind_cleanup(cx, t);
|
||||
}
|
||||
}
|
||||
!needs_unwind_cleanup
|
||||
}
|
||||
_ {
|
||||
needs_unwind_cleanup = true;
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cx.needs_unwind_cleanup_cache.insert(ty, needs_unwind_cleanup);
|
||||
|
||||
ret needs_unwind_cleanup;
|
||||
}
|
||||
|
||||
enum kind { kind_sendable, kind_copyable, kind_noncopyable, }
|
||||
|
||||
// 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>) ->
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
// fill-column: 78;
|
||||
|
Loading…
Reference in New Issue
Block a user