// NO_THREAD_SAFETY_ANALYSIS: Needs mutator lock, but used from unannotated `HashSet<>` functions. inline uint32_t ClassTable::ClassDescriptorHash::operator()(const TableSlot& slot) const
NO_THREAD_SAFETY_ANALYSIS { // No read barriers needed, we're reading a chain of constant references // for comparison with null and retrieval of constant primitive data. // See `ReadBarrierOption` and `Class::DescriptorHash()`. return slot.Read<kWithoutReadBarrier>()->DescriptorHash();
}
inlinebool ClassTable::ClassDescriptorEquals::operator()(const TableSlot& a, const TableSlot& b) const { // No read barrier needed, we're reading a chain of constant references // for comparison with null and retrieval of constant primitive data. // See ReadBarrierOption and `Class::DescriptorEquals()`. if (a.Hash() != b.Hash()) {
DCHECK(!a.Read<kWithoutReadBarrier>()->DescriptorEquals(b.Read<kWithoutReadBarrier>())); returnfalse;
} return a.Read<kWithoutReadBarrier>()->DescriptorEquals(b.Read<kWithoutReadBarrier>());
}
inlinebool ClassTable::ClassDescriptorEquals::operator()(const TableSlot& a, const DescriptorHashPair& b) const { // No read barrier needed, we're reading a chain of constant references for comparison // with null and retrieval of constant primitive data. See ReadBarrierOption. if (!a.MaskedHashEquals(b.second)) {
DCHECK(!a.Read<kWithoutReadBarrier>()->DescriptorEquals(b.first)); returnfalse;
} return a.Read<kWithoutReadBarrier>()->DescriptorEquals(b.first);
}
template <class Visitor> void ClassTable::VisitRoots(Visitor& visitor, bool skip_classes) {
ReaderMutexLock mu(Thread::Current(), lock_); if (!skip_classes) { for (ClassSet& class_set : classes_) { for (TableSlot& table_slot : class_set) {
table_slot.VisitRoot(visitor);
}
}
} for (GcRoot<mirror::Object>& root : strong_roots_) {
visitor.VisitRoot(root.AddressWithoutBarrier());
} for (const OatFile* oat_file : oat_files_) { for (GcRoot<mirror::Object>& root : oat_file->GetBssGcRoots()) {
visitor.VisitRootIfNonNull(root.AddressWithoutBarrier());
}
}
}
template <class Visitor> void ClassTable::VisitRoots(const Visitor& visitor, bool skip_classes) {
ReaderMutexLock mu(Thread::Current(), lock_); if (!skip_classes) { for (ClassSet& class_set : classes_) { for (TableSlot& table_slot : class_set) {
table_slot.VisitRoot(visitor);
}
}
} for (GcRoot<mirror::Object>& root : strong_roots_) {
visitor.VisitRoot(root.AddressWithoutBarrier());
} for (const OatFile* oat_file : oat_files_) { for (GcRoot<mirror::Object>& root : oat_file->GetBssGcRoots()) {
visitor.VisitRootIfNonNull(root.AddressWithoutBarrier());
}
}
}
template <class Condition, class Visitor> void ClassTable::VisitClassesIfConditionMet(Condition& cond, Visitor& visitor) {
ReaderMutexLock mu(Thread::Current(), lock_); for (ClassSet& class_set : classes_) { if (cond(class_set)) { for (TableSlot& table_slot : class_set) {
table_slot.VisitRoot(visitor);
}
}
}
}
template<ReadBarrierOption kReadBarrierOption> inline ObjPtr<mirror::Class> ClassTable::TableSlot::Read() const { const uint32_t before = data_.load(std::memory_order_relaxed); const ObjPtr<mirror::Class> before_ptr(ExtractPtr(before)); const ObjPtr<mirror::Class> after_ptr(
GcRoot<mirror::Class>(before_ptr).Read<kReadBarrierOption>()); if (kReadBarrierOption != kWithoutReadBarrier && before_ptr != after_ptr) { // If another thread raced and updated the reference, do not store the read barrier updated // one.
data_.CompareAndSetStrongRelease(before, Encode(after_ptr, MaskHash(before)));
} return after_ptr;
}
template<typename Visitor> inlinevoid ClassTable::TableSlot::VisitRoot(const Visitor& visitor) const { const uint32_t before = data_.load(std::memory_order_relaxed);
ObjPtr<mirror::Class> before_ptr(ExtractPtr(before));
GcRoot<mirror::Class> root(before_ptr);
visitor.VisitRoot(root.AddressWithoutBarrier());
ObjPtr<mirror::Class> after_ptr(root.Read<kWithoutReadBarrier>()); if (before_ptr != after_ptr) { // If another thread raced and updated the reference, do not store the read barrier updated // one.
data_.CompareAndSetStrongRelease(before, Encode(after_ptr, MaskHash(before)));
}
}
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.