Emit lifetime end markers for function arguments
Function arguments are (hopefully!) the last places where allocas don't
get proper markers for the end of their lifetimes. This means that this
code using 64 bytes of stack for the function arguments:
````rust
std::io::println("1");
std::io::println("2");
std::io::println("3");
std::io::println("4");
````
But with the proper lifetime markers, the slots can be reused, and
the arguments only need 16 bytes of stack.
This commit is contained in:
parent
70d8b8ddc5
commit
fafe136c2d
2 changed files with 26 additions and 2 deletions
|
|
@ -788,7 +788,7 @@ pub fn trans_call_inner<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
llself.is_some(),
|
||||
abi);
|
||||
|
||||
fcx.pop_custom_cleanup_scope(arg_cleanup_scope);
|
||||
fcx.scopes.borrow_mut().last_mut().unwrap().drop_non_lifetime_clean();
|
||||
|
||||
// Invoke the actual rust fn and update bcx/llresult.
|
||||
let (llret, b) = base::invoke(bcx,
|
||||
|
|
@ -829,12 +829,15 @@ pub fn trans_call_inner<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
cleanup::CustomScope(arg_cleanup_scope),
|
||||
false,
|
||||
abi);
|
||||
fcx.pop_custom_cleanup_scope(arg_cleanup_scope);
|
||||
fcx.scopes.borrow_mut().last_mut().unwrap().drop_non_lifetime_clean();
|
||||
|
||||
bcx = foreign::trans_native_call(bcx, callee_ty,
|
||||
llfn, opt_llretslot.unwrap(),
|
||||
llargs.as_slice(), arg_tys);
|
||||
}
|
||||
|
||||
fcx.pop_and_trans_custom_cleanup_scope(bcx, arg_cleanup_scope);
|
||||
|
||||
// If the caller doesn't care about the result of this fn call,
|
||||
// drop the temporary slot we made.
|
||||
match (dest, opt_llretslot) {
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ pub struct CachedEarlyExit {
|
|||
pub trait Cleanup {
|
||||
fn must_unwind(&self) -> bool;
|
||||
fn clean_on_unwind(&self) -> bool;
|
||||
fn is_lifetime_end(&self) -> bool;
|
||||
fn trans<'blk, 'tcx>(&self,
|
||||
bcx: Block<'blk, 'tcx>,
|
||||
debug_loc: Option<NodeInfo>)
|
||||
|
|
@ -875,6 +876,10 @@ impl<'blk, 'tcx> CleanupScope<'blk, 'tcx> {
|
|||
LoopScopeKind(id, _) => format!("{}_loop_{}_", prefix, id),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn drop_non_lifetime_clean(&mut self) {
|
||||
self.cleanups.retain(|c| c.is_lifetime_end());
|
||||
}
|
||||
}
|
||||
|
||||
impl<'blk, 'tcx> CleanupScopeKind<'blk, 'tcx> {
|
||||
|
|
@ -943,6 +948,10 @@ impl Cleanup for DropValue {
|
|||
self.must_unwind
|
||||
}
|
||||
|
||||
fn is_lifetime_end(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn trans<'blk, 'tcx>(&self,
|
||||
bcx: Block<'blk, 'tcx>,
|
||||
debug_loc: Option<NodeInfo>)
|
||||
|
|
@ -978,6 +987,10 @@ impl Cleanup for FreeValue {
|
|||
true
|
||||
}
|
||||
|
||||
fn is_lifetime_end(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn trans<'blk, 'tcx>(&self,
|
||||
bcx: Block<'blk, 'tcx>,
|
||||
debug_loc: Option<NodeInfo>)
|
||||
|
|
@ -1008,6 +1021,10 @@ impl Cleanup for FreeSlice {
|
|||
true
|
||||
}
|
||||
|
||||
fn is_lifetime_end(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn trans<'blk, 'tcx>(&self,
|
||||
bcx: Block<'blk, 'tcx>,
|
||||
debug_loc: Option<NodeInfo>)
|
||||
|
|
@ -1035,6 +1052,10 @@ impl Cleanup for LifetimeEnd {
|
|||
true
|
||||
}
|
||||
|
||||
fn is_lifetime_end(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn trans<'blk, 'tcx>(&self,
|
||||
bcx: Block<'blk, 'tcx>,
|
||||
debug_loc: Option<NodeInfo>)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue