/** *ClassHierarchyAnalysis(CHA)triestodevirtualizevirtualcallsinto *directcallsbasedontheinfogeneratedbyanalyzingclasshierarchies. *Ifaclassisnotsubclassed,orevenifit'ssubclassedbutoneofits *virtualmethodsisn'toverridden,avirtualcallforthatmethodcanbe *changedintoadirectcall. * *Eachvirtualmethodcarriesasingle-implementationstatus.Thestatusis *incrementallymaintainedattheendofclasslinkingtimewhenmethod *overridingtakeseffect. * *Compilertakesadvantageofthesingle-implementationinfoofa *method.IfamethodAhasthesingle-implementationflagset,thecompiler *devirtualizesthevirtualcallformethodAintoadirectcall,and *furthertrytoinlinethedirectcallasaresult.Thecompilerwill *alsoregisteradependencythatthecompiledcodedependsonthe *assumptionthatmethodAhassingle-implementationstatus. * *Whensingle-implementationinfoisupdatedattheendofclasslinking, *andifmethodA'ssingle-implementationstatusisinvalidated,allcompiled *codethatdependsontheassumptionthatmethodAhassingle-implementation *statusneedtobeinvalidated.Methodentrypointsthathavethisdependency *willbeupdatedasaresult.MethodAcanlaterberecompiledwithless *aggressiveassumptions. * *Forlivecompiledcodethat'sonstack,deoptmizationwillbeinitiated *toforcetheinvalidatedcompiledcodeintointerpretermodetoguarantee *correctness.Thedeoptimizationmechanismusedisahybridof *synchronousandasynchronousdeoptimization.Thesynchronousdeoptimization *partchecksahiddenlocalvariableflagforthemethod,andiftrue, *initiatesdeoptimization.Theasynchronousdeoptimizationpartissuesa *checkpointthatwalksthestackandforanycompiledcodeonthestack *thatshouldbedeoptimized,setthehiddenlocalvariablevaluetobetrue. * *Acha_lock_needstobeheldforupdatingsingle-implementationstatus, *andregistering/unregisteringCHAdependencies.RegisteringCHAdependency *andmakingcompiledcodevisiblealsoneedtobeatomic.Otherwise,we *maymissinvalidatingCHAdependentsormakingcompiledcodevisibleeven *afteritisinvalidated.Careneedstobetakenbetweencha_lock_and *JitCodeCache::lock_toguaranteetheatomicity. * *WebaseourCHAondynamicallylinkedclassprofilesinsteadofdoingstatic *analysis.Staticanalysiscanbetooaggressiveduetodynamicclassloading *atruntime,andtooconservativesincesomeclassesmaynotbereallyloaded *atruntime.
*/ class ClassHierarchyAnalysis { public: // Types for recording CHA dependencies. // For invalidating CHA dependency, we need to know both the ArtMethod and // the method header. If the ArtMethod has compiled code with the method header // as the entrypoint, we update the entrypoint to the interpreter bridge. // We will also deoptimize frames that are currently executing the code of // the method header. using MethodAndMethodHeaderPair = std::pair<ArtMethod*, OatQuickMethodHeader*>; using ListOfDependentPairs = std::vector<MethodAndMethodHeaderPair>;
ClassHierarchyAnalysis() {}
// Add a dependency that compiled code with `dependent_header` for `dependent_method` // assumes that virtual `method` has single-implementation. void AddDependency(ArtMethod* method,
ArtMethod* dependent_method,
OatQuickMethodHeader* dependent_header) REQUIRES(Locks::cha_lock_);
// Return compiled code that assumes that `method` has single-implementation. const ListOfDependentPairs& GetDependents(ArtMethod* method) REQUIRES(Locks::cha_lock_);
// Remove dependency tracking for compiled code that assumes that // `method` has single-implementation. void RemoveAllDependenciesFor(ArtMethod* method) REQUIRES(Locks::cha_lock_);
// Remove from cha_dependency_map_ all entries that contain OatQuickMethodHeader from // the given `method_headers` set. // This is used when some compiled code is freed. void RemoveDependentsWithMethodHeaders( const std::unordered_set<OatQuickMethodHeader*>& method_headers)
REQUIRES(Locks::cha_lock_);
// If a given class belongs to a linear allocation that is about to be deleted, in all its // superclasses and superinterfaces reset SingleImplementation fields of their methods // that might be affected by the deletion. // The method is intended to be called during GC before ReclaimPhase, since it gets info from // Java objects that are going to be collected. // For the same reason it's important to access objects without read barrier to not revive them. void ResetSingleImplementationInHierarchy(ObjPtr<mirror::Class> klass, const LinearAlloc* alloc,
PointerSize pointer_size) const REQUIRES_SHARED(Locks::mutator_lock_);
// Update CHA info for methods that `klass` overrides, after loading `klass`. void UpdateAfterLoadingOf(Handle<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
// Remove all of the dependencies for a linear allocator. This is called when dex cache unloading // occurs. void RemoveDependenciesForLinearAlloc(Thread* self, const LinearAlloc* linear_alloc)
REQUIRES(!Locks::cha_lock_);
// Check/update single-implementation info when one virtual method // overrides another. // `virtual_method` in `klass` overrides `method_in_super`. // This may invalidate some assumptions on single-implementation. // Append methods that should have their single-implementation flag invalidated // to `invalidated_single_impl_methods`. void CheckVirtualMethodSingleImplementationInfo(
Handle<mirror::Class> klass,
ArtMethod* virtual_method,
ArtMethod* method_in_super,
std::unordered_set<ArtMethod*>& invalidated_single_impl_methods,
PointerSize pointer_size)
REQUIRES_SHARED(Locks::mutator_lock_);
// Check/update single-implementation info when one method // implements an interface method. // `implementation_method` in `klass` implements `interface_method`. // Append `interface_method` to `invalidated_single_impl_methods` // if `interface_method` gets a new implementation. void CheckInterfaceMethodSingleImplementationInfo(
Handle<mirror::Class> klass,
ArtMethod* interface_method,
ArtMethod* implementation_method,
std::unordered_set<ArtMethod*>& invalidated_single_impl_methods,
PointerSize pointer_size)
REQUIRES_SHARED(Locks::mutator_lock_);
// A map that maps a method to a set of compiled code that assumes that method has a // single implementation, which is used to do CHA-based devirtualization.
std::unordered_map<ArtMethod*, ListOfDependentPairs> cha_dependency_map_
GUARDED_BY(Locks::cha_lock_);
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.