about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2018-08-19 17:01:31 +0200
committerRalf Jung <post@ralfj.de>2018-08-22 13:08:39 +0200
commit8ad40479c5eb761d78b4b8b3ba0e411b217fb497 (patch)
treefe813046f096db9740b00cb10f0bdab328dec09b
parentc3d392f5f5d302089bdde41528a12da187558b35 (diff)
downloadrust-8ad40479c5eb761d78b4b8b3ba0e411b217fb497.tar.gz
rust-8ad40479c5eb761d78b4b8b3ba0e411b217fb497.zip
optimize creating a stack frame
-rw-r--r--src/librustc/mir/interpret/value.rs2
-rw-r--r--src/librustc_mir/interpret/eval_context.rs21
2 files changed, 17 insertions, 6 deletions
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index 3cb6839f3c9..b142de81c1e 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc/mir/interpret/value.rs
@@ -178,6 +178,7 @@ impl<'tcx> Scalar {
 }
 
 impl From<Pointer> for Scalar {
+    #[inline(always)]
     fn from(ptr: Pointer) -> Self {
         Scalar::Ptr(ptr)
     }
@@ -210,6 +211,7 @@ pub enum ScalarMaybeUndef {
 }
 
 impl From<Scalar> for ScalarMaybeUndef {
+    #[inline(always)]
     fn from(s: Scalar) -> Self {
         ScalarMaybeUndef::Scalar(s)
     }
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index d42fc8746c4..33420b6150b 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -288,6 +288,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for &'a EvalContext<'a, 'm
     type Ty = Ty<'tcx>;
     type TyLayout = EvalResult<'tcx, TyLayout<'tcx>>;
 
+    #[inline]
     fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
         self.tcx.layout_of(self.param_env.and(ty))
             .map_err(|layout| EvalErrorKind::Layout(layout).into())
@@ -559,7 +560,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
             // value we use for things that we know are initially dead.
             let dummy =
                 LocalValue::Live(Operand::Immediate(Value::Scalar(ScalarMaybeUndef::Undef)));
-            self.frame_mut().locals = IndexVec::from_elem(dummy, &mir.local_decls);
+            let mut locals = IndexVec::from_elem(dummy, &mir.local_decls);
             // Now mark those locals as dead that we do not want to initialize
             match self.tcx.describe_def(instance.def_id()) {
                 // statics and constants don't have `Storage*` statements, no need to look for them
@@ -572,8 +573,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
                             match stmt.kind {
                                 StorageLive(local) |
                                 StorageDead(local) => {
-                                    // Worst case we are overwriting a dummy, no deallocation needed
-                                    self.storage_dead(local);
+                                    locals[local] = LocalValue::Dead;
                                 }
                                 _ => {}
                             }
@@ -582,11 +582,20 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
                 },
             }
             // Finally, properly initialize all those that still have the dummy value
-            for local in mir.local_decls.indices() {
-                if self.frame().locals[local] == dummy {
-                    self.storage_live(local)?;
+            for (local, decl) in locals.iter_mut().zip(mir.local_decls.iter()) {
+                match *local {
+                    LocalValue::Live(_) => {
+                        // This needs to be peoperly initialized.
+                        let layout = self.layout_of(self.monomorphize(decl.ty, instance.substs))?;
+                        *local = LocalValue::Live(self.uninit_operand(layout)?);
+                    }
+                    LocalValue::Dead => {
+                        // Nothing to do
+                    }
                 }
             }
+            // done
+            self.frame_mut().locals = locals;
         }
 
         if self.stack.len() > self.stack_limit {