Determine HLoadClass/String load kind early.

This helps save memory by avoiding the allocation of
HEnvironment and related objects for AOT references to
boot image strings and classes (kBootImage* load kinds)
and also for JIT references (kJitTableAddress).

Compiling aosp_taimen-userdebug boot image, the most memory
hungry method BatteryStats.dumpLocked() needs
  - before:
    Used 55105384 bytes of arena memory...
    ...
    UseListNode    10009704
    Environment      423248
    EnvVRegs       20676560
    ...
  - after:
    Used 50559176 bytes of arena memory...
    ...
    UseListNode     8568936
    Environment      365680
    EnvVRegs       17628704
    ...

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing --jit
Bug: 34053922
Change-Id: I68e73a438e6ac8e8908e6fccf53bbeea8a64a077
diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc
index e46c9a7..64092d3 100644
--- a/compiler/optimizing/sharpening.cc
+++ b/compiler/optimizing/sharpening.cc
@@ -45,8 +45,6 @@
         SharpenInvokeStaticOrDirect(instruction->AsInvokeStaticOrDirect(),
                                     codegen_,
                                     compiler_driver_);
-      } else if (instruction->IsLoadString()) {
-        ProcessLoadString(instruction->AsLoadString());
       }
       // TODO: Move the sharpening of invoke-virtual/-interface/-super from HGraphBuilder
       //       here. Rewrite it to avoid the CompilerDriver's reliance on verifier data
@@ -147,10 +145,11 @@
   invoke->SetDispatchInfo(dispatch_info);
 }
 
-HLoadClass::LoadKind HSharpening::ComputeLoadClassKind(HLoadClass* load_class,
-                                                       CodeGenerator* codegen,
-                                                       CompilerDriver* compiler_driver,
-                                                       const DexCompilationUnit& dex_compilation_unit) {
+HLoadClass::LoadKind HSharpening::ComputeLoadClassKind(
+    HLoadClass* load_class,
+    CodeGenerator* codegen,
+    CompilerDriver* compiler_driver,
+    const DexCompilationUnit& dex_compilation_unit) {
   Handle<mirror::Class> klass = load_class->GetClass();
   DCHECK(load_class->GetLoadKind() == HLoadClass::LoadKind::kRuntimeCall ||
          load_class->GetLoadKind() == HLoadClass::LoadKind::kReferrersClass)
@@ -237,7 +236,12 @@
   return load_kind;
 }
 
-void HSharpening::ProcessLoadString(HLoadString* load_string) {
+void HSharpening::ProcessLoadString(
+    HLoadString* load_string,
+    CodeGenerator* codegen,
+    CompilerDriver* compiler_driver,
+    const DexCompilationUnit& dex_compilation_unit,
+    VariableSizedHandleScope* handles) {
   DCHECK_EQ(load_string->GetLoadKind(), HLoadString::LoadKind::kRuntimeCall);
 
   const DexFile& dex_file = load_string->GetDexFile();
@@ -249,26 +253,26 @@
     ClassLinker* class_linker = runtime->GetClassLinker();
     ScopedObjectAccess soa(Thread::Current());
     StackHandleScope<1> hs(soa.Self());
-    Handle<mirror::DexCache> dex_cache = IsSameDexFile(dex_file, *compilation_unit_.GetDexFile())
-        ? compilation_unit_.GetDexCache()
+    Handle<mirror::DexCache> dex_cache = IsSameDexFile(dex_file, *dex_compilation_unit.GetDexFile())
+        ? dex_compilation_unit.GetDexCache()
         : hs.NewHandle(class_linker->FindDexCache(soa.Self(), dex_file));
-    mirror::String* string = nullptr;
+    ObjPtr<mirror::String> string = nullptr;
 
-    if (codegen_->GetCompilerOptions().IsBootImage()) {
+    if (codegen->GetCompilerOptions().IsBootImage()) {
       // 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(dex_file, string_index, dex_cache);
       CHECK(string != nullptr);
-      if (compiler_driver_->GetSupportBootImageFixup()) {
-        DCHECK(ContainsElement(compiler_driver_->GetDexFilesForOatFile(), &dex_file));
+      if (compiler_driver->GetSupportBootImageFixup()) {
+        DCHECK(ContainsElement(compiler_driver->GetDexFilesForOatFile(), &dex_file));
         desired_load_kind = HLoadString::LoadKind::kBootImageLinkTimePcRelative;
       } else {
         // compiler_driver_test. Do not sharpen.
         desired_load_kind = HLoadString::LoadKind::kRuntimeCall;
       }
     } else if (runtime->UseJitCompilation()) {
-      DCHECK(!codegen_->GetCompilerOptions().GetCompilePic());
+      DCHECK(!codegen->GetCompilerOptions().GetCompilePic());
       string = class_linker->LookupString(dex_file, string_index, dex_cache.Get());
       if (string != nullptr) {
         if (runtime->GetHeap()->ObjectIsInBootImageSpace(string)) {
@@ -283,7 +287,7 @@
       // AOT app compilation. Try to lookup the string without allocating if not found.
       string = class_linker->LookupString(dex_file, string_index, dex_cache.Get());
       if (string != nullptr && runtime->GetHeap()->ObjectIsInBootImageSpace(string)) {
-        if (codegen_->GetCompilerOptions().GetCompilePic()) {
+        if (codegen->GetCompilerOptions().GetCompilePic()) {
           desired_load_kind = HLoadString::LoadKind::kBootImageInternTable;
         } else {
           desired_load_kind = HLoadString::LoadKind::kBootImageAddress;
@@ -293,12 +297,12 @@
       }
     }
     if (string != nullptr) {
-      load_string->SetString(handles_->NewHandle(string));
+      load_string->SetString(handles->NewHandle(string));
     }
   }
   DCHECK_NE(desired_load_kind, static_cast<HLoadString::LoadKind>(-1));
 
-  HLoadString::LoadKind load_kind = codegen_->GetSupportedLoadStringKind(desired_load_kind);
+  HLoadString::LoadKind load_kind = codegen->GetSupportedLoadStringKind(desired_load_kind);
   load_string->SetLoadKind(load_kind);
 }