8199624: [Graal] Blocking jvmci compilations time out
authorthartmann
Wed, 21 Mar 2018 08:18:54 +0100
changeset 49469 1708db7f94c6
parent 49468 bef5683e363d
child 49470 a273b521a559
8199624: [Graal] Blocking jvmci compilations time out Summary: Handle blocking jvmci compilations that time out. Reviewed-by: kvn, dnsimon
src/hotspot/share/compiler/compileBroker.cpp
src/hotspot/share/prims/whitebox.cpp
test/hotspot/jtreg/compiler/calls/common/CallsBase.java
test/hotspot/jtreg/runtime/exceptionMsgs/AbstractMethodError/AbstractMethodErrorTest.java
test/hotspot/jtreg/runtime/exceptionMsgs/IncompatibleClassChangeError/IncompatibleClassChangeErrorTest.java
--- a/src/hotspot/share/compiler/compileBroker.cpp	Tue Mar 20 22:22:02 2018 +0100
+++ b/src/hotspot/share/compiler/compileBroker.cpp	Wed Mar 21 08:18:54 2018 +0100
@@ -1344,11 +1344,11 @@
 #if INCLUDE_JVMCI
 // The number of milliseconds to wait before checking if
 // JVMCI compilation has made progress.
-static const long JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE = 500;
+static const long JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE = 1000;
 
 // The number of JVMCI compilation progress checks that must fail
 // before unblocking a thread waiting for a blocking compilation.
-static const int JVMCI_COMPILATION_PROGRESS_WAIT_ATTEMPTS = 5;
+static const int JVMCI_COMPILATION_PROGRESS_WAIT_ATTEMPTS = 10;
 
 /**
  * Waits for a JVMCI compiler to complete a given task. This thread
--- a/src/hotspot/share/prims/whitebox.cpp	Tue Mar 20 22:22:02 2018 +0100
+++ b/src/hotspot/share/prims/whitebox.cpp	Wed Mar 21 08:18:54 2018 +0100
@@ -865,14 +865,21 @@
 
 bool WhiteBox::compile_method(Method* method, int comp_level, int bci, Thread* THREAD) {
   // Screen for unavailable/bad comp level or null method
-  if (method == NULL || comp_level > MIN2((CompLevel) TieredStopAtLevel, CompLevel_highest_tier) ||
-      CompileBroker::compiler(comp_level) == NULL) {
+  AbstractCompiler* comp = CompileBroker::compiler(comp_level);
+  if (method == NULL || comp_level > MIN2((CompLevel) TieredStopAtLevel, CompLevel_highest_tier) || comp == NULL) {
     return false;
   }
+
+  // Check if compilation is blocking
   methodHandle mh(THREAD, method);
+  DirectiveSet* directive = DirectivesStack::getMatchingDirective(mh, comp);
+  bool is_blocking = !directive->BackgroundCompilationOption;
+  DirectivesStack::release(directive);
+
+  // Compile method and check result
   nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), CompileTask::Reason_Whitebox, THREAD);
   MutexLockerEx mu(Compile_lock);
-  return (mh->queued_for_compilation() || nm != NULL);
+  return ((!is_blocking && mh->queued_for_compilation()) || nm != NULL);
 }
 
 WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level, jint bci))
--- a/test/hotspot/jtreg/compiler/calls/common/CallsBase.java	Tue Mar 20 22:22:02 2018 +0100
+++ b/test/hotspot/jtreg/compiler/calls/common/CallsBase.java	Wed Mar 21 08:18:54 2018 +0100
@@ -152,16 +152,18 @@
                     calleeVisited = false; // reset state
                 }
                 // compile with requested level if needed
-                if (compileCallee > 0) {
-                    compileMethod(calleeMethod, compileCallee);
+                if (compileCallee > 0 && !compileMethod(calleeMethod, compileCallee)) {
+                    System.out.println("WARNING: Blocking compilation failed for calleeMethod (timeout?). Skipping.");
+                    return;
                 }
                 if (checkCalleeCompilationLevel) {
                     Asserts.assertEQ(expectedCalleeCompilationLevel,
                             wb.getMethodCompilationLevel(calleeMethod),
                             "Unexpected callee compilation level");
                 }
-                if (compileCaller > 0) {
-                    compileMethod(callerMethod, compileCaller);
+                if (compileCaller > 0 && !compileMethod(callerMethod, compileCaller)) {
+                    System.out.println("WARNING: Blocking compilation failed for callerMethod (timeout?). Skipping.");
+                    return;
                 }
                 if (checkCallerCompilationLevel) {
                     Asserts.assertEQ(expectedCallerCompilationLevel,
@@ -185,11 +187,12 @@
      * A method to compile another method, searching it by name in current class
      * @param method a method to compile
      * @param compLevel a compilation level
+     * @return true if method was enqueued for compilation
      */
