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/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
index 2cd0331..4311d19 100644
--- a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
@@ -18,10 +18,15 @@
 #include "callee_save_frame.h"
 #include "entrypoints/entrypoint_utils-inl.h"
 #include "class_linker-inl.h"
+#include "class_table-inl.h"
 #include "dex_file-inl.h"
-#include "gc/accounting/card_table-inl.h"
+#include "gc/heap.h"
+#include "mirror/class-inl.h"
+#include "mirror/class_loader.h"
 #include "mirror/object_array-inl.h"
 #include "mirror/object-inl.h"
+#include "oat_file.h"
+#include "runtime.h"
 
 namespace art {
 
@@ -56,7 +61,20 @@
     REQUIRES_SHARED(Locks::mutator_lock_) {
   ScopedQuickEntrypointChecks sqec(self);
   auto* caller = GetCalleeSaveMethodCaller(self, Runtime::kSaveRefsOnly);
-  return ResolveStringFromCode(caller, string_idx);
+  mirror::String* result = ResolveStringFromCode(caller, string_idx);
+  if (LIKELY(result != nullptr)) {
+    // For AOT code, we need a write barrier for the dex cache that holds the GC roots in the .bss.
+    const DexFile* dex_file = caller->GetDexFile();
+    if (dex_file != nullptr &&
+        dex_file->GetOatDexFile() != nullptr &&
+        !dex_file->GetOatDexFile()->GetOatFile()->GetBssGcRoots().empty()) {
+      mirror::ClassLoader* class_loader = caller->GetDeclaringClass()->GetClassLoader();
+      // Note that we emit the barrier before the compiled code stores the string as GC root.
+      // This is OK as there is no suspend point point in between.
+      Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(class_loader);
+    }
+  }
+  return result;
 }
 
 }  // namespace art