Pre-resolve dex cache strings before collecting string offsets
Fix a bug where string offsets are nondeterministic in some cases.
This was caused by preresolving strings after collecting string
offsets.
Bug: 120039850
Test: test-art-host
(cherry picked from commit fe0e00a4d683aefa572dcc50b3f87ff77cb5162a)
Merged-In: I39235c6b4fa43a89e7082962d1c7d4643748d078
Change-Id: Ia22cb82fa07091a75a1cfaeb24231ce53d706b35
diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc
index c36f360..9626e21 100644
--- a/dex2oat/linker/image_writer.cc
+++ b/dex2oat/linker/image_writer.cc
@@ -253,6 +253,19 @@
CheckNonImageClassesRemoved();
}
+ {
+ // Preload deterministic contents to the dex cache arrays we're going to write.
+ ScopedObjectAccess soa(self);
+ ObjPtr<mirror::ClassLoader> class_loader = GetAppClassLoader();
+ std::vector<ObjPtr<mirror::DexCache>> dex_caches = FindDexCaches(self);
+ for (ObjPtr<mirror::DexCache> dex_cache : dex_caches) {
+ if (!IsImageObject(dex_cache)) {
+ continue; // Boot image DexCache is not written to the app image.
+ }
+ PreloadDexCache(dex_cache, class_loader);
+ }
+ }
+
// Used to store information that will later be used to calculate image
// offsets to string references in the AppImage.
std::vector<HeapReferencePointerInfo> string_ref_info;
@@ -697,20 +710,7 @@
CHECK(!oat_filenames.empty());
CHECK_EQ(image_filenames.size(), oat_filenames.size());
- Thread* self = Thread::Current();
- {
- // Preload deterministic contents to the dex cache arrays we're going to write.
- ScopedObjectAccess soa(self);
- ObjPtr<mirror::ClassLoader> class_loader = GetAppClassLoader();
- std::vector<ObjPtr<mirror::DexCache>> dex_caches = FindDexCaches(self);
- for (ObjPtr<mirror::DexCache> dex_cache : dex_caches) {
- if (!IsImageObject(dex_cache)) {
- continue; // Boot image DexCache is not written to the app image.
- }
- PreloadDexCache(dex_cache, class_loader);
- }
- }
-
+ Thread* const self = Thread::Current();
{
ScopedObjectAccess soa(self);
for (size_t i = 0; i < oat_filenames.size(); ++i) {