diff options
-rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 23 | ||||
-rw-r--r-- | runtime/stack.cc | 9 |
2 files changed, 32 insertions, 0 deletions
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index cb816298ad..9db1646f5f 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -208,6 +208,22 @@ class QuickArgumentVisitor { #endif public: + // Special handling for proxy methods. Proxy methods are instance methods so the + // 'this' object is the 1st argument. They also have the same frame layout as the + // kRefAndArgs runtime method. Since 'this' is a reference, it is located in the + // 1st GPR. + static mirror::Object* GetProxyThisObject(StackReference<mirror::ArtMethod>* sp) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + CHECK(sp->AsMirrorPtr()->IsProxyMethod()); + CHECK_EQ(kQuickCalleeSaveFrame_RefAndArgs_FrameSize, sp->AsMirrorPtr()->GetFrameSizeInBytes()); + CHECK_GT(kNumQuickGprArgs, 0u); + constexpr uint32_t kThisGprIndex = 0u; // 'this' is in the 1st GPR. + size_t this_arg_offset = kQuickCalleeSaveFrame_RefAndArgs_Gpr1Offset + + GprIndexToGprOffset(kThisGprIndex); + uint8_t* this_arg_address = reinterpret_cast<uint8_t*>(sp) + this_arg_offset; + return reinterpret_cast<StackReference<mirror::Object>*>(this_arg_address)->AsMirrorPtr(); + } + static mirror::ArtMethod* GetCallingMethod(StackReference<mirror::ArtMethod>* sp) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { DCHECK(sp->AsMirrorPtr()->IsCalleeSaveMethod()); @@ -435,6 +451,13 @@ class QuickArgumentVisitor { bool is_split_long_or_double_; }; +// Returns the 'this' object of a proxy method. This function is only used by StackVisitor. It +// allows to use the QuickArgumentVisitor constants without moving all the code in its own module. +extern "C" mirror::Object* artQuickGetProxyThisObject(StackReference<mirror::ArtMethod>* sp) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + return QuickArgumentVisitor::GetProxyThisObject(sp); +} + // Visits arguments on the stack placing them into the shadow frame. class BuildQuickShadowFrameVisitor FINAL : public QuickArgumentVisitor { public: diff --git a/runtime/stack.cc b/runtime/stack.cc index 43714b95e8..aaa5b898b3 100644 --- a/runtime/stack.cc +++ b/runtime/stack.cc @@ -113,6 +113,9 @@ uint32_t StackVisitor::GetDexPc(bool abort_on_failure) const { } } +extern "C" mirror::Object* artQuickGetProxyThisObject(StackReference<mirror::ArtMethod>* sp) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + mirror::Object* StackVisitor::GetThisObject() const { mirror::ArtMethod* m = GetMethod(); if (m->IsStatic()) { @@ -125,6 +128,12 @@ mirror::Object* StackVisitor::GetThisObject() const { } else { return cur_shadow_frame_->GetVRegReference(0); } + } else if (m->IsProxyMethod()) { + if (cur_quick_frame_ != nullptr) { + return artQuickGetProxyThisObject(cur_quick_frame_); + } else { + return cur_shadow_frame_->GetVRegReference(0); + } } else if (m->IsOptimized(sizeof(void*))) { // TODO: Implement, currently only used for exceptions when jdwp is enabled. UNIMPLEMENTED(WARNING) |