// Data contains the class pointer GcRoot as well as the low bits of the descriptor hash. mutable Atomic<uint32_t> data_; static constexpr uint32_t kHashMask = kObjectAlignment - 1;
};
using DescriptorHashPair = std::pair<std::string_view, uint32_t>;
class ClassDescriptorHash { public: // uint32_t for cross compilation. Requires mutator lock, but caller is not properly annotated.
uint32_t operator()(const TableSlot& slot) const; // uint32_t for cross compilation.
uint32_t operator()(const DescriptorHashPair& pair) const;
};
class ClassDescriptorEquals { public: // Same class loader and descriptor. booloperator()(const TableSlot& a, const TableSlot& b) const
NO_THREAD_SAFETY_ANALYSIS; // Same descriptor. booloperator()(const TableSlot& a, const DescriptorHashPair& b) const
NO_THREAD_SAFETY_ANALYSIS;
};
// Hash set that hashes class descriptor, and compares descriptors and class loaders. Results // should be compared for a matching class descriptor and class loader. using ClassSet = HashSet<TableSlot,
TableSlotEmptyFn,
ClassDescriptorHash,
ClassDescriptorEquals,
GcRootArenaAllocator<TableSlot, kAllocatorTagClassTable>>;
EXPORT ClassTable();
// Freeze the current class tables by allocating a new table and never updating or modifying the // existing table. This helps prevents dirty pages after caused by inserting after zygote fork. void FreezeSnapshot()
REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Returns the number of classes in previous snapshots defined by `defining_loader`.
size_t NumZygoteClasses(ObjPtr<mirror::ClassLoader> defining_loader) const
REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Returns all off the classes in the lastest snapshot defined by `defining_loader`.
size_t NumNonZygoteClasses(ObjPtr<mirror::ClassLoader> defining_loader) const
REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Returns the number of classes in previous snapshots no matter the defining loader.
EXPORT size_t NumReferencedZygoteClasses() const
REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Returns all off the classes in the lastest snapshot no matter the defining loader.
size_t NumReferencedNonZygoteClasses() const
REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Returns the number of class-sets in the class table.
size_t Size() const
REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Update a class in the table with the new class. Returns the existing class which was replaced.
ObjPtr<mirror::Class> UpdateClass(ObjPtr<mirror::Class> new_klass, size_t hash)
REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Visit classes in those class-sets which satisfy 'cond'. template <class Condition, class Visitor> void VisitClassesIfConditionMet(Condition& cond, Visitor& visitor) REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_); // Stops visit if the visitor returns false. template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor> bool Visit(Visitor& visitor)
REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_); template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor> bool Visit(const Visitor& visitor)
REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Return the first class that matches the descriptor. Returns null if there are none.
ObjPtr<mirror::Class> Lookup(std::string_view descriptor, size_t hash)
REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Return the first class that matches the descriptor of klass. Returns null if there are none. // Used for tests and debug-build checks.
ObjPtr<mirror::Class> LookupByDescriptor(ObjPtr<mirror::Class> klass)
REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Return true if we inserted the strong root, false if it already exists. bool InsertStrongRoot(ObjPtr<mirror::Object> obj)
REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Return true if we inserted the oat file, false if it already exists. bool InsertOatFile(const OatFile* oat_file)
REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Read a table from ptr and put it at the front of the class set.
EXPORT size_t ReadFromMemory(uint8_t* ptr)
REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Add a class set to the front of classes. void AddClassSet(ClassSet&& set)
REQUIRES(!lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Return true if we inserted the oat file, false if it already exists. bool InsertOatFileLocked(const OatFile* oat_file)
REQUIRES(lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
// Lock to guard inserting and removing. mutable ReaderWriterMutex lock_; // We have a vector to help prevent dirty pages after the zygote forks by calling FreezeSnapshot.
std::vector<ClassSet> classes_ GUARDED_BY(lock_); // Extra strong roots that can be either dex files or dex caches. Dex files used by the class // loader which may not be owned by the class loader must be held strongly live. Also dex caches // are held live to prevent them being unloading once they have classes in them.
std::vector<GcRoot<mirror::Object>> strong_roots_ GUARDED_BY(lock_); // Keep track of oat files with GC roots associated with dex caches in `strong_roots_`.
std::vector<const OatFile*> oat_files_ GUARDED_BY(lock_);
friendclass linker::ImageWriter; // for InsertWithoutLocks.
};
} // namespace art
#endif// ART_RUNTIME_CLASS_TABLE_H_
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.11 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.