diff options
author | 2022-01-19 10:34:57 +0000 | |
---|---|---|
committer | 2022-02-01 14:23:12 +0000 | |
commit | bdf7dc06b54b8571070acb2dd13d70dd4e696a48 (patch) | |
tree | 9aaad569a759cf4c670367d950615ce03d8dcde1 /compiler/optimizing/instruction_builder.cc | |
parent | b81df962c0e1547cb9235e68dbbb0478f604b4bb (diff) |
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
Diffstat (limited to 'compiler/optimizing/instruction_builder.cc')
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 31 |
1 files changed, 7 insertions, 24 deletions
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<mirror::Class> 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<mirror::Class> 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</*access_check=*/true>( + 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<uint32_t>( - 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. |