diff options
| -rw-r--r-- | compiler/optimizing/intrinsics.cc | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc index 075ec1ee2e..feaaaf45ec 100644 --- a/compiler/optimizing/intrinsics.cc +++ b/compiler/optimizing/intrinsics.cc @@ -16,12 +16,16 @@ #include "intrinsics.h" +#include "art_method.h" +#include "class_linker.h" #include "dex/quick/dex_file_method_inliner.h" #include "dex/quick/dex_file_to_method_inliner_map.h" #include "driver/compiler_driver.h" #include "invoke_type.h" +#include "mirror/dex_cache-inl.h" #include "nodes.h" #include "quick/inline_method_analyser.h" +#include "scoped_thread_state_change.h" #include "utils.h" namespace art { @@ -364,17 +368,34 @@ void IntrinsicsRecognizer::Run() { if (inst->IsInvoke()) { HInvoke* invoke = inst->AsInvoke(); InlineMethod method; - DexFileMethodInliner* inliner = - driver_->GetMethodInlinerMap()->GetMethodInliner(&invoke->GetDexFile()); + const DexFile& dex_file = invoke->GetDexFile(); + DexFileMethodInliner* inliner = driver_->GetMethodInlinerMap()->GetMethodInliner(&dex_file); DCHECK(inliner != nullptr); if (inliner->IsIntrinsic(invoke->GetDexMethodIndex(), &method)) { Intrinsics intrinsic = GetIntrinsic(method, graph_->GetInstructionSet()); if (intrinsic != Intrinsics::kNone) { if (!CheckInvokeType(intrinsic, invoke)) { - LOG(WARNING) << "Found an intrinsic with unexpected invoke type: " - << intrinsic << " for " - << PrettyMethod(invoke->GetDexMethodIndex(), invoke->GetDexFile()); + // We might be in a situation where we have inlined a method that calls an intrinsic, + // but that method is in a different dex file on which we do not have a + // verified_method that would have helped the compiler driver sharpen the call. + // We can still ensure the invoke types match by checking whether the called method + // is final or is in a final class. + ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); + { + ScopedObjectAccess soa(Thread::Current()); + ArtMethod* art_method = class_linker->FindDexCache(dex_file)->GetResolvedMethod( + invoke->GetDexMethodIndex(), class_linker->GetImagePointerSize()); + DCHECK(art_method != nullptr); + if (art_method->IsFinal() || art_method->GetDeclaringClass()->IsFinal()) { + invoke->SetIntrinsic(intrinsic, NeedsEnvironmentOrCache(intrinsic)); + } else { + LOG(WARNING) << "Found an intrinsic with unexpected invoke type: " + << intrinsic << " for " + << PrettyMethod(invoke->GetDexMethodIndex(), invoke->GetDexFile()) + << invoke->DebugName(); + } + } } else { invoke->SetIntrinsic(intrinsic, NeedsEnvironmentOrCache(intrinsic)); } |