Re-enable OSR.

1) Fix flaky test by doing explicit ProfilingInfo allocation,
   and OSR compilation instead of relying on the system. Also
   make sure the method $noinline$inlineCache always starts
   with the interpreter, as otherwise we would infinite loop.

2) Ensure the thread doing the OSR cannot be suspended once it
   holds an OSR method, as otherwise the jit code cache could
   delete the method before the thread had a chance to jump to it.

Change-Id: Ic0dee181a7b23260419a94a7d7405f150433d31a
diff --git a/test/570-checker-osr/src/Main.java b/test/570-checker-osr/src/Main.java
index bc6612f..828908a 100644
--- a/test/570-checker-osr/src/Main.java
+++ b/test/570-checker-osr/src/Main.java
@@ -36,8 +36,8 @@
     } catch (Exception e) {}
     DeoptimizationController.stopDeoptimization();
 
-    $noinline$inlineCache(new Main(), 0);
-    if ($noinline$inlineCache(new SubMain(), 1) != SubMain.class) {
+    $noinline$inlineCache(new Main(), /* isSecondInvocation */ false);
+    if ($noinline$inlineCache(new SubMain(), /* isSecondInvocation */ true) != SubMain.class) {
       throw new Error("Unexpected return value");
     }
   }
@@ -91,29 +91,29 @@
     DeoptimizationController.startDeoptimization();
   }
 
-  public static Class $noinline$inlineCache(Main m, int count) {
-    for (int i = 0; i < 500; ++i) {
-      // Warm me up.
+  public static Class $noinline$inlineCache(Main m, boolean isSecondInvocation) {
+    // If we are running in non-JIT mode, or were unlucky enough to get this method
+    // already JITted, just return the expected value.
+    if (!ensureInInterpreter()) {
+      return SubMain.class;
     }
-    if (count == 1) {
-      // Lots of back edges to trigger OSR compilation.
-      for (int i = 0; i < 1000; ++i) {
-      }
-      // Best effort to wait for OSR compilation.
-      try {
-        Thread.sleep(1);
-      } catch (Exception e) {}
+
+    ensureHasProfilingInfo();
+
+    // Ensure that we have OSR code to jump to.
+    if (isSecondInvocation) {
+      ensureHasOsrCode();
     }
 
     // This call will be optimized in the OSR compiled code
     // to check and deoptimize if m is not of type 'Main'.
     Main other = m.inlineCache();
 
-    if (count == 1) {
-      // Jump to OSR compiled code. The second run
-      // of this method will have 'm' as a SubMain, and the compiled
-      // code we are jumping to will have wrongly optimize other as being a
-      // 'Main'.
+    // Jump to OSR compiled code. The second run
+    // of this method will have 'm' as a SubMain, and the compiled
+    // code we are jumping to will have wrongly optimize other as being a
+    // 'Main'.
+    if (isSecondInvocation) {
       while (!ensureInOsrCode()) {}
     }
 
@@ -131,7 +131,10 @@
 
   public static int[] array = new int[4];
 
+  public static native boolean ensureInInterpreter();
   public static native boolean ensureInOsrCode();
+  public static native void ensureHasProfilingInfo();
+  public static native void ensureHasOsrCode();
 
   public static boolean doThrow = false;
 }