Visit targets of proxy methods when visiting thread roots.
The target of a non-static proxy method (`this` object), stored in the
proxy method's stack frame, needs to be visited as GC root. This is
especially important in the case of a moving GC, where the proxy
instance may be moved like any object.
Fix initially provided by Robert Vollmer.
Test: m test-art-host
Test: art/test/testrunner/testrunner.py --gcstress -t 1939-proxy-frames
Test: art/test/testrunner/testrunner.py --gcstress -t 1914-get-local-instance
Bug: 70216372
Bug: 67679263
Change-Id: Iea27a8eba51ccd9c9055efaf6b263892830170b5
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index c5157ce..a8c328f 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -319,7 +319,7 @@
// '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(ArtMethod** sp)
+ static StackReference<mirror::Object>* GetProxyThisObjectReference(ArtMethod** sp)
REQUIRES_SHARED(Locks::mutator_lock_) {
CHECK((*sp)->IsProxyMethod());
CHECK_GT(kNumQuickGprArgs, 0u);
@@ -327,7 +327,7 @@
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();
+ return reinterpret_cast<StackReference<mirror::Object>*>(this_arg_address);
}
static ArtMethod* GetCallingMethod(ArtMethod** sp) REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -647,7 +647,11 @@
// allows to use the QuickArgumentVisitor constants without moving all the code in its own module.
extern "C" mirror::Object* artQuickGetProxyThisObject(ArtMethod** sp)
REQUIRES_SHARED(Locks::mutator_lock_) {
- return QuickArgumentVisitor::GetProxyThisObject(sp);
+ return QuickArgumentVisitor::GetProxyThisObjectReference(sp)->AsMirrorPtr();
+}
+extern "C" StackReference<mirror::Object>* artQuickGetProxyThisObjectReference(ArtMethod** sp)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ return QuickArgumentVisitor::GetProxyThisObjectReference(sp);
}
// Visits arguments on the stack placing them into the shadow frame.