diff options
-rw-r--r-- | dex2oat/linker/image_writer.cc | 7 | ||||
-rw-r--r-- | runtime/class_table.cc | 5 | ||||
-rw-r--r-- | runtime/intern_table.cc | 4 |
3 files changed, 14 insertions, 2 deletions
diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc index c0dea85434..d4cd867266 100644 --- a/dex2oat/linker/image_writer.cc +++ b/dex2oat/linker/image_writer.cc @@ -1109,10 +1109,13 @@ class ImageWriter::PruneClassesVisitor : public ClassVisitor { 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 a4bc1fbc00..10f60ab508 100644 --- a/runtime/class_table.cc +++ b/runtime/class_table.cc @@ -135,6 +135,11 @@ size_t ClassTable::NumReferencedNonZygoteClasses() const { 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 7f29655de5..f587d0170f 100644 --- a/runtime/intern_table.cc +++ b/runtime/intern_table.cc @@ -340,6 +340,8 @@ ObjPtr<mirror::String> InternTable::Table::Find(ObjPtr<mirror::String> s, 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 @@ ObjPtr<mirror::String> InternTable::Table::Find(ObjPtr<mirror::String> s, 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()) { |