diff options
Diffstat (limited to 'compiler/optimizing/intrinsics.cc')
| -rw-r--r-- | compiler/optimizing/intrinsics.cc | 59 |
1 files changed, 41 insertions, 18 deletions
diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc index dfae534555..9bf10f58fd 100644 --- a/compiler/optimizing/intrinsics.cc +++ b/compiler/optimizing/intrinsics.cc @@ -139,9 +139,41 @@ static bool CheckInvokeType(Intrinsics intrinsic, HInvoke* invoke) { // Call might be devirtualized. return (invoke_type == kVirtual || invoke_type == kDirect); - default: + case kSuper: + case kInterface: + case kPolymorphic: return false; } + LOG(FATAL) << "Unknown intrinsic invoke type: " << intrinsic_type; + UNREACHABLE(); +} + +bool IntrinsicsRecognizer::Recognize(HInvoke* invoke, /*out*/ bool* wrong_invoke_type) { + ArtMethod* art_method = invoke->GetResolvedMethod(); + *wrong_invoke_type = false; + if (art_method == nullptr || !art_method->IsIntrinsic()) { + return false; + } + + { + // TODO: b/65872996 Polymorphic signature methods should be compiler intrinsics. + ScopedObjectAccess soa(Thread::Current()); + if (art_method->IsPolymorphicSignature()) { + return false; + } + } + + Intrinsics intrinsic = static_cast<Intrinsics>(art_method->GetIntrinsic()); + if (CheckInvokeType(intrinsic, invoke) == false) { + *wrong_invoke_type = true; + return false; + } + + invoke->SetIntrinsic(intrinsic, + NeedsEnvironmentOrCache(intrinsic), + GetSideEffects(intrinsic), + GetExceptions(intrinsic)); + return true; } void IntrinsicsRecognizer::Run() { @@ -151,23 +183,14 @@ void IntrinsicsRecognizer::Run() { inst_it.Advance()) { HInstruction* inst = inst_it.Current(); if (inst->IsInvoke()) { - HInvoke* invoke = inst->AsInvoke(); - ArtMethod* art_method = invoke->GetResolvedMethod(); - if (art_method != nullptr && art_method->IsIntrinsic()) { - Intrinsics intrinsic = static_cast<Intrinsics>(art_method->GetIntrinsic()); - if (!CheckInvokeType(intrinsic, invoke)) { - LOG(WARNING) << "Found an intrinsic with unexpected invoke type: " - << static_cast<uint32_t>(intrinsic) << " for " - << art_method->PrettyMethod() - << invoke->DebugName(); - } else { - invoke->SetIntrinsic(intrinsic, - NeedsEnvironmentOrCache(intrinsic), - GetSideEffects(intrinsic), - GetExceptions(intrinsic)); - MaybeRecordStat(stats_, - MethodCompilationStat::kIntrinsicRecognized); - } + bool wrong_invoke_type = false; + if (Recognize(inst->AsInvoke(), &wrong_invoke_type)) { + MaybeRecordStat(stats_, MethodCompilationStat::kIntrinsicRecognized); + } else if (wrong_invoke_type) { + LOG(WARNING) + << "Found an intrinsic with unexpected invoke type: " + << inst->AsInvoke()->GetResolvedMethod()->PrettyMethod() << " " + << inst->DebugName(); } } } |