rustc: Only invoke when there are cleanups
This commit is contained in:
parent
8780db2e0b
commit
7f9ed39040
@ -571,7 +571,6 @@ when unwinding through __morestack).
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
rust_task::reset_stack_limit() {
|
rust_task::reset_stack_limit() {
|
||||||
I(thread, on_rust_stack());
|
|
||||||
uintptr_t sp = get_sp();
|
uintptr_t sp = get_sp();
|
||||||
// Have to do the rest on the C stack because it involves
|
// Have to do the rest on the C stack because it involves
|
||||||
// freeing stack segments, logging, etc.
|
// freeing stack segments, logging, etc.
|
||||||
|
@ -2761,16 +2761,59 @@ fn trans_call_inner(in_cx: block, fn_expr_ty: ty::t, ret_ty: ty::t,
|
|||||||
|
|
||||||
fn invoke(bcx: block, llfn: ValueRef, llargs: [ValueRef]) -> block {
|
fn invoke(bcx: block, llfn: ValueRef, llargs: [ValueRef]) -> block {
|
||||||
let _icx = bcx.insn_ctxt("invoke_");
|
let _icx = bcx.insn_ctxt("invoke_");
|
||||||
// FIXME: May be worth turning this into a plain call when there are no
|
|
||||||
// cleanups to run
|
|
||||||
if bcx.unreachable { ret bcx; }
|
if bcx.unreachable { ret bcx; }
|
||||||
|
if need_invoke(bcx) {
|
||||||
|
log(error, "invoking");
|
||||||
let normal_bcx = sub_block(bcx, "normal return");
|
let normal_bcx = sub_block(bcx, "normal return");
|
||||||
Invoke(bcx, llfn, llargs, normal_bcx.llbb, get_landing_pad(bcx));
|
Invoke(bcx, llfn, llargs, normal_bcx.llbb, get_landing_pad(bcx));
|
||||||
ret normal_bcx;
|
ret normal_bcx;
|
||||||
|
} else {
|
||||||
|
log(error, "calling");
|
||||||
|
Call(bcx, llfn, llargs);
|
||||||
|
ret bcx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn need_invoke(bcx: block) -> bool {
|
||||||
|
if have_cached_lpad(bcx) {
|
||||||
|
ret true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Walk the scopes to look for cleanups
|
||||||
|
let mut cur = bcx;
|
||||||
|
loop {
|
||||||
|
alt cur.kind {
|
||||||
|
block_scope(info) {
|
||||||
|
for cleanup in info.cleanups {
|
||||||
|
alt cleanup {
|
||||||
|
clean(_, cleanup_type) | clean_temp(_, _, cleanup_type) {
|
||||||
|
if cleanup_type == normal_exit_and_unwind {
|
||||||
|
ret true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ { }
|
||||||
|
}
|
||||||
|
cur = alt cur.parent {
|
||||||
|
parent_some(next) { next }
|
||||||
|
parent_none { ret false; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn have_cached_lpad(bcx: block) -> bool {
|
||||||
|
let mut res = false;
|
||||||
|
in_lpad_scope_cx(bcx) {|info|
|
||||||
|
alt info.landing_pad {
|
||||||
|
some(_) { res = true; }
|
||||||
|
none { res = false; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret res;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_landing_pad(bcx: block) -> BasicBlockRef {
|
|
||||||
let _icx = bcx.insn_ctxt("get_landing_pad");
|
|
||||||
fn in_lpad_scope_cx(bcx: block, f: fn(scope_info)) {
|
fn in_lpad_scope_cx(bcx: block, f: fn(scope_info)) {
|
||||||
let mut bcx = bcx;
|
let mut bcx = bcx;
|
||||||
loop {
|
loop {
|
||||||
@ -2786,6 +2829,9 @@ fn get_landing_pad(bcx: block) -> BasicBlockRef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_landing_pad(bcx: block) -> BasicBlockRef {
|
||||||
|
let _icx = bcx.insn_ctxt("get_landing_pad");
|
||||||
|
|
||||||
let mut cached = none, pad_bcx = bcx; // Guaranteed to be set below
|
let mut cached = none, pad_bcx = bcx; // Guaranteed to be set below
|
||||||
in_lpad_scope_cx(bcx) {|info|
|
in_lpad_scope_cx(bcx) {|info|
|
||||||
// If there is a valid landing pad still around, use it
|
// If there is a valid landing pad still around, use it
|
||||||
|
Loading…
Reference in New Issue
Block a user