diff options
| author | 2015-09-28 15:13:57 +0000 | |
|---|---|---|
| committer | 2015-09-28 15:13:57 +0000 | |
| commit | cf3f991b0dbad7edd28958aee199f1d06f648984 (patch) | |
| tree | 8b0770087a128acdca7adc5b0d3bd1428e6239bc | |
| parent | 722b5a7580e2d1e7a0327f46615d4c24acba9baa (diff) | |
| parent | b30259251b22430fad12f1adeab671e4bf8f88f5 (diff) | |
Merge "ART: Use unique_ptr for alloca-ed ShadowFrames"
| -rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 6 | ||||
| -rw-r--r-- | runtime/interpreter/interpreter.cc | 6 | ||||
| -rw-r--r-- | runtime/interpreter/interpreter_common.cc | 7 | ||||
| -rw-r--r-- | runtime/stack.h | 40 |
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) |