Avoid read barrier for image HLoadClass

Concurrent copying baker:

X86_64 core-optimizing-pic.oat: 28583112 -> 27906824 (2.4% smaller)

Around 0.4% of 2.4% is from re-enabling kBootImageLinkTimeAddress,
kBootImageLinkTimePcRelative, and kBootImageAddress.

N6P boot.oat 32: 73042140 -> 71891956 (1.57% smaller)
N6P boot.oat 64: 83831608 -> 82531456 (1.55% smaller)

EAAC: 1252 -> 1245 (32 samples)

Bug: 29516974

Test: test-art-host CC baker, N6P booting

Change-Id: I9a196cf0157058836981c43c93872e9f0c4919aa
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index ceceedd..36f7b4d 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -4044,17 +4044,6 @@
 
 HLoadClass::LoadKind CodeGeneratorARM64::GetSupportedLoadClassKind(
     HLoadClass::LoadKind desired_class_load_kind) {
-  if (kEmitCompilerReadBarrier) {
-    switch (desired_class_load_kind) {
-      case HLoadClass::LoadKind::kBootImageLinkTimeAddress:
-      case HLoadClass::LoadKind::kBootImageLinkTimePcRelative:
-      case HLoadClass::LoadKind::kBootImageAddress:
-        // TODO: Implement for read barrier.
-        return HLoadClass::LoadKind::kDexCacheViaMethod;
-      default:
-        break;
-    }
-  }
   switch (desired_class_load_kind) {
     case HLoadClass::LoadKind::kReferrersClass:
       break;
@@ -4089,11 +4078,12 @@
     return;
   }
 
-  LocationSummary::CallKind call_kind = (cls->NeedsEnvironment() || kEmitCompilerReadBarrier)
+  const bool requires_read_barrier = kEmitCompilerReadBarrier && !cls->IsInBootImage();
+  LocationSummary::CallKind call_kind = (cls->NeedsEnvironment() || requires_read_barrier)
       ? LocationSummary::kCallOnSlowPath
       : LocationSummary::kNoCall;
   LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(cls, call_kind);
-  if (kUseBakerReadBarrier && !cls->NeedsEnvironment()) {
+  if (kUseBakerReadBarrier && requires_read_barrier && !cls->NeedsEnvironment()) {
     locations->SetCustomSlowPathCallerSaves(RegisterSet());  // No caller-save registers.
   }
 
@@ -4116,6 +4106,7 @@
   Location out_loc = cls->GetLocations()->Out();
   Register out = OutputRegister(cls);
 
+  const bool requires_read_barrier = kEmitCompilerReadBarrier && !cls->IsInBootImage();
   bool generate_null_check = false;
   switch (cls->GetLoadKind()) {
     case HLoadClass::LoadKind::kReferrersClass: {
@@ -4123,17 +4114,21 @@
       DCHECK(!cls->MustGenerateClinitCheck());
       // /* GcRoot<mirror::Class> */ out = current_method->declaring_class_
       Register current_method = InputRegisterAt(cls, 0);
-      GenerateGcRootFieldLoad(
-          cls, out_loc, current_method, ArtMethod::DeclaringClassOffset().Int32Value());
+      GenerateGcRootFieldLoad(cls,
+                              out_loc,
+                              current_method,
+                              ArtMethod::DeclaringClassOffset().Int32Value(),
+                              /*fixup_label*/ nullptr,
+                              requires_read_barrier);
       break;
     }
     case HLoadClass::LoadKind::kBootImageLinkTimeAddress:
-      DCHECK(!kEmitCompilerReadBarrier);
+      DCHECK(!requires_read_barrier);
       __ Ldr(out, codegen_->DeduplicateBootImageTypeLiteral(cls->GetDexFile(),
                                                             cls->GetTypeIndex()));
       break;
     case HLoadClass::LoadKind::kBootImageLinkTimePcRelative: {
-      DCHECK(!kEmitCompilerReadBarrier);
+      DCHECK(!requires_read_barrier);
       // Add ADRP with its PC-relative type patch.
       const DexFile& dex_file = cls->GetDexFile();
       uint32_t type_index = cls->GetTypeIndex();
@@ -4154,7 +4149,7 @@
       break;
     }
     case HLoadClass::LoadKind::kBootImageAddress: {
-      DCHECK(!kEmitCompilerReadBarrier);
+      DCHECK(!requires_read_barrier);
       DCHECK(cls->GetAddress() != 0u && IsUint<32>(cls->GetAddress()));
       __ Ldr(out.W(), codegen_->DeduplicateBootImageAddressLiteral(cls->GetAddress()));
       break;
@@ -4172,7 +4167,12 @@
       uint32_t offset = cls->GetAddress() & MaxInt<uint64_t>(offset_bits);
       __ Ldr(out.X(), codegen_->DeduplicateDexCacheAddressLiteral(base_address));
       // /* GcRoot<mirror::Class> */ out = *(base_address + offset)
-      GenerateGcRootFieldLoad(cls, out_loc, out.X(), offset);
+      GenerateGcRootFieldLoad(cls,
+                              out_loc,
+                              out.X(),
+                              offset,
+                              /*fixup_label*/ nullptr,
+                              requires_read_barrier);
       generate_null_check = !cls->IsInDexCache();
       break;
     }
@@ -4191,7 +4191,12 @@
       vixl::aarch64::Label* ldr_label =
           codegen_->NewPcRelativeDexCacheArrayPatch(dex_file, element_offset, adrp_label);
       // /* GcRoot<mirror::Class> */ out = *(base_address + offset)  /* PC-relative */
-      GenerateGcRootFieldLoad(cls, out_loc, out.X(), /* offset placeholder */ 0, ldr_label);
+      GenerateGcRootFieldLoad(cls,
+                              out_loc,
+                              out.X(),
+                              /* offset placeholder */ 0,
+                              ldr_label,
+                              requires_read_barrier);
       generate_null_check = !cls->IsInDexCache();
       break;
     }
@@ -4203,8 +4208,12 @@
       Register current_method = InputRegisterAt(cls, 0);
       __ Ldr(out.X(), MemOperand(current_method, resolved_types_offset.Int32Value()));
       // /* GcRoot<mirror::Class> */ out = out[type_index]
-      GenerateGcRootFieldLoad(
-          cls, out_loc, out.X(), CodeGenerator::GetCacheOffset(cls->GetTypeIndex()));
+      GenerateGcRootFieldLoad(cls,
+                              out_loc,
+                              out.X(),
+                              CodeGenerator::GetCacheOffset(cls->GetTypeIndex()),
+                              /*fixup_label*/ nullptr,
+                              requires_read_barrier);
       generate_null_check = !cls->IsInDexCache();
       break;
     }
@@ -5106,9 +5115,11 @@
                                                             Location root,
                                                             Register obj,
                                                             uint32_t offset,
-                                                            vixl::aarch64::Label* fixup_label) {
+                                                            vixl::aarch64::Label* fixup_label,
+                                                            bool requires_read_barrier) {
   Register root_reg = RegisterFrom(root, Primitive::kPrimNot);
-  if (kEmitCompilerReadBarrier) {
+  if (requires_read_barrier) {
+    DCHECK(kEmitCompilerReadBarrier);
     if (kUseBakerReadBarrier) {
       // Fast path implementation of art::ReadBarrier::BarrierForRoot when
       // Baker's read barrier are used: