Store class tables in the image
Reduces how long it takes to load an application image.
N5 boot.art size
Before: 8007680
After: 8122368
Also reduces boot time by how long AddImageClassesToClassTable
used to take (~20ms).
Changed class hashes to be uint32_t to fix cross compilation. We need
serialized hash tables to be valid with different pointer sizes.
Bug: 22858531
Change-Id: I463fc83f499ff75f509e80c253a55b9116ee5b89
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc
index 3d9f7dc..7d2d899 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -526,6 +526,21 @@
temp_table.VisitRoots(&visitor, kVisitRootFlagAllRoots);
}
+void PatchOat::PatchClassTable(const ImageHeader* image_header) {
+ const auto& section = image_header->GetImageSection(ImageHeader::kSectionClassTable);
+ // ClassTable temp_table;
+ // Note that we require that ReadFromMemory does not make an internal copy of the elements.
+ // This also relies on visit roots not doing any verification which could fail after we update
+ // the roots to be the image addresses.
+ WriterMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
+ ClassTable temp_table;
+ temp_table.ReadFromMemory(image_->Begin() + section.Offset());
+ FixupRootVisitor visitor(this);
+ BufferedRootVisitor<kDefaultBufferedRootCount> buffered_visitor(&visitor, RootInfo(kRootUnknown));
+ temp_table.VisitRoots(buffered_visitor);
+}
+
+
class RelocatedPointerVisitor {
public:
explicit RelocatedPointerVisitor(PatchOat* patch_oat) : patch_oat_(patch_oat) {}
@@ -606,6 +621,7 @@
PatchArtFields(image_header);
PatchArtMethods(image_header);
PatchInternedStrings(image_header);
+ PatchClassTable(image_header);
// Patch dex file int/long arrays which point to ArtFields.
PatchDexFileArrays(img_roots);