Revert^4 "Add the mainline framework boot image extensio...

Revert submission 2465993-boot-image-mainline-revert

Reason for revert: Relanding the changes

Reverted changes: /q/submissionid:2465993-boot-image-mainline-revert

Change-Id: I5dd81f74c08faccd1643c2b01826e6a76cbb10c5
diff --git a/dex2oat/driver/compiler_driver.cc b/dex2oat/driver/compiler_driver.cc
index 4f85140..3ad696b 100644
--- a/dex2oat/driver/compiler_driver.cc
+++ b/dex2oat/driver/compiler_driver.cc
@@ -2183,9 +2183,9 @@
         // fields. Limit the max number of encoded fields.
         if (!klass->IsInitialized() &&
             (is_app_image || is_boot_image || is_boot_image_extension) &&
-            try_initialize_with_superclasses &&
-            !too_many_encoded_fields &&
-            compiler_options.IsImageClass(descriptor)) {
+            try_initialize_with_superclasses && !too_many_encoded_fields &&
+            compiler_options.IsImageClass(descriptor) &&
+            compiler_options.IsAotCompilationEnabled()) {
           bool can_init_static_fields = false;
           if (is_boot_image || is_boot_image_extension) {
             // We need to initialize static fields, we only do this for image classes that aren't
diff --git a/dexoptanalyzer/dexoptanalyzer.cc b/dexoptanalyzer/dexoptanalyzer.cc
index ef43157..b182f68 100644
--- a/dexoptanalyzer/dexoptanalyzer.cc
+++ b/dexoptanalyzer/dexoptanalyzer.cc
@@ -239,11 +239,16 @@
       // If we don't receive the image, try to use the default one.
       // Tests may specify a different image (e.g. core image).
       std::string error_msg;
-      image_ = GetDefaultBootImageLocation(&error_msg);
-
+      std::string android_root = GetAndroidRootSafe(&error_msg);
+      if (android_root.empty()) {
+        LOG(ERROR) << error_msg;
+        Usage("--image unspecified and ANDROID_ROOT not set.");
+      }
+      image_ = GetDefaultBootImageLocationSafe(
+          android_root, /*deny_art_apex_data_files=*/false, &error_msg);
       if (image_.empty()) {
         LOG(ERROR) << error_msg;
-        Usage("--image unspecified and ANDROID_ROOT not set or image file does not exist.");
+        Usage("--image unspecified and failed to get default boot image location.");
       }
     }
   }
diff --git a/libartbase/base/file_utils.cc b/libartbase/base/file_utils.cc
index 2396289..d2afbcc 100644
--- a/libartbase/base/file_utils.cc
+++ b/libartbase/base/file_utils.cc
@@ -40,6 +40,7 @@
 
 #include <memory>
 #include <sstream>
+#include <vector>
 
 #include "android-base/file.h"
 #include "android-base/logging.h"
@@ -50,6 +51,7 @@
 #include "base/os.h"
 #include "base/stl_util.h"
 #include "base/unix_file/fd_file.h"
+#include "base/utils.h"
 
 #if defined(__APPLE__)
 #include <crt_externs.h>
@@ -78,6 +80,7 @@
 static constexpr const char* kAndroidI18nRootEnvVar = "ANDROID_I18N_ROOT";
 static constexpr const char* kApexDefaultPath = "/apex/";
 static constexpr const char* kArtApexDataEnvVar = "ART_APEX_DATA";
+static constexpr const char* kBootImageStem = "boot";
 
 // Get the "root" directory containing the "lib" directory where this instance
 // of the libartbase library (which contains `GetRootContainingLibartbase`) is
@@ -298,10 +301,82 @@
   return GetPrebuiltPrimaryBootImageDir(android_root);
 }
 
