Support proxy method in StackVisitor::GetThisObject
Adds function artQuickGetProxyThisObject which returns the 'this'
object of the proxy method using the QuickArgumentVisitor. Since
proxy methods have the same layout than the kRefsAndArgs runtime
method and 'this' is the 1st method argument, it is located in the
first GPR.
Bug: 17965861
(cherry picked from commit a836bc9760419af4a515f96c66100a39e865f3b9)
Change-Id: I09b5c1cdfc051d9395bba929d4650804eb3b1f7f
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index d4f9b49..403313a 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -199,6 +199,22 @@
#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());
@@ -410,6 +426,13 @@
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: