Fix non-deterministic compilation for const-string...

... in inlined methods that are not in the boot profile.
If such string is not in the boot image for other reasons,
do not resolve the string and use the kBssEntry load kind.

Boot image sizes for aosp_taimen-userdebug:
 - before:
   arm/boot*.art: 12349440
   arm/boot*.oat: 19862024
   arm64/boot*.art: 16609280
   arm64/boot*.oat: 23568592
 - after:
   arm/boot*.art: 12324864 (-24KiB)
   arm/boot*.oat: 19936612 (+73KiB)
   arm64/boot*.art: 16580608 (-28KiB)
   arm64/boot*.oat: 23642120 (+72KiB)

Test: aosp_taimen-userdebug boots.
Test: m test-art-host-gtest
Bug: 26687569
Change-Id: I3e0b72cd5e8c67904517856208f25a6c379ab601
diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc
index 885a08d..8637db1 100644
--- a/compiler/optimizing/sharpening.cc
+++ b/compiler/optimizing/sharpening.cc
@@ -303,11 +303,26 @@
       // Compiling boot image. Resolve the string and allocate it if needed, to ensure
       // the string will be added to the boot image.
       DCHECK(!runtime->UseJitCompilation());
-      string = class_linker->ResolveString(string_index, dex_cache);
-      CHECK(string != nullptr);
       if (compiler_options.GetCompilePic()) {
         DCHECK(ContainsElement(compiler_options.GetDexFilesForOatFile(), &dex_file));
-        desired_load_kind = HLoadString::LoadKind::kBootImageLinkTimePcRelative;
+        if (compiler_options.IsForceDeterminism()) {
+          // Strings for methods we're compiling should be pre-resolved but Strings in inlined
+          // methods may not be if these inlined methods are not in the boot image profile.
+          // Multiple threads allocating new Strings can cause non-deterministic boot image
+          // because of the image relying on the order of GC roots we walk. (We could fix that
+          // by ordering the roots we walk in ImageWriter.) Therefore we avoid allocating these
+          // strings even if that results in omitting them from the boot image and using the
+          // sub-optimal load kind kBssEntry.
+          string = class_linker->LookupString(string_index, dex_cache.Get());
+        } else {
+          string = class_linker->ResolveString(string_index, dex_cache);
+          CHECK(string != nullptr);
+        }
+        if (string != nullptr) {
+          desired_load_kind = HLoadString::LoadKind::kBootImageLinkTimePcRelative;
+        } else {
+          desired_load_kind = HLoadString::LoadKind::kBssEntry;
+        }
       } else {
         // Test configuration, do not sharpen.
         desired_load_kind = HLoadString::LoadKind::kRuntimeCall;