Allocate shadow frames in interpreter on stack instead of on heap.

Instead of using new, the shadow frames are allocated using alloca.

Change-Id: Idc92fbccf1fe7589ace7b97811b21a5c67c97fd2
diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc
index a3768c7..e0bb708 100644
--- a/src/interpreter/interpreter.cc
+++ b/src/interpreter/interpreter.cc
@@ -425,9 +425,9 @@
     }
   }
 
-  Runtime* runtime = Runtime::Current();
-  UniquePtr<ShadowFrame> new_shadow_frame(ShadowFrame::Create(num_regs, &shadow_frame,
-                                                              target_method, 0));
+  void* memory = alloca(ShadowFrame::ComputeSize(num_regs));
+  ShadowFrame* new_shadow_frame(ShadowFrame::Create(num_regs, &shadow_frame,
+                                                    target_method, 0, memory));
   size_t cur_reg = num_regs - num_ins;
   if (receiver != NULL) {
     new_shadow_frame->SetVRegReference(cur_reg, receiver);
@@ -463,10 +463,10 @@
     }
   }
 
-  if (LIKELY(runtime->IsStarted())) {
-    result->SetJ((target_method->GetEntryPointFromInterpreter())(self, new_shadow_frame.get()).GetJ());
+  if (LIKELY(Runtime::Current()->IsStarted())) {
+    result->SetJ((target_method->GetEntryPointFromInterpreter())(self, new_shadow_frame).GetJ());
   } else {
-    UnstartedRuntimeInvoke(self, target_method, new_shadow_frame.get(), result, num_regs - num_ins);
+    UnstartedRuntimeInvoke(self, target_method, new_shadow_frame, result, num_regs - num_ins);
   }
   mh.ChangeMethod(shadow_frame.GetMethod());
 }
@@ -2135,10 +2135,9 @@
   }
   // Set up shadow frame with matching number of reference slots to vregs.
   ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame();
-  UniquePtr<ShadowFrame> shadow_frame(ShadowFrame::Create(num_regs,
-                                                          last_shadow_frame,
-                                                          method, 0));
-  self->PushShadowFrame(shadow_frame.get());
+  void* memory = alloca(ShadowFrame::ComputeSize(num_regs));
+  ShadowFrame* shadow_frame(ShadowFrame::Create(num_regs, last_shadow_frame, method, 0, memory));
+  self->PushShadowFrame(shadow_frame);
   size_t cur_reg = num_regs - num_ins;
   if (!method->IsStatic()) {
     CHECK(receiver != NULL);
@@ -2176,7 +2175,7 @@
     }
   }
   if (LIKELY(!method->IsNative())) {
-    JValue r = Execute(self, mh, code_item, *shadow_frame.get(), JValue());
+    JValue r = Execute(self, mh, code_item, *shadow_frame, JValue());
     if (result != NULL) {
       *result = r;
     }
diff --git a/src/oat/runtime/support_interpreter.cc b/src/oat/runtime/support_interpreter.cc
index 6a65cea..4f8cf61 100644
--- a/src/oat/runtime/support_interpreter.cc
+++ b/src/oat/runtime/support_interpreter.cc
@@ -81,16 +81,17 @@
 
   MethodHelper mh(method);
   const DexFile::CodeItem* code_item = mh.GetCodeItem();
-  UniquePtr<ShadowFrame> shadow_frame(ShadowFrame::Create(code_item->registers_size_,
-                                                          NULL, // No last shadow coming from quick.
-                                                          method, 0));
+  uint16_t num_regs = code_item->registers_size_;
+  void* memory = alloca(ShadowFrame::ComputeSize(num_regs));
+  ShadowFrame* shadow_frame(ShadowFrame::Create(num_regs, NULL, // No last shadow coming from quick.
+                                                method, 0, memory));
   size_t first_arg_reg = code_item->registers_size_ - code_item->ins_size_;
-  BuildShadowFrameVisitor shadow_frame_builder(mh, sp, *shadow_frame.get(), first_arg_reg);
+  BuildShadowFrameVisitor shadow_frame_builder(mh, sp, *shadow_frame, first_arg_reg);
   shadow_frame_builder.VisitArguments();
   // Push a transition back into managed code onto the linked list in thread.
   ManagedStack fragment;
   self->PushManagedStackFragment(&fragment);
-  self->PushShadowFrame(shadow_frame.get());
+  self->PushShadowFrame(shadow_frame);
   self->EndAssertNoThreadSuspension(old_cause);
 
   if (method->IsStatic() && !method->GetDeclaringClass()->IsInitializing()) {
@@ -103,7 +104,7 @@
     }
   }
 
-  JValue result = interpreter::EnterInterpreterFromStub(self, mh, code_item, *shadow_frame.get());
+  JValue result = interpreter::EnterInterpreterFromStub(self, mh, code_item, *shadow_frame);
   // Pop transition.
   self->PopManagedStackFragment(fragment);
   return result.GetJ();
diff --git a/src/stack.h b/src/stack.h
index d6ff9c6..1b4d285 100644
--- a/src/stack.h
+++ b/src/stack.h
@@ -58,13 +58,23 @@
 //  - JNI - just VRegs, but where every VReg holds a reference.
 class ShadowFrame {
  public:
-  // Create ShadowFrame for interpreter.
+  // Compute size of ShadowFrame in bytes.
+  static size_t ComputeSize(uint32_t num_vregs) {
+    return sizeof(ShadowFrame) + (sizeof(uint32_t) * num_vregs) +
+           (sizeof(mirror::Object*) * num_vregs);
+  }
+
+  // Create ShadowFrame in heap for deoptimization.
   static ShadowFrame* Create(uint32_t num_vregs, ShadowFrame* link,
                              mirror::AbstractMethod* method, uint32_t dex_pc) {
-    size_t sz = sizeof(ShadowFrame) +
-                (sizeof(uint32_t) * num_vregs) +
-                (sizeof(mirror::Object*) * num_vregs);
-    uint8_t* memory = new uint8_t[sz];
+    uint8_t* memory = new uint8_t[ComputeSize(num_vregs)];
+    ShadowFrame* sf = new (memory) ShadowFrame(num_vregs, link, method, dex_pc, true);
+    return sf;
+  }
+
+  // Create ShadowFrame for interpreter using provided memory.
+  static ShadowFrame* Create(uint32_t num_vregs, ShadowFrame* link,
+                             mirror::AbstractMethod* method, uint32_t dex_pc, void* memory) {
     ShadowFrame* sf = new (memory) ShadowFrame(num_vregs, link, method, dex_pc, true);
     return sf;
   }