summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dex2oat/linker/image_writer.cc7
-rw-r--r--runtime/class_table.cc5
-rw-r--r--runtime/intern_table.cc4
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()) {