From bdf7dc06b54b8571070acb2dd13d70dd4e696a48 Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Wed, 19 Jan 2022 10:34:57 +0000 Subject: 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 --- compiler/optimizing/instruction_builder.cc | 31 +++++++----------------------- 1 file changed, 7 insertions(+), 24 deletions(-) (limited to 'compiler/optimizing/instruction_builder.cc') diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index f8bf126eeb..aabc433448 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -28,6 +28,7 @@ #include "dex/dex_instruction-inl.h" #include "driver/dex_compilation_unit.h" #include "driver/compiler_options.h" +#include "entrypoints/entrypoint_utils-inl.h" #include "imtable-inl.h" #include "intrinsics.h" #include "intrinsics_utils.h" @@ -932,36 +933,18 @@ static ArtMethod* ResolveMethod(uint16_t method_idx, // make this an invoke-unresolved to handle cross-dex invokes or abstract super methods, both of // which require runtime handling. if (*invoke_type == kSuper) { - ObjPtr compiling_class = dex_compilation_unit.GetCompilingClass().Get(); - if (compiling_class == nullptr) { + if (referrer == nullptr) { // We could not determine the method's class we need to wait until runtime. DCHECK(Runtime::Current()->IsAotCompiler()); return nullptr; } - ObjPtr referenced_class = class_linker->LookupResolvedType( - dex_compilation_unit.GetDexFile()->GetMethodId(method_idx).class_idx_, - dex_compilation_unit.GetDexCache().Get(), - class_loader.Get()); - DCHECK(referenced_class != nullptr); // We have already resolved a method from this class. - if (!referenced_class->IsAssignableFrom(compiling_class)) { - // We cannot statically determine the target method. The runtime will throw a - // NoSuchMethodError on this one. + ArtMethod* actual_method = FindSuperMethodToCall( + method_idx, resolved_method, referrer, soa.Self()); + if (actual_method == nullptr) { + // Clean up any exception left by method resolution. + soa.Self()->ClearException(); return nullptr; } - ArtMethod* actual_method; - if (referenced_class->IsInterface()) { - actual_method = referenced_class->FindVirtualMethodForInterfaceSuper( - resolved_method, class_linker->GetImagePointerSize()); - } else { - uint16_t vtable_index = resolved_method->GetMethodIndex(); - if (vtable_index >= static_cast( - compiling_class->GetSuperClass()->GetVTableLength())) { - // No super method. The runtime will throw a NoSuchMethodError. - return nullptr; - } - actual_method = compiling_class->GetSuperClass()->GetVTableEntry( - vtable_index, class_linker->GetImagePointerSize()); - } if (!actual_method->IsInvokable()) { // Fail if the actual method cannot be invoked. Otherwise, the runtime resolution stub // could resolve the callee to the wrong method. -- cgit v1.2.3-59-g8ed1b