Track what intern tables are from boot images
Goal: Use this to make it faster to do collision checks between app
image intern tables against the non boot image intern tables.
Bug: 116059983
Test: test-art-host
Change-Id: I7a2305167335da5b6685822894f7985970e99053
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index 10d2b6f..d22b301 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -2178,6 +2178,22 @@
EXPECT_TRUE(preresolved_seen.find("Other class init") == preresolved_seen.end());
// Expect the sets match.
EXPECT_GE(seen.size(), preresolved_seen.size());
+
+ // Verify what strings are marked as boot image.
+ std::set<std::string> boot_image_strings;
+ std::set<std::string> app_image_strings;
+
+ MutexLock mu(Thread::Current(), *Locks::intern_table_lock_);
+ intern_table.VisitInterns([&](const GcRoot<mirror::String>& root)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ boot_image_strings.insert(root.Read()->ToModifiedUtf8());
+ }, /*visit_boot_images=*/true, /*visit_non_boot_images=*/false);
+ intern_table.VisitInterns([&](const GcRoot<mirror::String>& root)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ app_image_strings.insert(root.Read()->ToModifiedUtf8());
+ }, /*visit_boot_images=*/false, /*visit_non_boot_images=*/true);
+ EXPECT_EQ(boot_image_strings.size(), 0u);
+ EXPECT_TRUE(app_image_strings == seen);
}
}
diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc
index fd10b6b..5ca7f07 100644
--- a/dex2oat/linker/image_writer.cc
+++ b/dex2oat/linker/image_writer.cc
@@ -2614,17 +2614,19 @@
CHECK_EQ(intern_table_bytes, image_info.intern_table_bytes_);
// Fixup the pointers in the newly written intern table to contain image addresses.
InternTable temp_intern_table;
- // Note that we require that ReadFromMemory does not make an internal copy of the elements so that
- // the VisitRoots() will update the memory directly rather than the copies.
+ // Note that we require that ReadFromMemory does not make an internal copy of the elements so
+ // that the VisitRoots() will update the memory directly rather than the copies.
// This also relies on visit roots not doing any verification which could fail after we update
// the roots to be the image addresses.
- temp_intern_table.AddTableFromMemory(intern_table_memory_ptr, VoidFunctor());
+ temp_intern_table.AddTableFromMemory(intern_table_memory_ptr,
+ VoidFunctor(),
+ /*is_boot_image=*/ false);
CHECK_EQ(temp_intern_table.Size(), intern_table->Size());
temp_intern_table.VisitRoots(&root_visitor, kVisitRootFlagAllRoots);
// Record relocations. (The root visitor does not get to see the slot addresses.)
MutexLock lock(Thread::Current(), *Locks::intern_table_lock_);
DCHECK(!temp_intern_table.strong_interns_.tables_.empty());
- DCHECK(!temp_intern_table.strong_interns_.tables_[0].empty()); // Inserted at the beginning.
+ DCHECK(!temp_intern_table.strong_interns_.tables_[0].Empty()); // Inserted at the beginning.
}
// Write the class table(s) into the image. class_table_bytes_ may be 0 if there are multiple
// class loaders. Writing multiple class tables into the image is currently unsupported.