Skip to content

Commit fafe136

Browse files
committed
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.
1 parent 70d8b8d commit fafe136

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

src/librustc/middle/trans/callee.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,7 @@ pub fn trans_call_inner<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
788788
llself.is_some(),
789789
abi);
790790

791-
fcx.pop_custom_cleanup_scope(arg_cleanup_scope);
791+
fcx.scopes.borrow_mut().last_mut().unwrap().drop_non_lifetime_clean();
792792

793793
// Invoke the actual rust fn and update bcx/llresult.
794794
let (llret, b) = base::invoke(bcx,
@@ -829,12 +829,15 @@ pub fn trans_call_inner<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
829829
cleanup::CustomScope(arg_cleanup_scope),
830830
false,
831831
abi);
832-
fcx.pop_custom_cleanup_scope(arg_cleanup_scope);
832+
fcx.scopes.borrow_mut().last_mut().unwrap().drop_non_lifetime_clean();
833+
833834
bcx = foreign::trans_native_call(bcx, callee_ty,
834835
llfn, opt_llretslot.unwrap(),
835836
llargs.as_slice(), arg_tys);
836837
}
837838

839+
fcx.pop_and_trans_custom_cleanup_scope(bcx, arg_cleanup_scope);
840+
838841
// If the caller doesn't care about the result of this fn call,
839842
// drop the temporary slot we made.
840843
match (dest, opt_llretslot) {

src/librustc/middle/trans/cleanup.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ pub struct CachedEarlyExit {
7474
pub trait Cleanup {
7575
fn must_unwind(&self) -> bool;
7676
fn clean_on_unwind(&self) -> bool;
77+
fn is_lifetime_end(&self) -> bool;
7778
fn trans<'blk, 'tcx>(&self,
7879
bcx: Block<'blk, 'tcx>,
7980
debug_loc: Option<NodeInfo>)
@@ -875,6 +876,10 @@ impl<'blk, 'tcx> CleanupScope<'blk, 'tcx> {
875876
LoopScopeKind(id, _) => format!("{}_loop_{}_", prefix, id),
876877
}
877878
}
879+
880+
pub fn drop_non_lifetime_clean(&mut self) {
881+
self.cleanups.retain(|c| c.is_lifetime_end());
882+
}
878883
}
879884

880885
impl<'blk, 'tcx> CleanupScopeKind<'blk, 'tcx> {
@@ -943,6 +948,10 @@ impl Cleanup for DropValue {
943948
self.must_unwind
944949
}
945950

951+
fn is_lifetime_end(&self) -> bool {
952+
false
953+
}
954+
946955
fn trans<'blk, 'tcx>(&self,
947956
bcx: Block<'blk, 'tcx>,
948957
debug_loc: Option<NodeInfo>)
@@ -978,6 +987,10 @@ impl Cleanup for FreeValue {
978987
true
979988
}
980989

990+
fn is_lifetime_end(&self) -> bool {
991+
false
992+
}
993+
981994
fn trans<'blk, 'tcx>(&self,
982995
bcx: Block<'blk, 'tcx>,
983996
debug_loc: Option<NodeInfo>)
@@ -1008,6 +1021,10 @@ impl Cleanup for FreeSlice {
10081021
true
10091022
}
10101023

1024+
fn is_lifetime_end(&self) -> bool {
1025+
false
1026+
}
1027+
10111028
fn trans<'blk, 'tcx>(&self,
10121029
bcx: Block<'blk, 'tcx>,
10131030
debug_loc: Option<NodeInfo>)
@@ -1035,6 +1052,10 @@ impl Cleanup for LifetimeEnd {
10351052
true
10361053
}
10371054

1055+
fn is_lifetime_end(&self) -> bool {
1056+
true
1057+
}
1058+
10381059
fn trans<'blk, 'tcx>(&self,
10391060
bcx: Block<'blk, 'tcx>,
10401061
debug_loc: Option<NodeInfo>)

0 commit comments

Comments
 (0)