ART: Fix MethodHandle invoke-super
Adds test for MethodHandles.unreflectSpecial() and fixes the
associated method refinement in the method handle dispatch.
Bug: 77729852
Test: art/test/run-test --host --64 956
(cherry picked from commit d7959c2abe72629581f7465500b95a3d4e57e7ca)
Change-Id: Idf022997a3d34b75428cac0bc539f6ea4bb1bc94
Merged-In: I6c364a5a6edaa9e9d04ae96683d5bb3e6adbcb6e
diff --git a/runtime/method_handles.cc b/runtime/method_handles.cc
index 82370c4..64ab789 100644
--- a/runtime/method_handles.cc
+++ b/runtime/method_handles.cc
@@ -674,13 +674,15 @@
return WellKnownClasses::StringInitToStringFactory(target_method);
}
} else if (handle_kind == mirror::MethodHandle::Kind::kInvokeSuper) {
- ObjPtr<mirror::Class> declaring_class = target_method->GetDeclaringClass();
-
// Note that we're not dynamically dispatching on the type of the receiver
// here. We use the static type of the "receiver" object that we've
// recorded in the method handle's type, which will be the same as the
// special caller that was specified at the point of lookup.
ObjPtr<mirror::Class> referrer_class = handle_type->GetPTypes()->Get(0);
+ ObjPtr<mirror::Class> declaring_class = target_method->GetDeclaringClass();
+ if (referrer_class == declaring_class) {
+ return target_method;
+ }
if (!declaring_class->IsInterface()) {
ObjPtr<mirror::Class> super_class = referrer_class->GetSuperClass();
uint16_t vtable_index = target_method->GetMethodIndex();
@@ -690,8 +692,6 @@
// will always be declared by super_class (or one of its super classes).
DCHECK_LT(vtable_index, super_class->GetVTableLength());
return super_class->GetVTableEntry(vtable_index, kRuntimePointerSize);
- } else {
- return referrer_class->FindVirtualMethodForInterfaceSuper(target_method, kRuntimePointerSize);
}
}
return target_method;