Initialize intrinsics in dex2oat.

When compiling without a boot image, we used to not initialize them.
Also adjust run-test with --no-image to not pass an image to dex2oat.

Test: test.py --no-image --optimizing
Bug: 220702556
Change-Id: Ia0f26f35ee4ad24988e067c4c7c53a0acf98cf51
diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc
index 16c3029..f2d2b45 100644
--- a/compiler/optimizing/intrinsics.cc
+++ b/compiler/optimizing/intrinsics.cc
@@ -156,7 +156,6 @@
   }
   if (!compiler_options.IsBootImage() &&
       Runtime::Current()->GetHeap()->GetBootImageSpaces().empty()) {
-    DCHECK(compiler_options.IsJitCompiler());
     return false;  // Running without boot image, cannot use required boot image objects.
   }
   return true;
diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc
index 1130f3a..c8fccfb 100644
--- a/compiler/optimizing/intrinsics_arm64.cc
+++ b/compiler/optimizing/intrinsics_arm64.cc
@@ -4514,7 +4514,6 @@
     bool boot_image_available =
         codegen->GetCompilerOptions().IsBootImage() ||
         !Runtime::Current()->GetHeap()->GetBootImageSpaces().empty();
-    DCHECK(boot_image_available || codegen->GetCompilerOptions().IsJitCompiler());
     bool can_be_view = (DataType::Size(value_type) != 1u) && boot_image_available;
     vixl::aarch64::Label* slow_path_label =
         can_be_view ? slow_path->GetByteArrayViewCheckLabel() : slow_path->GetEntryLabel();
diff --git a/compiler/optimizing/intrinsics_arm_vixl.cc b/compiler/optimizing/intrinsics_arm_vixl.cc
index aa4c139..255f605 100644
--- a/compiler/optimizing/intrinsics_arm_vixl.cc
+++ b/compiler/optimizing/intrinsics_arm_vixl.cc
@@ -4234,7 +4234,6 @@
   bool boot_image_available =
       codegen->GetCompilerOptions().IsBootImage() ||
       !Runtime::Current()->GetHeap()->GetBootImageSpaces().empty();
-  DCHECK(boot_image_available || codegen->GetCompilerOptions().IsJitCompiler());
   bool can_be_view =
       ((value_type != DataType::Type::kReference) && (DataType::Size(value_type) != 1u)) &&
       boot_image_available;
diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc
index c65e467..ae53528 100644
--- a/compiler/optimizing/intrinsics_x86_64.cc
+++ b/compiler/optimizing/intrinsics_x86_64.cc
@@ -3656,7 +3656,6 @@
     bool boot_image_available =
         codegen->GetCompilerOptions().IsBootImage() ||
         !Runtime::Current()->GetHeap()->GetBootImageSpaces().empty();
-    DCHECK(boot_image_available || codegen->GetCompilerOptions().IsJitCompiler());
     bool can_be_view = (DataType::Size(value_type) != 1u) && boot_image_available;
     slow_path_label =
         can_be_view ? slow_path->GetByteArrayViewCheckLabel() : slow_path->GetEntryLabel();
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 4770a37..b90a789 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -101,6 +101,7 @@
 #include "palette/palette.h"
 #include "profile/profile_compilation_info.h"
 #include "runtime.h"
+#include "runtime_intrinsics.h"
 #include "runtime_options.h"
 #include "scoped_thread_state_change-inl.h"
 #include "stream/buffered_output_stream.h"
@@ -1688,13 +1689,6 @@
     }
     // Note that dex2oat won't close the swap_fd_. The compiler driver's swap space will do that.
 
