summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Andreas Gampe <agampe@google.com> 2015-09-28 15:13:57 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2015-09-28 15:13:57 +0000
commitcf3f991b0dbad7edd28958aee199f1d06f648984 (patch)
tree8b0770087a128acdca7adc5b0d3bd1428e6239bc
parent722b5a7580e2d1e7a0327f46615d4c24acba9baa (diff)
parentb30259251b22430fad12f1adeab671e4bf8f88f5 (diff)
Merge "ART: Use unique_ptr for alloca-ed ShadowFrames"
-rw-r--r--runtime/entrypoints/quick/quick_trampoline_entrypoints.cc6
-rw-r--r--runtime/interpreter/interpreter.cc6
-rw-r--r--runtime/interpreter/interpreter_common.cc7
-rw-r--r--runtime/stack.h40
4 files changed, 45 insertions, 14 deletions
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 1302c5f17b..b567303b55 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -31,6 +31,7 @@
#include "mirror/object_array-inl.h"
#include "runtime.h"
#include "scoped_thread_state_change.h"
+#include "stack.h"
#include "debugger.h"
namespace art {
@@ -653,9 +654,10 @@ extern "C" uint64_t artQuickToInterpreterBridge(ArtMethod* method, Thread* self,
const DexFile::CodeItem* code_item = method->GetCodeItem();
DCHECK(code_item != nullptr) << PrettyMethod(method);
uint16_t num_regs = code_item->registers_size_;
- void* memory = alloca(ShadowFrame::ComputeSize(num_regs));
// No last shadow coming from quick.
- ShadowFrame* shadow_frame(ShadowFrame::Create(num_regs, nullptr, method, 0, memory));
+ ShadowFrameAllocaUniquePtr shadow_frame_unique_ptr =
+ CREATE_SHADOW_FRAME(num_regs, nullptr, method, 0);
+ ShadowFrame* shadow_frame = shadow_frame_unique_ptr.get();
size_t first_arg_reg = code_item->registers_size_ - code_item->ins_size_;
uint32_t shorty_len = 0;
auto* non_proxy_method = method->GetInterfaceMethodIfProxy(sizeof(void*));
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index 3ac80c6642..f783b04b95 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -21,6 +21,7 @@
#include "mirror/string-inl.h"
#include "scoped_thread_state_change.h"
#include "ScopedLocalRef.h"
+#include "stack.h"
#include "unstarted_runtime.h"
namespace art {
@@ -330,8 +331,9 @@ void EnterInterpreterFromInvoke(Thread* self, ArtMethod* method, Object* receive
}
// Set up shadow frame with matching number of reference slots to vregs.
ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame();
- void* memory = alloca(ShadowFrame::ComputeSize(num_regs));
- ShadowFrame* shadow_frame(ShadowFrame::Create(num_regs, last_shadow_frame, method, 0, memory));
+ ShadowFrameAllocaUniquePtr shadow_frame_unique_ptr =
+ CREATE_SHADOW_FRAME(num_regs, last_shadow_frame, method, 0);
+ ShadowFrame* shadow_frame = shadow_frame_unique_ptr.get();
self->PushShadowFrame(shadow_frame);
size_t cur_reg = num_regs - num_ins;
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 2de12dcec2..ad34c9ad9e 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -21,6 +21,7 @@
#include "debugger.h"
#include "entrypoints/runtime_asm_entrypoints.h"
#include "mirror/array-inl.h"
+#include "stack.h"
#include "unstarted_runtime.h"
#include "verifier/method_verifier.h"
@@ -584,9 +585,9 @@ static inline bool DoCallCommon(ArtMethod* called_method,
// Allocate shadow frame on the stack.
const char* old_cause = self->StartAssertNoThreadSuspension("DoCallCommon");
- void* memory = alloca(ShadowFrame::ComputeSize(num_regs));
- ShadowFrame* new_shadow_frame(ShadowFrame::Create(num_regs, &shadow_frame, called_method, 0,
- memory));
+ ShadowFrameAllocaUniquePtr shadow_frame_unique_ptr =
+ CREATE_SHADOW_FRAME(num_regs, &shadow_frame, called_method, 0);
+ ShadowFrame* new_shadow_frame = shadow_frame_unique_ptr.get();
// Initialize new shadow frame by copying the registers from the callee shadow frame.
if (do_assignability_check) {
diff --git a/runtime/stack.h b/runtime/stack.h
index b805239836..292c745090 100644
--- a/runtime/stack.h
+++ b/runtime/stack.h
@@ -62,6 +62,10 @@ template<class MirrorType>
class MANAGED StackReference : public mirror::CompressedReference<MirrorType> {
};
+// Forward declaration. Just calls the destructor.
+struct ShadowFrameDeleter;
+using ShadowFrameAllocaUniquePtr = std::unique_ptr<ShadowFrame, ShadowFrameDeleter>;
+
// ShadowFrame has 2 possible layouts:
// - interpreter - separate VRegs and reference arrays. References are in the reference array.
// - JNI - just VRegs, but where every VReg holds a reference.
@@ -77,21 +81,26 @@ class ShadowFrame {
static ShadowFrame* CreateDeoptimizedFrame(uint32_t num_vregs, ShadowFrame* link,
ArtMethod* method, uint32_t dex_pc) {
uint8_t* memory = new uint8_t[ComputeSize(num_vregs)];
- return Create(num_vregs, link, method, dex_pc, memory);
+ return CreateShadowFrameImpl(num_vregs, link, method, dex_pc, memory);
}
// Delete a ShadowFrame allocated on the heap for deoptimization.
static void DeleteDeoptimizedFrame(ShadowFrame* sf) {
+ sf->~ShadowFrame(); // Explicitly destruct.
uint8_t* memory = reinterpret_cast<uint8_t*>(sf);
delete[] memory;
}
- // Create ShadowFrame for interpreter using provided memory.
- static ShadowFrame* Create(uint32_t num_vregs, ShadowFrame* link,
- ArtMethod* method, uint32_t dex_pc, void* memory) {
- ShadowFrame* sf = new (memory) ShadowFrame(num_vregs, link, method, dex_pc, true);
- return sf;
- }
+ // Create a shadow frame in a fresh alloca. This needs to be in the context of the caller.
+ // Inlining doesn't work, the compiler will still undo the alloca. So this needs to be a macro.
+#define CREATE_SHADOW_FRAME(num_vregs, link, method, dex_pc) ({ \
+ size_t frame_size = ShadowFrame::ComputeSize(num_vregs); \
+ void* alloca_mem = alloca(frame_size); \
+ ShadowFrameAllocaUniquePtr( \
+ ShadowFrame::CreateShadowFrameImpl((num_vregs), (link), (method), (dex_pc), \
+ (alloca_mem))); \
+ })
+
~ShadowFrame() {}
// TODO(iam): Clean references array up since they're always there,
@@ -283,6 +292,15 @@ class ShadowFrame {
return OFFSETOF_MEMBER(ShadowFrame, vregs_);
}
+ // Create ShadowFrame for interpreter using provided memory.
+ static ShadowFrame* CreateShadowFrameImpl(uint32_t num_vregs,
+ ShadowFrame* link,
+ ArtMethod* method,
+ uint32_t dex_pc,
+ void* memory) {
+ return new (memory) ShadowFrame(num_vregs, link, method, dex_pc, true);
+ }
+
private:
ShadowFrame(uint32_t num_vregs, ShadowFrame* link, ArtMethod* method,
uint32_t dex_pc, bool has_reference_array)
@@ -326,6 +344,14 @@ class ShadowFrame {
DISALLOW_IMPLICIT_CONSTRUCTORS(ShadowFrame);
};
+struct ShadowFrameDeleter {
+ inline void operator()(ShadowFrame* frame) {
+ if (frame != nullptr) {
+ frame->~ShadowFrame();
+ }
+ }
+};
+
class JavaFrameRootInfo : public RootInfo {
public:
JavaFrameRootInfo(uint32_t thread_id, const StackVisitor* stack_visitor, size_t vreg)