diff options
| -rw-r--r-- | compiler/driver/compiler_driver.cc | 2 | ||||
| -rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 6 | ||||
| -rw-r--r-- | runtime/object_utils.h | 31 |
3 files changed, 36 insertions, 3 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 402d4f4b18..61e9fbb151 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -1200,7 +1200,7 @@ void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType if (no_guarantee_of_dex_cache_entry) { // See if the method is also declared in this dex cache. uint32_t dex_method_idx = MethodHelper(method).FindDexMethodIndexInOtherDexFile( - *target_method->dex_file); + *target_method->dex_file, target_method->dex_method_index); if (dex_method_idx != DexFile::kDexNoIndex) { target_method->dex_method_index = dex_method_idx; } else { diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index 9f301907e2..f9486c3506 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -561,9 +561,11 @@ extern "C" const void* artQuickResolutionTrampoline(mirror::ArtMethod* called, caller->GetDexCacheResolvedMethods()->Set(called->GetDexMethodIndex(), called); } else { // Calling from one dex file to another, need to compute the method index appropriate to - // the caller's dex file. + // the caller's dex file. Since we get here only if the original called was a runtime + // method, we've got the correct dex_file and a dex_method_idx from above. + DCHECK(&MethodHelper(caller).GetDexFile() == dex_file); uint32_t method_index = - MethodHelper(called).FindDexMethodIndexInOtherDexFile(MethodHelper(caller).GetDexFile()); + MethodHelper(called).FindDexMethodIndexInOtherDexFile(*dex_file, dex_method_idx); if (method_index != DexFile::kDexNoIndex) { caller->GetDexCacheResolvedMethods()->Set(method_index, called); } diff --git a/runtime/object_utils.h b/runtime/object_utils.h index 0451f5d5ed..a981fabf3d 100644 --- a/runtime/object_utils.h +++ b/runtime/object_utils.h @@ -607,6 +607,37 @@ class MethodHelper { return DexFile::kDexNoIndex; } + // The name_and_signature_idx MUST point to a MethodId with the same name and signature in the + // other_dexfile, such as the method index used to resolve this method in the other_dexfile. + uint32_t FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile, + uint32_t name_and_signature_idx) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + const DexFile& dexfile = GetDexFile(); + const DexFile::MethodId& mid = dexfile.GetMethodId(method_->GetDexMethodIndex()); + const DexFile::MethodId& name_and_sig_mid = other_dexfile.GetMethodId(name_and_signature_idx); + DCHECK_STREQ(dexfile.GetMethodName(mid), other_dexfile.GetMethodName(name_and_sig_mid)); + DCHECK_EQ(dexfile.GetMethodSignature(mid), other_dexfile.GetMethodSignature(name_and_sig_mid)); + if (&dexfile == &other_dexfile) { + return method_->GetDexMethodIndex(); + } + const char* mid_declaring_class_descriptor = dexfile.StringByTypeIdx(mid.class_idx_); + const DexFile::StringId* other_descriptor = + other_dexfile.FindStringId(mid_declaring_class_descriptor); + if (other_descriptor != nullptr) { + const DexFile::TypeId* other_type_id = + other_dexfile.FindTypeId(other_dexfile.GetIndexForStringId(*other_descriptor)); + if (other_type_id != nullptr) { + const DexFile::MethodId* other_mid = other_dexfile.FindMethodId( + *other_type_id, other_dexfile.GetStringId(name_and_sig_mid.name_idx_), + other_dexfile.GetProtoId(name_and_sig_mid.proto_idx_)); + if (other_mid != nullptr) { + return other_dexfile.GetIndexForMethodId(*other_mid); + } + } + } + return DexFile::kDexNoIndex; + } + private: // Set the method_ field, for proxy methods looking up the interface method via the resolved // methods table. |