Introduce FindSuperMethodToCall to find the target of a super call.
And use it across compiler/runtime/nterp. This also fixes an issue in
nterp when handling an obsolete method.
Also move FindMethodFast and FindFieldFast next to their only use.
Test: test.py
Bug: 214328881
Change-Id: If64849575ae342324e30026e29d285eca6e61263
diff --git a/runtime/interpreter/mterp/nterp.cc b/runtime/interpreter/mterp/nterp.cc
index 7719b5f..34c971c 100644
--- a/runtime/interpreter/mterp/nterp.cc
+++ b/runtime/interpreter/mterp/nterp.cc
@@ -330,43 +330,14 @@
return 0;
}
- // ResolveMethod returns the method based on the method_id. For super invokes
- // we must use the executing class's context to find the right method.
if (invoke_type == kSuper) {
- ObjPtr<mirror::Class> executing_class = caller->GetDeclaringClass();
- ObjPtr<mirror::Class> referenced_class = class_linker->LookupResolvedType(
- executing_class->GetDexFile().GetMethodId(method_index).class_idx_,
- executing_class->GetDexCache(),
- executing_class->GetClassLoader());
- DCHECK(referenced_class != nullptr); // We have already resolved a method from this class.
- if (!referenced_class->IsAssignableFrom(executing_class)) {
- // We cannot determine the target method.
- ThrowNoSuchMethodError(invoke_type,
- resolved_method->GetDeclaringClass(),
- resolved_method->GetName(),
- resolved_method->GetSignature());
+ resolved_method = caller->SkipAccessChecks()
+ ? FindSuperMethodToCall</*access_check=*/false>(method_index, resolved_method, caller, self)
+ : FindSuperMethodToCall</*access_check=*/true>(method_index, resolved_method, caller, self);
+ if (resolved_method == nullptr) {
+ DCHECK(self->IsExceptionPending());
return 0;
}
- if (referenced_class->IsInterface()) {
- resolved_method = referenced_class->FindVirtualMethodForInterfaceSuper(
- resolved_method, class_linker->GetImagePointerSize());
- } else {
- uint16_t vtable_index = resolved_method->GetMethodIndex();
- ObjPtr<mirror::Class> super_class = executing_class->GetSuperClass();
- if (super_class == nullptr ||
- !super_class->HasVTable() ||
- vtable_index >= static_cast<uint32_t>(super_class->GetVTableLength())) {
- // Behavior to agree with that of the verifier.
- ThrowNoSuchMethodError(invoke_type,
- resolved_method->GetDeclaringClass(),
- resolved_method->GetName(),
- resolved_method->GetSignature());
- return 0;
- } else {
- resolved_method = executing_class->GetSuperClass()->GetVTableEntry(
- vtable_index, class_linker->GetImagePointerSize());
- }
- }
}
if (invoke_type == kInterface) {