8199624: [Graal] Blocking jvmci compilations time out
Handle blocking jvmci compilations that time out. Reviewed-by: kvn, dnsimon
This commit is contained in:
parent
68345b93ad
commit
eda7916ce8
@ -1344,11 +1344,11 @@ CompileTask* CompileBroker::create_compile_task(CompileQueue* queue,
|
||||
#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
|
||||
|
@ -865,14 +865,21 @@ WB_END
|
||||
|
||||
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))
|
||||
|
@ -152,16 +152,18 @@ public abstract class CallsBase {
|
||||
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 @@ public abstract class CallsBase {
|
||||
* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -54,7 +54,23 @@ public class AbstractMethodErrorTest {
|
||||
|
||||
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 @@ public class AbstractMethodErrorTest {
|
||||
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 class AbstractMethodErrorTest {
|
||||
|
||||
|
||||
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 @@ class AME4_E extends AME4_B {
|
||||
// - 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() ");
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -62,7 +62,24 @@ public class IncompatibleClassChangeErrorTest {
|
||||
"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 @@ public class IncompatibleClassChangeErrorTest {
|
||||
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 class IncompatibleClassChangeErrorTest {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
setup_test();
|
||||
if (!setup_test()) {
|
||||
return;
|
||||
}
|
||||
test_iccInt();
|
||||
test_icc_compiled_itable_stub();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user