Merge "Fix running some run-tests with -Xjitthreshold:0"
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 8db892b..46d8373 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -371,9 +371,18 @@
   // Is `boot_image_filename` the name of a core image (small boot
   // image used for ART testing only)?
   static bool IsCoreImageFilename(const std::string& boot_image_filename) {
-    // TODO: This is under-approximating...
-    return android::base::EndsWith(boot_image_filename, "core.art")
-        || android::base::EndsWith(boot_image_filename, "core-optimizing.art");
+    // Look for "core.art" or "core-*.art".
+    if (android::base::EndsWith(boot_image_filename, "core.art")) {
+      return true;
+    }
+    if (!android::base::EndsWith(boot_image_filename, ".art")) {
+      return false;
+    }
+    size_t dash_pos = boot_image_filename.find_last_of("-/");
+    if (dash_pos == std::string::npos || boot_image_filename[dash_pos] != '-') {
+      return false;
+    }
+    return (dash_pos >= 4u) && (boot_image_filename.compare(dash_pos - 4u, 4u, "core") == 0);
   }
 
   optimizer::DexToDexCompiler& GetDexToDexCompiler() {
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 4fc7262..8b10a78 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -147,10 +147,11 @@
   //   that this method is actually inlined;
   // - if a method's name contains the substring "$noinline$", do not
   //   inline that method.
-  // We limit this to AOT compilation, as the JIT may or may not inline
+  // We limit the latter to AOT compilation, as the JIT may or may not inline
   // depending on the state of classes at runtime.
-  const bool honor_inlining_directives =
-      IsCompilingWithCoreImage() && Runtime::Current()->IsAotCompiler();
+  const bool honor_noinline_directives = IsCompilingWithCoreImage();
+  const bool honor_inline_directives =
+      honor_noinline_directives && Runtime::Current()->IsAotCompiler();
 
   // Keep a copy of all blocks when starting the visit.
   ArenaVector<HBasicBlock*> blocks = graph_->GetReversePostOrder();
@@ -164,18 +165,19 @@
       HInvoke* call = instruction->AsInvoke();
       // As long as the call is not intrinsified, it is worth trying to inline.
       if (call != nullptr && call->GetIntrinsic() == Intrinsics::kNone) {
-        if (honor_inlining_directives) {
+        if (honor_noinline_directives) {
           // Debugging case: directives in method names control or assert on inlining.
           std::string callee_name = outer_compilation_unit_.GetDexFile()->PrettyMethod(
               call->GetDexMethodIndex(), /* with_signature */ false);
           // Tests prevent inlining by having $noinline$ in their method names.
           if (callee_name.find("$noinline$") == std::string::npos) {
-            if (!TryInline(call)) {
+            if (!TryInline(call) && honor_inline_directives) {
               bool should_have_inlined = (callee_name.find("$inline$") != std::string::npos);
               CHECK(!should_have_inlined) << "Could not inline " << callee_name;
             }
           }
         } else {
+          DCHECK(!honor_inline_directives);
           // Normal case: try to inline.
           TryInline(call);
         }
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index a757960..23cf071 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -717,12 +717,14 @@
 void Jit::MethodEntered(Thread* thread, ArtMethod* method) {
   Runtime* runtime = Runtime::Current();
   if (UNLIKELY(runtime->UseJitCompilation() && runtime->GetJit()->JitAtFirstUse())) {
-    // The compiler requires a ProfilingInfo object.
-    ProfilingInfo::Create(thread,
-                          method->GetInterfaceMethodIfProxy(kRuntimePointerSize),
-                          /* retry_allocation */ true);
-    JitCompileTask compile_task(method, JitCompileTask::kCompile);
-    compile_task.Run(thread);
+    ArtMethod* np_method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize);
+    DCHECK(!np_method->IsNative());
+    if (np_method->IsCompilable()) {
+      // The compiler requires a ProfilingInfo object.
+      ProfilingInfo::Create(thread, np_method, /* retry_allocation */ true);
+      JitCompileTask compile_task(method, JitCompileTask::kCompile);
+      compile_task.Run(thread);
+    }
     return;
   }
 
diff --git a/test/461-get-reference-vreg/get_reference_vreg_jni.cc b/test/461-get-reference-vreg/get_reference_vreg_jni.cc
index b2cad67..7eb3fe5 100644
--- a/test/461-get-reference-vreg/get_reference_vreg_jni.cc
+++ b/test/461-get-reference-vreg/get_reference_vreg_jni.cc
@@ -37,21 +37,21 @@
     ArtMethod* m = GetMethod();
     std::string m_name(m->GetName());
 
-    if (m_name.compare("testThisWithInstanceCall") == 0) {
+    if (m_name.compare("$noinline$testThisWithInstanceCall") == 0) {
       found_method_index_ = 1;
       uint32_t value = 0;
       CHECK(GetVReg(m, 1, kReferenceVReg, &value));
       CHECK_EQ(reinterpret_cast<mirror::Object*>(value), this_value_);
       CHECK_EQ(GetThisObject(), this_value_);
-    } else if (m_name.compare("testThisWithStaticCall") == 0) {
+    } else if (m_name.compare("$noinline$testThisWithStaticCall") == 0) {
       found_method_index_ = 2;
       uint32_t value = 0;
       CHECK(GetVReg(m, 1, kReferenceVReg, &value));
-    } else if (m_name.compare("testParameter") == 0) {
+    } else if (m_name.compare("$noinline$testParameter") == 0) {
       found_method_index_ = 3;
       uint32_t value = 0;
       CHECK(GetVReg(m, 1, kReferenceVReg, &value));
-    } else if (m_name.compare("testObjectInScope") == 0) {
+    } else if (m_name.compare("$noinline$testObjectInScope") == 0) {
       found_method_index_ = 4;
       uint32_t value = 0;
       CHECK(GetVReg(m, 0, kReferenceVReg, &value));
diff --git a/test/461-get-reference-vreg/src/Main.java b/test/461-get-reference-vreg/src/Main.java
index f7d4356..a14b0e9 100644
--- a/test/461-get-reference-vreg/src/Main.java
+++ b/test/461-get-reference-vreg/src/Main.java
@@ -18,19 +18,19 @@
   public Main() {
   }
 
-  int testThisWithInstanceCall() {
+  int $noinline$testThisWithInstanceCall() {
     return doNativeCallRef();
   }
 
-  int testThisWithStaticCall() {
+  int $noinline$testThisWithStaticCall() {
     return doStaticNativeCallRef();
   }
 
-  static int testParameter(Object a) {
+  static int $noinline$testParameter(Object a) {
     return doStaticNativeCallRef();
   }
 
-  static int testObjectInScope() {
+  static int $noinline$testObjectInScope() {
     Object a = array[0];
     return doStaticNativeCallRef();
   }
@@ -41,19 +41,19 @@
   public static void main(String[] args) {
     System.loadLibrary(args[0]);
     Main rm = new Main();
-    if (rm.testThisWithInstanceCall() != 1) {
+    if (rm.$noinline$testThisWithInstanceCall() != 1) {
       throw new Error("Expected 1");
     }
 
-    if (rm.testThisWithStaticCall() != 2) {
+    if (rm.$noinline$testThisWithStaticCall() != 2) {
       throw new Error("Expected 2");
     }
 
-    if (testParameter(new Object()) != 3) {
+    if ($noinline$testParameter(new Object()) != 3) {
       throw new Error("Expected 3");
     }
 
-    if (testObjectInScope() != 4) {
+    if ($noinline$testObjectInScope() != 4) {
       throw new Error("Expected 4");
     }
   }
diff --git a/test/570-checker-osr/src/Main.java b/test/570-checker-osr/src/Main.java
index 4de5634..78f3c32 100644
--- a/test/570-checker-osr/src/Main.java
+++ b/test/570-checker-osr/src/Main.java
@@ -61,51 +61,71 @@
   }
 
   public static int $noinline$returnInt() {
-    if (doThrow) throw new Error("");
+    // If we are running in non-JIT mode, or were unlucky enough to get this method
+    // already JITted, skip the wait for OSR code.
+    boolean interpreting = isInInterpreter("$noinline$returnInt");
     int i = 0;
     for (; i < 100000; ++i) {
     }
-    while (!isInOsrCode("$noinline$returnInt")) {}
+    if (interpreting) {
+      while (!isInOsrCode("$noinline$returnInt")) {}
+    }
     System.out.println(i);
     return 53;
   }
 
   public static float $noinline$returnFloat() {
-    if (doThrow) throw new Error("");
+    // If we are running in non-JIT mode, or were unlucky enough to get this method
+    // already JITted, skip the wait for OSR code.
+    boolean interpreting = isInInterpreter("$noinline$returnFloat");
     int i = 0;
     for (; i < 200000; ++i) {
     }
-    while (!isInOsrCode("$noinline$returnFloat")) {}
+    if (interpreting) {
+      while (!isInOsrCode("$noinline$returnFloat")) {}
+    }
     System.out.println(i);
     return 42.2f;
   }
 
   public static double $noinline$returnDouble() {
-    if (doThrow) throw new Error("");
+    // If we are running in non-JIT mode, or were unlucky enough to get this method
+    // already JITted, skip the wait for OSR code.
+    boolean interpreting = isInInterpreter("$noinline$returnDouble");
     int i = 0;
     for (; i < 300000; ++i) {
     }
-    while (!isInOsrCode("$noinline$returnDouble")) {}
+    if (interpreting) {
+      while (!isInOsrCode("$noinline$returnDouble")) {}
+    }
     System.out.println(i);
     return Double.longBitsToDouble(0xF000000000001111L);
   }
 
   public static long $noinline$returnLong() {
-    if (doThrow) throw new Error("");
+    // If we are running in non-JIT mode, or were unlucky enough to get this method
+    // already JITted, skip the wait for OSR code.
+    boolean interpreting = isInInterpreter("$noinline$returnLong");
     int i = 0;
     for (; i < 400000; ++i) {
     }
-    while (!isInOsrCode("$noinline$returnLong")) {}
+    if (interpreting) {
+      while (!isInOsrCode("$noinline$returnLong")) {}
+    }
     System.out.println(i);
     return 0xFFFF000000001111L;
   }
 
   public static void $noinline$deopt() {
-    if (doThrow) throw new Error("");
+    // If we are running in non-JIT mode, or were unlucky enough to get this method
+    // already JITted, skip the wait for OSR code.
+    boolean interpreting = isInInterpreter("$noinline$deopt");
     int i = 0;
     for (; i < 100000; ++i) {
     }
-    while (!isInOsrCode("$noinline$deopt")) {}
+    if (interpreting) {
+      while (!isInOsrCode("$noinline$deopt")) {}
+    }
     DeoptimizationController.startDeoptimization();
   }
 
@@ -242,7 +262,6 @@
 
   public static void $opt$noinline$testOsrInlineLoop(String[] args) {
     // Regression test for inlining a method with a loop to a method without a loop in OSR mode.
-    if (doThrow) throw new Error();
     assertIntEquals(12, $opt$inline$testRemoveSuspendCheck(12, 5));
     // Since we cannot have a loop directly in this method, we need to force the OSR
     // compilation from native code.
@@ -280,8 +299,6 @@
   public static native boolean isInInterpreter(String methodName);
   public static native void ensureHasProfilingInfo(String methodName);
   public static native void ensureHasOsrCode(String methodName);
-
-  public static boolean doThrow = false;
 }
 
 class SubMain extends Main {
diff --git a/test/597-deopt-invoke-stub/run b/test/597-deopt-invoke-stub/run
index 53b7c4c..990c30e 100644
--- a/test/597-deopt-invoke-stub/run
+++ b/test/597-deopt-invoke-stub/run
@@ -16,6 +16,6 @@
 
 # In order to test deoptimizing at quick-to-interpreter bridge,
 # we want to run in debuggable mode with jit compilation.
-# We also bump up the jit threshold to 10 to make sure that the method
+# We also bump up the jit threshold to 10000 to make sure that the method
 # that should be interpreted is not compiled.
-exec ${RUN} --jit --runtime-option -Xjitthreshold:10000 -Xcompiler-option --debuggable "${@}"
+exec ${RUN} "${@}" --jit --runtime-option -Xjitthreshold:10000 -Xcompiler-option --debuggable
diff --git a/test/655-jit-clinit/src/Main.java b/test/655-jit-clinit/src/Main.java
index 2fb8f2a..7fe5084 100644
--- a/test/655-jit-clinit/src/Main.java
+++ b/test/655-jit-clinit/src/Main.java
@@ -20,7 +20,7 @@
     if (!hasJit()) {
       return;
     }
-    Foo.hotMethod();
+    Foo.$noinline$hotMethod();
   }
 
   public native static boolean hasJitCompiledEntrypoint(Class<?> cls, String methodName);
@@ -28,7 +28,7 @@
 }
 
 class Foo {
-  static void hotMethod() {
+  static void $noinline$hotMethod() {
     for (int i = 0; i < array.length; ++i) {
       array[i] = array;
     }
@@ -36,8 +36,8 @@
 
   static {
     array = new Object[10000];
-    while (!Main.hasJitCompiledEntrypoint(Foo.class, "hotMethod")) {
-      Foo.hotMethod();
+    while (!Main.hasJitCompiledEntrypoint(Foo.class, "$noinline$hotMethod")) {
+      Foo.$noinline$hotMethod();
       try {
         // Sleep to give a chance for the JIT to compile `hotMethod`.
         Thread.sleep(100);