Add comments about class/intern table search order.
Also add a related comment about pruning classes only from
the last class set in the `ClassTable` and move some local
variables out of a loop.
Test: Rely on TreeHugger.
Bug: 181943478
Change-Id: Iba1296fb60fde2f90e1e256865bf02ebc3d8f292
diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc
index c0dea85..d4cd867 100644
--- a/dex2oat/linker/image_writer.cc
+++ b/dex2oat/linker/image_writer.cc
@@ -1109,10 +1109,13 @@
ClassTable* class_table =
Runtime::Current()->GetClassLinker()->ClassTableForClassLoader(class_loader_);
WriterMutexLock mu(Thread::Current(), class_table->lock_);
+ // App class loader class tables contain only one internal set. The boot class path class
+ // table also contains class sets from boot images we're compiling against but we are not
+ // pruning these boot image classes, so all classes to remove are in the last set.
+ DCHECK(!class_table->classes_.empty());
+ ClassTable::ClassSet& last_class_set = class_table->classes_.back();
for (mirror::Class* klass : classes_to_prune_) {
uint32_t hash = ClassTable::TableSlot::HashDescriptor(klass);
- DCHECK(!class_table->classes_.empty());
- ClassTable::ClassSet& last_class_set = class_table->classes_.back();
auto it = last_class_set.FindWithHash(ClassTable::TableSlot(klass, hash), hash);
DCHECK(it != last_class_set.end());
last_class_set.erase(it);
diff --git a/runtime/class_table.cc b/runtime/class_table.cc
index a4bc1fb..10f60ab 100644
--- a/runtime/class_table.cc
+++ b/runtime/class_table.cc
@@ -135,6 +135,11 @@
ObjPtr<mirror::Class> ClassTable::Lookup(const char* 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()) {
diff --git a/runtime/intern_table.cc b/runtime/intern_table.cc
index 7f29655..f587d01 100644
--- a/runtime/intern_table.cc
+++ b/runtime/intern_table.cc
@@ -340,6 +340,8 @@
for (Table::InternalTable& table : MakeIterationRange(tables_.begin(), mid)) {
DCHECK(table.set_.FindWithHash(GcRoot<mirror::String>(s), hash) == table.set_.end());
}
+ // Search from the last table, assuming that apps shall search for their own
+ // strings more often than for boot image strings.
for (Table::InternalTable& table : ReverseRange(MakeIterationRange(mid, tables_.end()))) {
auto it = table.set_.FindWithHash(GcRoot<mirror::String>(s), hash);
if (it != table.set_.end()) {
@@ -352,6 +354,8 @@
FLATTEN
ObjPtr<mirror::String> InternTable::Table::Find(const Utf8String& string, uint32_t hash) {
Locks::intern_table_lock_->AssertHeld(Thread::Current());
+ // Search from the last table, assuming that apps shall search for their own
+ // strings more often than for boot image strings.
for (InternalTable& table : ReverseRange(tables_)) {
auto it = table.set_.FindWithHash(string, hash);
if (it != table.set_.end()) {