-    protected final void compileMethod(Method method, int compLevel) {
+    protected final boolean compileMethod(Method method, int compLevel) {
         wb.deoptimizeMethod(method);
         Asserts.assertTrue(wb.isMethodCompilable(method, compLevel));
-        wb.enqueueMethodForCompilation(method, compLevel);
+        return wb.enqueueMethodForCompilation(method, compLevel);
     }
 
     /*
--- a/test/hotspot/jtreg/runtime/exceptionMsgs/AbstractMethodError/AbstractMethodErrorTest.java	Tue Mar 20 22:22:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/exceptionMsgs/AbstractMethodError/AbstractMethodErrorTest.java	Wed Mar 21 08:18:54 2018 +0100
@@ -54,7 +54,23 @@
 
     private static boolean enableChecks = true;
 
-    public static void setup_test() {
+    private static boolean compile(Class<?> clazz, String name) {
+        try {
+            Method method = clazz.getMethod(name);
+            boolean enqueued = WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
+            if (!enqueued) {
+                System.out.println("Warning: Blocking compilation failed for " + clazz.getName() + "." + name + " (timeout?)");
+                return false;
+            } else if (!WHITE_BOX.isMethodCompiled(method)) {
+                throw new RuntimeException(clazz.getName() + "." + name + " is not compiled");
+            }
+        } catch (NoSuchMethodException e) {
+            throw new RuntimeException(clazz.getName() + "." + name + " not found", e);
+        }
+        return true;
+    }
+
+    public static boolean setup_test() {
         // Assure all exceptions are loaded.
         new AbstractMethodError();
         new IncompatibleClassChangeError();
@@ -67,48 +83,19 @@
         enableChecks = true;
 
         // Compile
-        try {
-            Method method = AbstractMethodErrorTest.class.getMethod("test_ame5_compiled_vtable_stub");
-            WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
-            if (!WHITE_BOX.isMethodCompiled(method)) {
-                throw new RuntimeException(method.getName() + " is not compiled");
-            }
-            method = AbstractMethodErrorTest.class.getMethod("test_ame6_compiled_itable_stub");
-            WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
-            if (!WHITE_BOX.isMethodCompiled(method)) {
-                throw new RuntimeException(method.getName() + " is not compiled");
-            }
-            method = AME5_C.class.getMethod("c");
-            WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
-            if (!WHITE_BOX.isMethodCompiled(method)) {
-                throw new RuntimeException("AME5_C." + method.getName() + " is not compiled");
-            }
-            method = AME5_D.class.getMethod("c");
-            WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
-            if (!WHITE_BOX.isMethodCompiled(method)) {
-                throw new RuntimeException("AME5_D." + method.getName() + " is not compiled");
-            }
-            method = AME5_E.class.getMethod("c");
-            WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
-            if (!WHITE_BOX.isMethodCompiled(method)) {
-                throw new RuntimeException("AME5_E." + method.getName() + " is not compiled");
-            }
-            method = AME6_C.class.getMethod("c");
-            WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
-            if (!WHITE_BOX.isMethodCompiled(method)) {
-                throw new RuntimeException("AME6_C." + method.getName() + " is not compiled");
-            }
-            method = AME6_D.class.getMethod("c");
-            WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
-            if (!WHITE_BOX.isMethodCompiled(method)) {
-                throw new RuntimeException("AME6_D." + method.getName() + " is not compiled");
-            }
-            method = AME6_E.class.getMethod("c");
-            WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
-            if (!WHITE_BOX.isMethodCompiled(method)) {
-                throw new RuntimeException("AME6_E." + method.getName() + " is not compiled");
-            }
-        } catch (NoSuchMethodException e) { }
+        if (!compile(AbstractMethodErrorTest.class, "test_ame5_compiled_vtable_stub") ||
+            !compile(AbstractMethodErrorTest.class, "test_ame6_compiled_itable_stub") ||
+            !compile(AME5_C.class, "mc") ||
+            !compile(AME5_D.class, "mc") ||
+            !compile(AME5_E.class, "mc") ||
+            !compile(AME6_C.class, "mc") ||
+            !compile(AME6_D.class, "mc") ||
+            !compile(AME6_E.class, "mc")) {
+            return false;
+        }
+
+        System.out.println("warmup done.");
+        return true;
     }
 
     private static String expectedErrorMessageAME1_1 =
@@ -493,7 +480,9 @@
 
 
     public static void main(String[] args) throws Exception {
-        setup_test();
+        if (!setup_test()) {
+          return;
+        }
         test_ame1();
         test_ame2();
         test_ame3_1();
@@ -756,66 +745,66 @@
 // - Call errorneous B.mc() in the end to raise the AbstraceMethodError
 
 abstract class AME5_A {
-    abstract void ma();
-    abstract void mb();
-    abstract void mc();
+    public abstract void ma();
+    public abstract void mb();
+    public abstract void mc();
 }
 
 class AME5_B extends AME5_A {
-    void ma() {
+    public void ma() {
         System.out.print("B.ma() ");
     }
 
-    void mb() {
+    public void mb() {
         System.out.print("B.mb() ");
     }
 
     // This method is missing in the .jasm implementation.
-    void mc() {
+    public void mc() {
         System.out.print("B.mc() ");
     }
 }
 
 class AME5_C extends AME5_A {
-    void ma() {
+    public void ma() {
         System.out.print("C.ma() ");
     }
 
-    void mb() {
+    public void mb() {
         System.out.print("C.mb() ");
     }
 
-    void mc() {
+    public void mc() {
         System.out.print("C.mc() ");
     }
 }
 
 class AME5_D extends AME5_A {
-    void ma() {
+    public void ma() {
         System.out.print("D.ma() ");
     }
 
-    void mb() {
+    public void mb() {
         System.out.print("D.mb() ");
     }
 
-    void mc() {
+    public void mc() {
         System.out.print("D.mc() ");
     }
 }
 
 class AME5_E extends AME5_A {
-    void ma() {
-       System.out.print("E.ma() ");
-   }
+    public  void ma() {
+        System.out.print("E.ma() ");
+    }
 
-   void mb() {
-       System.out.print("E.mb() ");
-   }
+    public void mb() {
+        System.out.print("E.mb() ");
+    }
 
-   void mc() {
-       System.out.print("E.mc() ");
-   }
+    public void mc() {
+        System.out.print("E.mc() ");
+    }
 }
 
 //-------------------------------------------------------------------------
--- a/test/hotspot/jtreg/runtime/exceptionMsgs/IncompatibleClassChangeError/IncompatibleClassChangeErrorTest.java	Tue Mar 20 22:22:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/exceptionMsgs/IncompatibleClassChangeError/IncompatibleClassChangeErrorTest.java	Wed Mar 21 08:18:54 2018 +0100
@@ -62,7 +62,24 @@
         "Class ICC_B does not implement the requested interface ICC_iB";
         // old message: "vtable stub"
 
-    public static void setup_test() {
+
+    private static boolean compile(Class<?> clazz, String name) {
+        try {
+            Method method = clazz.getMethod(name);
+            boolean enqueued = WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
+            if (!enqueued) {
+                System.out.println("Warning: Blocking compilation failed for " + clazz.getName() + "." + name + " (timeout?)");
+                return false;
+            } else if (!WHITE_BOX.isMethodCompiled(method)) {
+                throw new RuntimeException(clazz.getName() + "." + name + " is not compiled");
+            }
+        } catch (NoSuchMethodException e) {
+            throw new RuntimeException(clazz.getName() + "." + name + " not found", e);
+        }
+        return true;
+    }
+
+    public static boolean setup_test() {
         // Assure all exceptions are loaded.
         new AbstractMethodError();
         new IncompatibleClassChangeError();
@@ -75,29 +92,15 @@
         enableChecks = true;
 
         // Compile
-        try {
-            Method method = IncompatibleClassChangeErrorTest.class.getMethod("test_icc_compiled_itable_stub");
-            WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
-            if (!WHITE_BOX.isMethodCompiled(method)) {
-                throw new RuntimeException(method.getName() + " is not compiled");
-            }
-            method = ICC_C.class.getMethod("b");
-            WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
-            if (!WHITE_BOX.isMethodCompiled(method)) {
-                throw new RuntimeException("ICC_C." + method.getName() + " is not compiled");
-            }
-            method = ICC_D.class.getMethod("b");
-            WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
-            if (!WHITE_BOX.isMethodCompiled(method)) {
-                throw new RuntimeException("ICC_D." + method.getName() + " is not compiled");
-            }
-            method = ICC_E.class.getMethod("b");
-            WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
-            if (!WHITE_BOX.isMethodCompiled(method)) {
-                throw new RuntimeException("ICC_E." + method.getName() + " is not compiled");
-            }
-        } catch (NoSuchMethodException e) { }
+        if (!compile(IncompatibleClassChangeErrorTest.class, "test_icc_compiled_itable_stub") ||
+            !compile(ICC_C.class, "b") ||
+            !compile(ICC_D.class, "b") ||
+            !compile(ICC_E.class, "b")) {
+          return false;
+        }
+
         System.out.println("warmup done.");
+        return true;
     }
 
     // Should never be compiled.
@@ -204,7 +207,9 @@
     }
 
     public static void main(String[] args) throws Exception {
-        setup_test();
+        if (!setup_test()) {
+            return;
+        }
         test_iccInt();
         test_icc_compiled_itable_stub();
     }