-std::string GetDefaultBootImageLocation(const std::string& android_root,
-                                        bool deny_art_apex_data_files) {
+std::string GetFirstMainlineFrameworkLibraryFilename(std::string* error_msg) {
+  const char* env_bcp = getenv("BOOTCLASSPATH");
+  const char* env_dex2oat_bcp = getenv("DEX2OATBOOTCLASSPATH");
+  if (env_bcp == nullptr || env_dex2oat_bcp == nullptr) {
+    *error_msg = "BOOTCLASSPATH and DEX2OATBOOTCLASSPATH must not be empty";
+    return "";
+  }
+
+  // DEX2OATBOOTCLASSPATH contains core libraries and framework libraries. We used to only compile
+  // those libraries. Now we compile mainline framework libraries as well, and we have repurposed
+  // DEX2OATBOOTCLASSPATH to indicate the separation between mainline framework libraries and other
+  // libraries.
+  std::string_view mainline_bcp(env_bcp);
+  if (!android::base::ConsumePrefix(&mainline_bcp, env_dex2oat_bcp)) {
+    *error_msg = "DEX2OATBOOTCLASSPATH must be a prefix of BOOTCLASSPATH";
+    return "";
+  }
+
+  std::vector<std::string_view> mainline_bcp_jars;
+  Split(mainline_bcp, ':', &mainline_bcp_jars);
+  if (mainline_bcp_jars.empty()) {
+    *error_msg = "No mainline framework library found";
+    return "";
+  }
+
+  return std::string(mainline_bcp_jars[0]);
+}
+
+static std::string GetFirstMainlineFrameworkLibraryName(std::string* error_msg) {
+  std::string filename = GetFirstMainlineFrameworkLibraryFilename(error_msg);
+  if (filename.empty()) {
+    return "";
+  }
+
+  std::string jar_name = android::base::Basename(filename);
+
+  std::string_view library_name(jar_name);
+  if (!android::base::ConsumeSuffix(&library_name, ".jar")) {
+    *error_msg = "Invalid mainline framework jar: " + jar_name;
+    return "";
+  }
+
+  return std::string(library_name);
+}
+
+// Returns true when no error occurs, even if the extension doesn't exist.
+static bool MaybeAppendBootImageMainlineExtension(const std::string& android_root,
+                                                  /*inout*/ std::string* location,
+                                                  /*out*/ std::string* error_msg) {
+  if (!kIsTargetAndroid) {
+    return true;
+  }
+  // Due to how the runtime determines the mapping between boot images and bootclasspath jars, the
+  // name of the boot image extension must be in the format of
+  // `<primary-boot-image-stem>-<first-library-name>.art`.
+  std::string library_name = GetFirstMainlineFrameworkLibraryName(error_msg);
+  if (library_name.empty()) {
+    return false;
+  }
+  std::string mainline_extension_location = StringPrintf(
+      "%s/framework/%s-%s.art", android_root.c_str(), kBootImageStem, library_name.c_str());
+  std::string mainline_extension_path =
+      GetSystemImageFilename(mainline_extension_location.c_str(), kRuntimeISA);
+  if (!OS::FileExists(mainline_extension_path.c_str(), /*check_file_type=*/true)) {
+    // This is expected when the ART module is preloaded on an old source tree that doesn't
+    // dexpreopt mainline BCP jars, so it shouldn't be considered as an error.
+    return true;
+  }
+  *location += ":" + mainline_extension_location;
+  return true;
+}
+
+std::string GetDefaultBootImageLocationSafe(const std::string& android_root,
+                                            bool deny_art_apex_data_files,
+                                            std::string* error_msg) {
   constexpr static const char* kEtcBootImageProf = "etc/boot-image.prof";
-  constexpr static const char* kBootImageStem = "boot";
   constexpr static const char* kMinimalBootImageStem = "boot_minimal";
 
   // If an update for the ART module has been been installed, a single boot image for the entire
@@ -347,28 +422,37 @@
       PLOG(ERROR) << "Minimal boot image check failed, could not stat: " << boot_image_filename;
     }
   }
-  // Boot image consists of two parts:
-  //  - the primary boot image (contains the Core Libraries)
-  //  - the boot image extensions (contains framework libraries)
-  // Typically "/apex/com.android.art/javalib/boot.art!/apex/com.android.art/etc/boot-image.prof:
-  // /system/framework/boot-framework.art!/system/etc/boot-image.prof".
-  return StringPrintf("%s/%s.art!%s/%s:%s/framework/%s-framework.art!%s/%s",
-                      GetPrebuiltPrimaryBootImageDir(android_root).c_str(),
-                      kBootImageStem,
-                      kAndroidArtApexDefaultPath,
-                      kEtcBootImageProf,
-                      android_root.c_str(),
-                      kBootImageStem,
-                      android_root.c_str(),
-                      kEtcBootImageProf);
-}
 
