Revert "Revert "Store resolved Strings for AOT code in .bss.""

Fixed oat_test to keep dex files alive. Fixed mips build.
Rewritten the .bss GC root visiting and added write barrier
to the artResolveStringFromCode().

Test: build aosp_mips-eng
Test: m ART_DEFAULT_GC_TYPE=SS test-art-target-host-gtest-oat_test
Test: Run ART test suite on host and Nexus 9.
Bug: 20323084
Bug: 30627598

This reverts commit 5f926055cb88089d8ca27243f35a9dfd89d981f0.

Change-Id: I07fa2278d82b8eb64964c9a4b66cb93726ccda6b
diff --git a/compiler/driver/compiled_method_storage_test.cc b/compiler/driver/compiled_method_storage_test.cc
index 5063d71..b72d0ac 100644
--- a/compiler/driver/compiled_method_storage_test.cc
+++ b/compiler/driver/compiled_method_storage_test.cc
@@ -32,8 +32,6 @@
                         Compiler::kOptimizing,
                         /* instruction_set_ */ kNone,
                         /* instruction_set_features */ nullptr,
-                        /* boot_image */ false,
-                        /* app_image */ false,
                         /* image_classes */ nullptr,
                         /* compiled_classes */ nullptr,
                         /* compiled_methods */ nullptr,
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 2ad30ee..6cca397 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -264,8 +264,6 @@
     Compiler::Kind compiler_kind,
     InstructionSet instruction_set,
     const InstructionSetFeatures* instruction_set_features,
-    bool boot_image,
-    bool app_image,
     std::unordered_set<std::string>* image_classes,
     std::unordered_set<std::string>* compiled_classes,
     std::unordered_set<std::string>* compiled_methods,
@@ -286,8 +284,6 @@
       compiled_methods_lock_("compiled method lock"),
       compiled_methods_(MethodTable::key_compare()),
       non_relative_linker_patch_count_(0u),
-      boot_image_(boot_image),
-      app_image_(app_image),
       image_classes_(image_classes),
       classes_to_compile_(compiled_classes),
       methods_to_compile_(compiled_methods),
@@ -313,7 +309,7 @@
   if (compiler_options->VerifyOnlyProfile()) {
     CHECK(profile_compilation_info_ != nullptr) << "Requires profile";
   }
-  if (boot_image_) {
+  if (GetCompilerOptions().IsBootImage()) {
     CHECK(image_classes_.get() != nullptr) << "Expected image classes for boot image";
   }
 }
@@ -405,7 +401,7 @@
   // 3) Attempt to verify all classes
   // 4) Attempt to initialize image classes, and trivially initialized classes
   PreCompile(class_loader, dex_files, timings);
