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:
Björn Steinbrink 2014-10-13 16:12:38 +02:00
parent 70d8b8ddc5
commit fafe136c2d
2 changed files with 26 additions and 2 deletions

View File

@ -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) {

View File

@ -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>)