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;
}