Re-enable app image loader for userfaultfd.

Just disable dex cache generation for now, and make sure the image works with
the right GC.

Test: test.py
Bug: 260557058
Bug: 270936884
Change-Id: Iceae4f8a615d2f1e740936c05b121d91915b2519
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 880addb..224b928 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2098,6 +2098,10 @@
         *error_msg = "Checksums count does not match";
         return false;
       }
+      if (oat_header->IsConcurrentCopying() != gUseReadBarrier) {
+        *error_msg = "GCs do not match";
+        return false;
+      }
 
       // Check if the dex checksums match the dex files that we just loaded.
       uint32_t* checksums = reinterpret_cast<uint32_t*>(
diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc
index dee5e23..32de174 100644
--- a/runtime/oat_file_manager.cc
+++ b/runtime/oat_file_manager.cc
@@ -67,7 +67,7 @@
 static constexpr bool kEnableAppImage = true;
 
 // If true, we attempt to load an app image generated by the runtime.
-static const bool kEnableRuntimeAppImage = !gUseUserfaultfd;
+static const bool kEnableRuntimeAppImage = true;
 
 const OatFile* OatFileManager::RegisterOatFile(std::unique_ptr<const OatFile> oat_file,
                                                bool in_memory) {
diff --git a/runtime/runtime_image.cc b/runtime/runtime_image.cc
index 5bd238c..80c9d3a 100644
--- a/runtime/runtime_image.cc
+++ b/runtime/runtime_image.cc
@@ -55,8 +55,6 @@
 
 using android::base::StringPrintf;
 
-static constexpr bool kEmitDexCacheArrays = true;
-
 /**
  * The native data structures that we store in the image.
  */
@@ -102,7 +100,6 @@
     intern_table_(InternStringHash(this), InternStringEquals(this)),
     class_table_(ClassDescriptorHash(this), ClassDescriptorEquals()) {}
 
-
   bool Generate(std::string* error_msg) {
     if (!WriteObjects(error_msg)) {
       return false;
@@ -1088,6 +1085,8 @@
                         runtime->GetBootClassPathChecksums());
     key_value_store.Put(OatHeader::kClassPathKey,
                         oat_dex_file->GetOatFile()->GetClassLoaderContext());
+    key_value_store.Put(OatHeader::kConcurrentCopying,
+                        gUseReadBarrier ? OatHeader::kTrueValue : OatHeader::kFalseValue);
 
     std::unique_ptr<const InstructionSetFeatures> isa_features =
         InstructionSetFeatures::FromCppDefines();
@@ -1241,6 +1240,11 @@
 
     return reinterpret_cast<mirror::GcRootArray<T>*>(data.data() + offset);
   }
+  static bool EmitDexCacheArrays() {
+    // We need to treat dex cache arrays specially in an image for userfaultfd.
+    // Disable for now. See b/270936884.
+    return !gUseUserfaultfd;
+  }
 
   uint32_t CopyDexCache(ObjPtr<mirror::DexCache> cache) REQUIRES_SHARED(Locks::mutator_lock_) {
     auto it = dex_caches_.find(cache->GetDexFile());
@@ -1254,7 +1258,7 @@
     reinterpret_cast<mirror::DexCache*>(copy)->ResetNativeArrays();
     reinterpret_cast<mirror::DexCache*>(copy)->SetDexFile(nullptr);
 
-    if (!kEmitDexCacheArrays) {
+    if (!EmitDexCacheArrays()) {
       return offset;
     }
 
diff --git a/test/knownfailures.json b/test/knownfailures.json
index d996005..cb9c890 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -1557,11 +1557,5 @@
         "env_vars": {"ART_TEST_DEBUG_GC": "true"},
         "bug": "b/264844668",
         "description": ["Test timing out on debug gc."]
-    },
-    {
-        "tests": ["845-data-image", "846-multidex-data-image"],
-        "env_vars": {"ART_USE_READ_BARRIER": "false"},
-        "bug": "b/270936884",
-        "description": ["Fails with CMC."]
     }
 ]