-  if (IsBootImage()) {
+  if (GetCompilerOptions().IsBootImage()) {
     // We don't need to setup the intrinsics for non boot image compilation, as
     // those compilations will pick up a boot image that have the ArtMethod already
     // set with the intrinsics flag.
@@ -899,7 +895,7 @@
     return;
   }
 
-  if (GetCompilerOptions().IsForceDeterminism() && IsBootImage()) {
+  if (GetCompilerOptions().IsForceDeterminism() && GetCompilerOptions().IsBootImage()) {
     // Resolve strings from const-string. Do this now to have a deterministic image.
     ResolveConstStrings(this, dex_files, timings);
     VLOG(compiler) << "Resolve const-strings: " << GetMemoryUsageString(false);
@@ -927,7 +923,7 @@
   }
   // No set of image classes, assume we include all the classes.
   // NOTE: Currently only reachable from InitImageMethodVisitor for the app image case.
-  return !IsBootImage();
+  return !GetCompilerOptions().IsBootImage();
 }
 
 bool CompilerDriver::IsClassToCompile(const char* descriptor) const {
@@ -1051,7 +1047,7 @@
 // Make a list of descriptors for classes to include in the image
 void CompilerDriver::LoadImageClasses(TimingLogger* timings) {
   CHECK(timings != nullptr);
-  if (!IsBootImage()) {
+  if (!GetCompilerOptions().IsBootImage()) {
     return;
   }
 
@@ -1279,7 +1275,7 @@
 };
 
 void CompilerDriver::UpdateImageClasses(TimingLogger* timings) {
-  if (IsBootImage()) {
+  if (GetCompilerOptions().IsBootImage()) {
     TimingLogger::ScopedTiming t("UpdateImageClasses", timings);
 
     Runtime* runtime = Runtime::Current();
@@ -1306,7 +1302,7 @@
     // Having the klass reference here implies that the klass is already loaded.
     return true;
   }
-  if (!IsBootImage()) {
+  if (!GetCompilerOptions().IsBootImage()) {
     // Assume loaded only if klass is in the boot image. App classes cannot be assumed
     // loaded because we don't even know what class loader will be used to load them.
     bool class_in_image = runtime->GetHeap()->FindSpaceFromObject(klass, false)->IsImageSpace();
@@ -1496,7 +1492,7 @@
 
   if (!use_dex_cache && force_relocations) {
     bool is_in_image;
-    if (IsBootImage()) {
+    if (GetCompilerOptions().IsBootImage()) {
       is_in_image = IsImageClass(method->GetDeclaringClassDescriptor());
     } else {
       is_in_image = instruction_set_ != kX86 && instruction_set_ != kX86_64 &&
@@ -1895,7 +1891,7 @@
 
   ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, dex_files,
                                      thread_pool);
-  if (IsBootImage()) {
+  if (GetCompilerOptions().IsBootImage()) {
     // For images we resolve all types, such as array, whereas for applications just those with
     // classdefs are resolved by ResolveClassFieldsAndMethods.
     TimingLogger::ScopedTiming t("Resolve Types", timings);
@@ -2005,7 +2001,7 @@
       // It is *very* problematic if there are verification errors in the boot classpath. For example,
       // we rely on things working OK without verification when the decryption dialog is brought up.
       // So abort in a debug build if we find this violated.
-      DCHECK(!manager_->GetCompiler()->IsBootImage() || klass->IsVerified())
+      DCHECK(!manager_->GetCompiler()->GetCompilerOptions().IsBootImage() || klass->IsVerified())
           << "Boot classpath class " << PrettyClass(klass.Get()) << " failed to fully verify.";
     }
     soa.Self()->AssertNoPendingException();
@@ -2136,7 +2132,8 @@
           if (!klass->IsInitialized()) {
             // We need to initialize static fields, we only do this for image classes that aren't
             // marked with the $NoPreloadHolder (which implies this should not be initialized early).
-            bool can_init_static_fields = manager_->GetCompiler()->IsBootImage() &&
+            bool can_init_static_fields =
+                manager_->GetCompiler()->GetCompilerOptions().IsBootImage() &&
                 manager_->GetCompiler()->IsImageClass(descriptor) &&
                 !StringPiece(descriptor).ends_with("$NoPreloadHolder;");
             if (can_init_static_fields) {
@@ -2208,7 +2205,7 @@
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   ParallelCompilationManager context(class_linker, jni_class_loader, this, &dex_file, dex_files,
                                      init_thread_pool);
-  if (IsBootImage()) {
+  if (GetCompilerOptions().IsBootImage()) {
     // TODO: remove this when transactional mode supports multithreading.
     init_thread_count = 1U;
   }
@@ -2262,7 +2259,7 @@
     CHECK(dex_file != nullptr);
     InitializeClasses(class_loader, *dex_file, dex_files, timings);
   }
-  if (boot_image_ || app_image_) {
+  if (GetCompilerOptions().IsBootImage() || GetCompilerOptions().IsAppImage()) {
     // Make sure that we call EnsureIntiailized on all the array classes to call
     // SetVerificationAttempted so that the access flags are set. If we do not do this they get
     // changed at runtime resulting in more dirty image pages.
@@ -2272,7 +2269,7 @@
     InitializeArrayClassesAndCreateConflictTablesVisitor visitor;
     Runtime::Current()->GetClassLinker()->VisitClassesWithoutClassesLock(&visitor);
   }
-  if (IsBootImage()) {
+  if (GetCompilerOptions().IsBootImage()) {
     // Prune garbage objects created during aborted transactions.
     Runtime::Current()->GetHeap()->CollectGarbage(true);
   }
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index fc63df1..9a4dd85 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -90,8 +90,6 @@
                  Compiler::Kind compiler_kind,
                  InstructionSet instruction_set,
                  const InstructionSetFeatures* instruction_set_features,
-                 bool boot_image,
-                 bool app_image,
                  std::unordered_set<std::string>* image_classes,
                  std::unordered_set<std::string>* compiled_classes,
                  std::unordered_set<std::string>* compiled_methods,
@@ -147,11 +145,6 @@
     return compiler_.get();
   }
 
-  // Are we compiling and creating an image file?
-  bool IsBootImage() const {
-    return boot_image_;
-  }
-
   const std::unordered_set<std::string>* GetImageClasses() const {
     return image_classes_.get();
   }
@@ -527,9 +520,6 @@
   // in the .oat_patches ELF section if requested in the compiler options.
   size_t non_relative_linker_patch_count_ GUARDED_BY(compiled_methods_lock_);
 
-  const bool boot_image_;
-  const bool app_image_;
-
   // If image_ is true, specifies the classes that will be included in the image.
   // Note if image_classes_ is null, all classes are included in the image.
   std::unique_ptr<std::unordered_set<std::string>> image_classes_;
diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc
index 30ba8c9..cbcc169 100644
--- a/compiler/driver/compiler_options.cc
+++ b/compiler/driver/compiler_options.cc
@@ -30,6 +30,8 @@
       inline_depth_limit_(kUnsetInlineDepthLimit),
       inline_max_code_units_(kUnsetInlineMaxCodeUnits),
       no_inline_from_(nullptr),
+      boot_image_(false),
+      app_image_(false),
       include_patch_information_(kDefaultIncludePatchInformation),
       top_k_profile_threshold_(kDefaultTopKProfileThreshold),
       debuggable_(false),
@@ -78,34 +80,35 @@
                                  bool dump_cfg_append,
                                  bool force_determinism,
                                  RegisterAllocator::Strategy regalloc_strategy,
-                                 const std::vector<std::string>* passes_to_run
-                                 ) :  // NOLINT(whitespace/parens)
-    compiler_filter_(compiler_filter),
-    huge_method_threshold_(huge_method_threshold),
-    large_method_threshold_(large_method_threshold),
-    small_method_threshold_(small_method_threshold),
-    tiny_method_threshold_(tiny_method_threshold),
-    num_dex_methods_threshold_(num_dex_methods_threshold),
-    inline_depth_limit_(inline_depth_limit),
-    inline_max_code_units_(inline_max_code_units),
-    no_inline_from_(no_inline_from),
-    include_patch_information_(include_patch_information),
-    top_k_profile_threshold_(top_k_profile_threshold),
-    debuggable_(debuggable),
-    generate_debug_info_(generate_debug_info),
-    generate_mini_debug_info_(kDefaultGenerateMiniDebugInfo),
-    implicit_null_checks_(implicit_null_checks),
-    implicit_so_checks_(implicit_so_checks),
-    implicit_suspend_checks_(implicit_suspend_checks),
-    compile_pic_(compile_pic),
-    verbose_methods_(verbose_methods),
-    abort_on_hard_verifier_failure_(abort_on_hard_verifier_failure),
-    init_failure_output_(init_failure_output),
-    dump_cfg_file_name_(dump_cfg_file_name),
-    dump_cfg_append_(dump_cfg_append),
-    force_determinism_(force_determinism),
-    register_allocation_strategy_(regalloc_strategy),
-    passes_to_run_(passes_to_run) {
+                                 const std::vector<std::string>* passes_to_run)
+    : compiler_filter_(compiler_filter),
+      huge_method_threshold_(huge_method_threshold),
+      large_method_threshold_(large_method_threshold),
+      small_method_threshold_(small_method_threshold),
+      tiny_method_threshold_(tiny_method_threshold),
+      num_dex_methods_threshold_(num_dex_methods_threshold),
+      inline_depth_limit_(inline_depth_limit),
+      inline_max_code_units_(inline_max_code_units),
+      no_inline_from_(no_inline_from),
+      boot_image_(false),
+      app_image_(false),
+      include_patch_information_(include_patch_information),
+      top_k_profile_threshold_(top_k_profile_threshold),
+      debuggable_(debuggable),
+      generate_debug_info_(generate_debug_info),
+      generate_mini_debug_info_(kDefaultGenerateMiniDebugInfo),
+      implicit_null_checks_(implicit_null_checks),
+      implicit_so_checks_(implicit_so_checks),
+      implicit_suspend_checks_(implicit_suspend_checks),
+      compile_pic_(compile_pic),
+      verbose_methods_(verbose_methods),
+      abort_on_hard_verifier_failure_(abort_on_hard_verifier_failure),
+      init_failure_output_(init_failure_output),
+      dump_cfg_file_name_(dump_cfg_file_name),
+      dump_cfg_append_(dump_cfg_append),
+      force_determinism_(force_determinism),
+      register_allocation_strategy_(regalloc_strategy),
+      passes_to_run_(passes_to_run) {
 }
 
 void CompilerOptions::ParseHugeMethodMax(const StringPiece& option, UsageFn Usage) {
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index abc58d7..8e4a775 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -203,6 +203,14 @@
     return include_patch_information_;
   }
 
+  bool IsBootImage() const {
+    return boot_image_;
+  }
+
+  bool IsAppImage() const {
+    return app_image_;
+  }
+
   // Should the code be compiled as position independent?
   bool GetCompilePic() const {
     return compile_pic_;
@@ -281,6 +289,8 @@
   // prefer vector<> over a lookup-oriented container, such as set<>.
   const std::vector<const DexFile*>* no_inline_from_;
 
+  bool boot_image_;
+  bool app_image_;
   bool include_patch_information_;
   // When using a profile file only the top K% of the profiled samples will be compiled.
   double top_k_profile_threshold_;
@@ -305,7 +315,7 @@
   std::string dump_cfg_file_name_;
   bool dump_cfg_append_;
 
-  // Whether the compiler should trade performance for determinism to guarantee exactly reproducable
+  // Whether the compiler should trade performance for determinism to guarantee exactly reproducible
   // outcomes.
   bool force_determinism_;
 
@@ -320,6 +330,7 @@
   const std::vector<std::string>* passes_to_run_;
 
   friend class Dex2Oat;
+  friend class CommonCompilerTest;
 
   DISALLOW_COPY_AND_ASSIGN(CompilerOptions);
 };