summaryrefslogtreecommitdiffstats
path: root/compiler/dex/mir_method_info.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/dex/mir_method_info.cc')
-rw-r--r--compiler/dex/mir_method_info.cc19
1 files changed, 13 insertions, 6 deletions
diff --git a/compiler/dex/mir_method_info.cc b/compiler/dex/mir_method_info.cc
index 3d3d979..34fb1bf 100644
--- a/compiler/dex/mir_method_info.cc
+++ b/compiler/dex/mir_method_info.cc
@@ -58,8 +58,9 @@ void MirMethodLoweringInfo::Resolve(CompilerDriver* compiler_driver,
auto current_dex_cache(hs.NewHandle<mirror::DexCache>(nullptr));
// Even if the referrer class is unresolved (i.e. we're compiling a method without class
// definition) we still want to resolve methods and record all available info.
+ Runtime* const runtime = Runtime::Current();
const DexFile* const dex_file = mUnit->GetDexFile();
- const bool use_jit = Runtime::Current()->UseJit();
+ const bool use_jit = runtime->UseJit();
const VerifiedMethod* const verified_method = mUnit->GetVerifiedMethod();
for (auto it = method_infos, end = method_infos + count; it != end; ++it) {
@@ -80,7 +81,7 @@ void MirMethodLoweringInfo::Resolve(CompilerDriver* compiler_driver,
it->target_method_idx_ = it->MethodIndex();
current_dex_cache.Assign(dex_cache.Get());
resolved_method = compiler_driver->ResolveMethod(soa, dex_cache, class_loader, mUnit,
- it->MethodIndex(), invoke_type);
+ it->target_method_idx_, invoke_type, true);
} else {
// The method index is actually the dex PC in this case.
// Calculate the proper dex file and target method idx.
@@ -89,8 +90,7 @@ void MirMethodLoweringInfo::Resolve(CompilerDriver* compiler_driver,
// Don't devirt if we are in a different dex file since we can't have direct invokes in
// another dex file unless we always put a direct / patch pointer.
devirt_target = nullptr;
- current_dex_cache.Assign(
- Runtime::Current()->GetClassLinker()->FindDexCache(*it->target_dex_file_));
+ current_dex_cache.Assign(runtime->GetClassLinker()->FindDexCache(*it->target_dex_file_));
CHECK(current_dex_cache.Get() != nullptr);
DexCompilationUnit cu(
mUnit->GetCompilationUnit(), mUnit->GetClassLoader(), mUnit->GetClassLinker(),
@@ -99,6 +99,14 @@ void MirMethodLoweringInfo::Resolve(CompilerDriver* compiler_driver,
nullptr /* verified_method not used */);
resolved_method = compiler_driver->ResolveMethod(soa, current_dex_cache, class_loader, &cu,
it->target_method_idx_, invoke_type, false);
+ if (resolved_method == nullptr) {
+ // If the method is null then it should be a miranda method, in this case try
+ // re-loading it, this time as an interface method. The actual miranda method is in the
+ // vtable, but it will resolve to an interface method.
+ resolved_method = compiler_driver->ResolveMethod(
+ soa, current_dex_cache, class_loader, &cu, it->target_method_idx_, kInterface, false);
+ CHECK(resolved_method != nullptr);
+ }
if (resolved_method != nullptr) {
// Since this was a dequickened virtual, it is guaranteed to be resolved. However, it may be
// resolved to an interface method. If this is the case then change the invoke type to
@@ -123,10 +131,9 @@ void MirMethodLoweringInfo::Resolve(CompilerDriver* compiler_driver,
it->vtable_idx_ =
compiler_driver->GetResolvedMethodVTableIndex(resolved_method, invoke_type);
}
-
MethodReference target_method(it->target_dex_file_, it->target_method_idx_);
int fast_path_flags = compiler_driver->IsFastInvoke(
- soa, dex_cache, class_loader, mUnit, referrer_class.Get(), resolved_method,
+ soa, current_dex_cache, class_loader, mUnit, referrer_class.Get(), resolved_method,
&invoke_type, &target_method, devirt_target, &it->direct_code_, &it->direct_method_);
const bool is_referrers_class = referrer_class.Get() == resolved_method->GetDeclaringClass();
const bool is_class_initialized =