-std::string GetDefaultBootImageLocation(std::string* error_msg) {
-  std::string android_root = GetAndroidRootSafe(error_msg);
-  if (android_root.empty()) {
+  // Boot image consists of three parts:
+  //  - the primary boot image (contains the Core Libraries)
+  //  - the boot image framework extension (contains framework libraries)
+  //  - the boot image mainline extension (contains mainline framework libraries)
+  // Typically "/system/framework/boot.art!/apex/com.android.art/etc/boot-image.prof:
+  // /system/framework/boot-framework.art!/system/etc/boot-image.prof:
+  // /system/framework/boot-framework-adservices.art".
+
+  std::string location = StringPrintf("%s/%s.art!%s/%s:%s/framework/%s-framework.art!%s/%s",
+                                      GetPrebuiltPrimaryBootImageDir(android_root).c_str(),
+                                      kBootImageStem,
+                                      kAndroidArtApexDefaultPath,
+                                      kEtcBootImageProf,
+                                      android_root.c_str(),
+                                      kBootImageStem,
+                                      android_root.c_str(),
+                                      kEtcBootImageProf);
+  if (!MaybeAppendBootImageMainlineExtension(android_root, &location, error_msg)) {
     return "";
   }
-  return GetDefaultBootImageLocation(android_root, /*deny_art_apex_data_files=*/false);
+  return location;
+}
+
+std::string GetDefaultBootImageLocation(const std::string& android_root,
+                                        bool deny_art_apex_data_files) {
+  std::string error_msg;
+  std::string location =
+      GetDefaultBootImageLocationSafe(android_root, deny_art_apex_data_files, &error_msg);
+  CHECK(!location.empty()) << error_msg;
+  return location;
 }
 
 std::string GetJitZygoteBootImageLocation() {
diff --git a/libartbase/base/file_utils.h b/libartbase/base/file_utils.h
index f539f5f..faec95e 100644
--- a/libartbase/base/file_utils.h
+++ b/libartbase/base/file_utils.h
@@ -78,11 +78,18 @@
 // generated at build time).
 std::string GetPrebuiltPrimaryBootImageDir();
 
-// Returns the default boot image location (ANDROID_ROOT/framework/boot.art).
-// Returns an empty string if ANDROID_ROOT is not set.
-std::string GetDefaultBootImageLocation(std::string* error_msg);
+// Returns the filename of the first mainline framework library.
+std::string GetFirstMainlineFrameworkLibraryFilename(std::string* error_msg);
 
 // Returns the default boot image location, based on the passed `android_root`.
+// Returns an empty string if an error occurs.
+// The default boot image location can only be used with the default bootclasspath (the value of the
+// BOOTCLASSPATH environment variable).
+std::string GetDefaultBootImageLocationSafe(const std::string& android_root,
+                                            bool deny_art_apex_data_files,
+                                            std::string* error_msg);
+
+// Same as above, but fails if an error occurs.
 std::string GetDefaultBootImageLocation(const std::string& android_root,
                                         bool deny_art_apex_data_files);
 
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 5994410..092d652 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -714,35 +714,20 @@
 }
 
 /**
- * Update entrypoints (native and Java) of methods before the first fork. This
+ * Update entrypoints of methods before the first fork. This
  * helps sharing pages where ArtMethods are allocated between the zygote and
  * forked apps.
  */
 class UpdateMethodsPreFirstForkVisitor : public ClassVisitor {
  public:
-  UpdateMethodsPreFirstForkVisitor(Thread* self, ClassLinker* class_linker)
-      : vm_(down_cast<JNIEnvExt*>(self->GetJniEnv())->GetVm()),
-        self_(self),
-        class_linker_(class_linker),
+  explicit UpdateMethodsPreFirstForkVisitor(ClassLinker* class_linker)
+      : class_linker_(class_linker),
         can_use_nterp_(interpreter::CanRuntimeUseNterp()) {}
 
   bool operator()(ObjPtr<mirror::Class> klass) override REQUIRES_SHARED(Locks::mutator_lock_) {
     bool is_initialized = klass->IsVisiblyInitialized();
     for (ArtMethod& method : klass->GetDeclaredMethods(kRuntimePointerSize)) {
-      if (is_initialized || !method.NeedsClinitCheckBeforeCall()) {
-        if (method.IsNative()) {
-          const void* existing = method.GetEntryPointFromJni();
-          if (method.IsCriticalNative()
-                  ? class_linker_->IsJniDlsymLookupCriticalStub(existing)
-                  : class_linker_->IsJniDlsymLookupStub(existing)) {
-            const void* native_code =
-                vm_->FindCodeForNativeMethod(&method, /*error_msg=*/ nullptr, /*can_suspend=*/ false);
-            if (native_code != nullptr) {
-              class_linker_->RegisterNative(self_, &method, native_code);
-            }
-          }
-        }
-      } else if (can_use_nterp_) {
+      if (!is_initialized && method.NeedsClinitCheckBeforeCall() && can_use_nterp_) {
         const void* existing = method.GetEntryPointFromQuickCompiledCode();
         if (class_linker_->IsQuickResolutionStub(existing) && CanMethodUseNterp(&method)) {
           method.SetEntryPointFromQuickCompiledCode(interpreter::GetNterpWithClinitEntryPoint());
@@ -753,8 +738,6 @@
   }
 
  private:
-  JavaVMExt* const vm_;
-  Thread* const self_;
   ClassLinker* const class_linker_;
   const bool can_use_nterp_;
 
@@ -775,7 +758,7 @@
     class_linker_->MakeInitializedClassesVisiblyInitialized(self, /*wait=*/ true);
 
     ScopedObjectAccess soa(self);
-    UpdateMethodsPreFirstForkVisitor visitor(self, class_linker_);
+    UpdateMethodsPreFirstForkVisitor visitor(class_linker_);
     class_linker_->VisitClasses(&visitor);
   }
   heap_->PreZygoteFork();
diff --git a/test/dexpreopt/dexpreopt_test.cc b/test/dexpreopt/dexpreopt_test.cc
index 55593ea..9641e0a 100644
--- a/test/dexpreopt/dexpreopt_test.cc
+++ b/test/dexpreopt/dexpreopt_test.cc
@@ -46,7 +46,8 @@
 
 namespace art {
 
-using ::testing::IsSubsetOf;
+using ::android::base::Error;
+using ::testing::IsSupersetOf;
 
 constexpr const char* kZygote32 = "zygote";
 constexpr const char* kZygote64 = "zygote64";
@@ -99,6 +100,12 @@
   if (jars.empty()) {
     return Errorf("Environment variable `DEX2OATBOOTCLASSPATH` is not defined or empty");
   }
+  std::string error_msg;
+  std::string first_mainline_jar = GetFirstMainlineFrameworkLibraryFilename(&error_msg);
+  if (first_mainline_jar.empty()) {
+    return Error() << error_msg;
+  }
+  jars.push_back(std::move(first_mainline_jar));
   std::string art_root = GetArtRoot();
   std::string android_root = GetAndroidRoot();
   std::vector<std::string> artifacts;
@@ -218,7 +225,7 @@
         GetZygoteMappedOatFiles(zygote_name);
     ASSERT_RESULT_OK(mapped_oat_files);
 
-    EXPECT_THAT(expected_artifacts.value(), IsSubsetOf(mapped_oat_files.value()));
+    EXPECT_THAT(mapped_oat_files.value(), IsSupersetOf(expected_artifacts.value()));
   }
 }
 
@@ -236,7 +243,7 @@
       GetSystemServerArtifactsMappedOdexes();
   ASSERT_RESULT_OK(mapped_odexes);
 
-  EXPECT_THAT(expected_artifacts.value(), IsSubsetOf(mapped_odexes.value()));
+  EXPECT_THAT(mapped_odexes.value(), IsSupersetOf(expected_artifacts.value()));
 }
 
 }  // namespace art
diff --git a/test/generate-boot-image/generate-boot-image.cc b/test/generate-boot-image/generate-boot-image.cc
index 475bfb1..f22bad4 100644
--- a/test/generate-boot-image/generate-boot-image.cc
+++ b/test/generate-boot-image/generate-boot-image.cc
@@ -109,8 +109,9 @@
   android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
 
   std::string dir = "";
-  // Set the compiler filter to `verify` by default to make test preparation faster.
-  std::string compiler_filter = "verify";
+  // Set the compiler filter to `speed-profile` by default to make test preparation
+  // faster and behave like normal boot image generation.
+  std::string compiler_filter = "speed-profile";
   for (int i = 1; i < argc; i++) {
     std::string_view arg{argv[i]};
     if (android::base::ConsumePrefix(&arg, "--output-dir=")) {