class ArtMethod; class CodeGenerator; class CodeItemDataAccessor; class DexCompilationUnit; template <class T> class Handle; class HBasicBlock; class HEnvironment; class HGraph; class HInstanceFieldGet; class HInstanceFieldSet; class HInstruction; class HInvoke; class OptimizingCompilerStats; class ReferenceTypeInfo; template <size_t kNumReferences> class StackHandleScope;
// Try to inline `resolved_method` in place of `invoke_instruction`. `do_rtp` is whether // reference type propagation can run after the inlining. If the inlining is successful, this // method will replace and remove the `invoke_instruction`. bool TryInlineAndReplace(HInvoke* invoke_instruction,
ArtMethod* resolved_method,
ReferenceTypeInfo receiver_type, bool do_rtp, bool is_speculative)
REQUIRES_SHARED(Locks::mutator_lock_);
// Substitutes parameters in the callee graph with their values from the caller. void SubstituteArguments(HGraph* callee_graph,
HInvoke* invoke_instruction,
ReferenceTypeInfo receiver_type, const DexCompilationUnit& dex_compilation_unit)
REQUIRES_SHARED(Locks::mutator_lock_);
// Run simple optimizations on `callee_graph`. void RunOptimizations(HGraph* callee_graph,
HEnvironment* caller_environment, const dex::CodeItem* code_item, const DexCompilationUnit& dex_compilation_unit, bool try_catch_inlining_allowed_for_recursive_inline)
REQUIRES_SHARED(Locks::mutator_lock_);
// Try to recognize known simple patterns and replace invoke call with appropriate instructions. bool TryPatternSubstitution(HInvoke* invoke_instruction,
ArtMethod* method, const CodeItemDataAccessor& accessor,
HInstruction** return_replacement)
REQUIRES_SHARED(Locks::mutator_lock_);
// Returns whether inlining is allowed based on ART semantics. bool IsInliningAllowed(art::ArtMethod* method, const CodeItemDataAccessor& accessor) const
REQUIRES_SHARED(Locks::mutator_lock_);
// Returns whether ART supports inlining this method. // // Some methods are not supported because they have features for which inlining // is not implemented. For example, we do not currently support inlining throw // instructions into a try block. bool IsInliningSupported(const HInvoke* invoke_instruction,
art::ArtMethod* method, const CodeItemDataAccessor& accessor) const
REQUIRES_SHARED(Locks::mutator_lock_);
// Returns whether inlining is encouraged. // // For example, this checks whether the function has grown too large and // inlining should be prevented. bool IsInliningEncouraged(const HInvoke* invoke_instruction,
art::ArtMethod* method, const CodeItemDataAccessor& accessor) const
REQUIRES_SHARED(Locks::mutator_lock_);
// Inspects the body of a method (callee_graph) and returns whether it can be // inlined. // // This checks for instructions and constructs that we do not support // inlining, such as inlining a throw instruction into a try block. bool CanInlineBody(const HGraph* callee_graph,
HInvoke* invoke,
size_t* out_number_of_instructions, bool is_speculative) const
REQUIRES_SHARED(Locks::mutator_lock_);
// Create a new HInstanceFieldGet.
HInstanceFieldGet* CreateInstanceFieldGet(uint32_t field_index,
ArtMethod* referrer,
HInstruction* obj); // Create a new HInstanceFieldSet.
HInstanceFieldSet* CreateInstanceFieldSet(uint32_t field_index,
ArtMethod* referrer,
HInstruction* obj,
HInstruction* value, bool* is_final = nullptr);
// Try inlining the invoke instruction using inline caches. bool TryInlineFromInlineCache(HInvoke* invoke_instruction)
REQUIRES_SHARED(Locks::mutator_lock_);
// Try inlining the invoke instruction using CHA. bool TryInlineFromCHA(HInvoke* invoke_instruction)
REQUIRES_SHARED(Locks::mutator_lock_);
// When we fail inlining `invoke_instruction`, we will try to devirtualize the // call. bool TryDevirtualize(HInvoke* invoke_instruction,
ArtMethod* method,
HInvoke** replacement)
REQUIRES_SHARED(Locks::mutator_lock_);
// Try getting the inline cache from JIT code cache. // Return true if the inline cache was successfully allocated and the // invoke info was found in the profile info.
InlineCacheType GetInlineCacheJIT(
HInvoke* invoke_instruction, /*out*/StackHandleScope<InlineCache::kIndividualCacheSize>* classes)
REQUIRES_SHARED(Locks::mutator_lock_);
// Try getting the inline cache from AOT offline profile. // Return true if the inline cache was successfully allocated and the // invoke info was found in the profile info.
InlineCacheType GetInlineCacheAOT(
HInvoke* invoke_instruction, /*out*/StackHandleScope<InlineCache::kIndividualCacheSize>* classes)
REQUIRES_SHARED(Locks::mutator_lock_);
// Try to inline the target of a monomorphic call. If successful, the code // in the graph will look like: // if (receiver.getClass() != ic.GetMonomorphicType()) deopt // ... // inlined code bool TryInlineMonomorphicCall(HInvoke* invoke_instruction, const StackHandleScope<InlineCache::kIndividualCacheSize>& classes)
REQUIRES_SHARED(Locks::mutator_lock_);
// Try to inline targets of a polymorphic call. bool TryInlinePolymorphicCall(HInvoke* invoke_instruction, const StackHandleScope<InlineCache::kIndividualCacheSize>& classes)
REQUIRES_SHARED(Locks::mutator_lock_);
// Returns whether or not we should use only polymorphic inlining with no deoptimizations. bool UseOnlyPolymorphicInliningWithNoDeopt();
// Try CHA-based devirtualization to change virtual method calls into // direct calls. // Returns the actual method that resolved_method can be devirtualized to.
ArtMethod* FindMethodFromCHA(ArtMethod* resolved_method)
REQUIRES_SHARED(Locks::mutator_lock_);
// Add a CHA guard for a CHA-based devirtualized call. A CHA guard checks a // should_deoptimize flag and if it's true, does deoptimization. void AddCHAGuard(HInstruction* invoke_instruction,
uint32_t dex_pc,
HInstruction* cursor,
HBasicBlock* bb_cursor);
// Add a type guard on the given `receiver`. This will add to the graph: // i0 = HFieldGet(receiver, klass) // i1 = HLoadClass(class_index, is_referrer) // i2 = HNotEqual(i0, i1) // // And if `with_deoptimization` is true: // HDeoptimize(i2) // // The method returns the `HNotEqual`, that will be used for polymorphic inlining.
HInstruction* AddTypeGuard(HInstruction* receiver,
HInstruction* cursor,
HBasicBlock* bb_cursor,
dex::TypeIndex class_index,
Handle<mirror::Class> klass,
HInstruction* invoke_instruction, bool with_deoptimization)
REQUIRES_SHARED(Locks::mutator_lock_);
// The 'parent' inliner, that means the inlining optimization that requested // `graph_` to be inlined. const HInliner* const parent_; const HEnvironment* const caller_environment_; const size_t depth_;
// The budget left for inlining, in number of instructions.
size_t inlining_budget_;
// States if we are allowing try catch inlining to occur at this particular instance of inlining. bool try_catch_inlining_allowed_;
// True if we need to run type propagation to type guards we inserted. bool run_extra_type_propagation_;
// Used to record stats about optimizations on the inlined graph. // If the inlining is successful, these stats are merged to the caller graph's stats.
OptimizingCompilerStats* inline_stats_;
DISALLOW_COPY_AND_ASSIGN(HInliner);
};
} // namespace art
#endif// ART_COMPILER_OPTIMIZING_INLINER_H_
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.