void ClassTable::FreezeSnapshot() {
WriterMutexLock mu(Thread::Current(), lock_); // Propagate the min/max load factor from the old active set.
DCHECK(!classes_.empty()); const ClassSet& last_set = classes_.back();
ClassSet new_set(last_set.GetMinLoadFactor(), last_set.GetMaxLoadFactor());
classes_.push_back(std::move(new_set));
}
ObjPtr<mirror::Class> ClassTable::UpdateClass(ObjPtr<mirror::Class> klass, size_t hash) {
WriterMutexLock mu(Thread::Current(), lock_); // Should only be updating latest table.
TableSlot slot(klass, hash); auto existing_it = classes_.back().FindWithHash(slot, hash); if (UNLIKELY(existing_it == classes_.back().end())) { for (const ClassSet& class_set : classes_) { if (class_set.FindWithHash(slot, hash) != class_set.end()) {
LOG(FATAL) << "Updating class found in frozen table " << klass->PrettyDescriptor();
UNREACHABLE();
}
}
LOG(FATAL) << "Updating class not found " << klass->PrettyDescriptor();
UNREACHABLE();
} const ObjPtr<mirror::Class> existing = existing_it->Read();
CHECK_NE(existing, klass) << klass->PrettyDescriptor();
CHECK(!existing->IsResolved()) << klass->PrettyDescriptor();
CHECK_EQ(klass->GetStatus(), ClassStatus::kResolving) << klass->PrettyDescriptor();
CHECK(!klass->IsTemp()) << klass->PrettyDescriptor();
VerifyObject(klass); // Update the element in the hash set with the new class. This is safe to do since the descriptor // doesn't change.
*existing_it = slot; return existing;
}
ObjPtr<mirror::Class> ClassTable::Lookup(std::string_view descriptor, size_t hash) {
DescriptorHashPair pair(descriptor, hash);
ReaderMutexLock mu(Thread::Current(), lock_); // Search from the last table, assuming that apps shall search for their own classes // more often than for boot image classes. For prebuilt boot images, this also helps // by searching the large table from the framework boot image extension compiled as // single-image before the individual small tables from the primary boot image // compiled as multi-image. for (ClassSet& class_set : ReverseRange(classes_)) { auto it = class_set.FindWithHash(pair, hash); if (it != class_set.end()) { return it->Read();
}
} return nullptr;
}
void ClassTable::AddClassSet(ClassSet&& set) {
WriterMutexLock mu(Thread::Current(), lock_); // Insert before the last (unfrozen) table since we add new classes into the back. // Keep the order of previous frozen tables unchanged, so that we can can remember // the number of searched frozen tables and not search them again. // TODO: Make use of this in `ClassLinker::FindClass()`.
DCHECK(!classes_.empty());
classes_.insert(classes_.end() - 1, std::move(set));
}
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.