diff options
Diffstat (limited to 'compiler/optimizing/profiling_info_builder.cc')
-rw-r--r-- | compiler/optimizing/profiling_info_builder.cc | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/compiler/optimizing/profiling_info_builder.cc b/compiler/optimizing/profiling_info_builder.cc new file mode 100644 index 0000000000..7e8cdb1454 --- /dev/null +++ b/compiler/optimizing/profiling_info_builder.cc @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "profiling_info_builder.h" + +#include "art_method-inl.h" +#include "driver/compiler_options.h" +#include "dex/code_item_accessors-inl.h" +#include "jit/profiling_info.h" +#include "optimizing_compiler_stats.h" +#include "scoped_thread_state_change-inl.h" + +namespace art HIDDEN { + +void ProfilingInfoBuilder::Run() { + DCHECK_EQ(GetGraph()->GetProfilingInfo(), nullptr); + // Order does not matter. + for (HBasicBlock* block : GetGraph()->GetReversePostOrder()) { + // No need to visit the phis. + for (HInstructionIteratorHandleChanges inst_it(block->GetInstructions()); !inst_it.Done(); + inst_it.Advance()) { + inst_it.Current()->Accept(this); + } + } + + ScopedObjectAccess soa(Thread::Current()); + GetGraph()->SetProfilingInfo( + ProfilingInfo::Create(soa.Self(), GetGraph()->GetArtMethod(), inline_caches_)); +} + +void ProfilingInfoBuilder::HandleInvoke(HInvoke* invoke) { + DCHECK(!invoke->GetEnvironment()->IsFromInlinedInvoke()); + if (IsInlineCacheUseful(invoke)) { + inline_caches_.push_back(invoke->GetDexPc()); + } +} + +void ProfilingInfoBuilder::VisitInvokeInterface(HInvokeInterface* invoke) { + HandleInvoke(invoke); +} + +void ProfilingInfoBuilder::VisitInvokeVirtual(HInvokeVirtual* invoke) { + HandleInvoke(invoke); +} + +bool ProfilingInfoBuilder::IsInlineCacheUseful(HInvoke* invoke) { + DCHECK(invoke->IsInvokeVirtual() || invoke->IsInvokeInterface()); + if (invoke->IsIntrinsic()) { + return false; + } + if (!invoke->GetBlock()->GetGraph()->IsCompilingBaseline()) { + return false; + } + if (Runtime::Current()->IsAotCompiler()) { + return false; + } + if (invoke->InputAt(0)->GetReferenceTypeInfo().IsExact()) { + return false; + } + if (invoke->GetResolvedMethod() != nullptr) { + ScopedObjectAccess soa(Thread::Current()); + if (invoke->GetResolvedMethod()->IsFinal() || + invoke->GetResolvedMethod()->GetDeclaringClass()->IsFinal()) { + return false; + } + } + return true; +} + +InlineCache* ProfilingInfoBuilder::GetInlineCache(ProfilingInfo* info, HInvoke* instruction) { + DCHECK(!instruction->GetEnvironment()->IsFromInlinedInvoke()); + ScopedObjectAccess soa(Thread::Current()); + return info->GetInlineCache(instruction->GetDexPc()); +} + +} // namespace art |