-    // If we're doing the image, override the compiler filter to force full compilation. Must be
-    // done ahead of WellKnownClasses::Init that causes verification.  Note: doesn't force
-    // compilation of class initializers.
-    // Whilst we're in native take the opportunity to initialize well known classes.
-    Thread* self = Thread::Current();
-    WellKnownClasses::Init(self->GetJniEnv());
-
     if (!IsBootImage() && !IsBootImageExtension()) {
       constexpr bool kSaveDexInput = false;
       if (kSaveDexInput) {
@@ -2708,6 +2702,13 @@
     // Runtime::Start, give it away now so that we don't starve GC.
     self->TransitionFromRunnableToSuspended(ThreadState::kNative);
 
+    // Now that we are in native state, initialize well known classes and
+    // intrinsics if we don't have a boot image.
+    WellKnownClasses::Init(self->GetJniEnv());
+    if (IsBootImage() || runtime_->GetHeap()->GetBootImageSpaces().empty()) {
+      InitializeIntrinsics();
+    }
+
     WatchDog::SetRuntime(runtime_.get());
 
     return true;
diff --git a/dex2oat/driver/compiler_driver.cc b/dex2oat/driver/compiler_driver.cc
index 2a0a6a9..d17177c 100644
--- a/dex2oat/driver/compiler_driver.cc
+++ b/dex2oat/driver/compiler_driver.cc
@@ -1044,11 +1044,6 @@
 
   if (GetCompilerOptions().IsBootImage()) {
     AddClassesContainingIntrinsics(image_classes);
-
-    // All intrinsics must be in the primary boot image, so we don't need to setup
-    // the intrinsics for any other compilation, as those compilations will pick up
-    // a boot image that have the ArtMethod already set with the intrinsics flag.
-    InitializeIntrinsics();
   }
 
   // Make a first pass to load all classes explicitly listed in the file
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index a14d386..a48d860 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -60,6 +60,7 @@
 #include "noop_compiler_callbacks.h"
 #include "profile/profile_compilation_info.h"
 #include "runtime-inl.h"
+#include "runtime_intrinsics.h"
 #include "scoped_thread_state_change-inl.h"
 #include "thread.h"
 #include "well_known_classes.h"
@@ -160,8 +161,10 @@
     runtime_->RunRootClinits(soa.Self());
   }
 
-  // We're back in native, take the opportunity to initialize well known classes.
+  // We're back in native, take the opportunity to initialize well known classes and ensure
+  // intrinsics are initialized.
   WellKnownClasses::Init(Thread::Current()->GetJniEnv());
+  InitializeIntrinsics();
 
   // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
   // pool is created by the runtime.
diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar
index 1275743..9a1bdad 100755
--- a/test/etc/run-test-jar
+++ b/test/etc/run-test-jar
@@ -759,14 +759,13 @@
     # We'll abuse a second flag here to test different behavior. If --relocate, use the
     # existing image - relocation will fail as patching is disallowed. If --no-relocate,
     # pass a non-existent image - compilation will fail as dex2oat is disallowed.
-    if [ "${RELOCATE}" = "y" ] ; then
-      DALVIKVM_BOOT_OPT="-Ximage:${BOOT_IMAGE}"
-    else
-      DALVIKVM_BOOT_OPT="-Ximage:/system/non-existent/boot.art"
+    if [ "${RELOCATE}" = "n" ] ; then
+      BOOT_IMAGE="/system/non-existent/boot.art"
     fi
-else
-    DALVIKVM_BOOT_OPT="-Ximage:${BOOT_IMAGE}"
+    # App images cannot be generated without a boot image.
+    APP_IMAGE="n"
 fi
+DALVIKVM_BOOT_OPT="-Ximage:${BOOT_IMAGE}"
 
 if [ "$USE_GDB_DEX2OAT" = "y" ]; then
   if [ "$HOST" = "n" ]; then
diff --git a/test/run-test b/test/run-test
index 96552e6..dccc9f6 100755
--- a/test/run-test
+++ b/test/run-test
@@ -844,7 +844,7 @@
 if [[ "$TEST_NAME" =~ ^[0-9]+-checker- ]] || [ "$dump_cfg" = "true" ]; then
   if [ "$runtime" = "art" -a "$run_optimizing" = "true" ]; then
     # In no-prebuild or no-image mode, the compiler only quickens so disable the checker.
-    if [ "$prebuild_mode" = "yes" -a "$have_image" = "yes" ]; then
+    if [ "$prebuild_mode" = "yes" ]; then
       run_checker="yes"
 
       if [ "$target_mode" = "no" ]; then