Add PreResolved strings dex cache array

For app images, this dex cache may be prepopulated to speed up
application startup. This new dex cache array is created when
--resolve-startup-const-strings=true.

Test: test-art-host
Bug: 116059983
Bug: 118385560

Change-Id: I379dc15174281665d7f4ceb106f7fbf51f89b921
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 864b215..df6e8a8 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -719,6 +719,10 @@
 
   for (const DexFile* dex_file : dex_files) {
     dex_cache.Assign(class_linker->FindDexCache(soa.Self(), *dex_file));
+    if (only_startup_strings) {
+      // When resolving startup strings, create the preresolved strings array.
+      dex_cache->AddPreResolvedStringsArray();
+    }
     TimingLogger::ScopedTiming t("Resolve const-string Strings", timings);
 
     for (ClassAccessor accessor : dex_file->GetClasses()) {
@@ -757,6 +761,10 @@
                   : inst->VRegB_31c());
               ObjPtr<mirror::String> string = class_linker->ResolveString(string_index, dex_cache);
               CHECK(string != nullptr) << "Could not allocate a string when forcing determinism";
+              if (only_startup_strings) {
+                dex_cache->GetPreResolvedStrings()[string_index.index_] =
+                    GcRoot<mirror::String>(string);
+              }
               ++num_instructions;
               break;
             }