diff --git a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/hotspot/test/CompileTheWorld.java b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/hotspot/test/CompileTheWorld.java index 8fdf0d35e831..44611913f879 100644 --- a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/hotspot/test/CompileTheWorld.java +++ b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/hotspot/test/CompileTheWorld.java @@ -238,6 +238,7 @@ public CompileTheWorld(HotSpotJVMCIRuntime jvmciRuntime, super(jvmciRuntime, compiler, Options.InvalidateInstalledCode.getValue(harnessOptions), false, + Options.IgnoreCompilationFailures.getValue(harnessOptions), Options.MultiThreaded.getValue(harnessOptions), Options.Threads.getValue(harnessOptions), Options.StatsInterval.getValue(harnessOptions)); @@ -1031,6 +1032,7 @@ static class Options { public static final OptionKey Help = new OptionKey<>(false); public static final OptionKey Classpath = new OptionKey<>(CompileTheWorld.SUN_BOOT_CLASS_PATH); public static final OptionKey Verbose = new OptionKey<>(true); + public static final OptionKey IgnoreCompilationFailures = new OptionKey<>(false); /** * Ignore Graal classes by default to avoid problems associated with compiling snippets and * method substitutions. @@ -1061,6 +1063,7 @@ static class Options { static final ReflectionOptionDescriptors DESCRIPTORS = new ReflectionOptionDescriptors(Options.class, "Help", "List options and their help messages and then exit.", "Classpath", "Class path denoting methods to compile. Default is to compile boot classes.", + "IgnoreCompilationFailures", "Do not exit with an error if any errors in compilation are detected. Defaults to false.", "Verbose", "Verbose operation. Default is !MultiThreaded.", "LimitModules", "Comma separated list of module names to which compilation should be limited. " + "Module names can be prefixed with \"~\" to exclude the named module.", diff --git a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/hotspot/test/LibGraalCompilationDriver.java b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/hotspot/test/LibGraalCompilationDriver.java index 0db924085ee7..93cabbb2d296 100644 --- a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/hotspot/test/LibGraalCompilationDriver.java +++ b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/hotspot/test/LibGraalCompilationDriver.java @@ -39,6 +39,7 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import org.graalvm.collections.UnmodifiableMapCursor; @@ -48,6 +49,7 @@ import com.oracle.truffle.runtime.hotspot.libgraal.LibGraalScope; import jdk.graal.compiler.api.test.ModuleSupport; +import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.debug.TTY; import jdk.graal.compiler.hotspot.CompilationTask; import jdk.graal.compiler.hotspot.HotSpotGraalCompiler; @@ -60,6 +62,7 @@ import jdk.graal.compiler.serviceprovider.GraalUnsafeAccess; import jdk.graal.compiler.util.OptionsEncoder; import jdk.vm.ci.hotspot.HotSpotCompilationRequest; +import jdk.vm.ci.hotspot.HotSpotCompilationRequestResult; import jdk.vm.ci.hotspot.HotSpotInstalledCode; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; @@ -103,6 +106,11 @@ public class LibGraalCompilationDriver { */ private final boolean eagerResolving; + /** + * If true, will not exit with an error in case of errors during compilation. + */ + private final boolean ignoreFailures; + /** * Whether to use multiple threads for compilation. */ @@ -129,12 +137,13 @@ public class LibGraalCompilationDriver { * @param statsInterval Interval between compilation progress reports, in seconds. */ public LibGraalCompilationDriver(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalCompiler compiler, - boolean invalidateInstalledCode, boolean eagerResolving, + boolean invalidateInstalledCode, boolean eagerResolving, boolean ignoreFailures, boolean multiThreaded, int threadCount, int statsInterval) { this.jvmciRuntime = jvmciRuntime; this.compiler = compiler; this.invalidateInstalledCode = invalidateInstalledCode; this.eagerResolving = eagerResolving; + this.ignoreFailures = ignoreFailures; this.multiThreaded = multiThreaded; this.numThreads = threadCount; this.statsInterval = statsInterval; @@ -591,16 +600,19 @@ protected CompilationResult compileWithJarGraal(Compilation compilation, OptionV long allocatedAtStart = getCurrentThreadAllocatedBytes(); CompilationTask task = createCompilationTask(method, useProfilingInfo, installAsDefault); - task.runCompilation(compileOptions); - HotSpotInstalledCode installedCode = task.getInstalledCode(); - if (installedCode == null) { - return null; + HotSpotCompilationRequestResult result = task.runCompilation(compileOptions); + if (result.getFailure() != null) { + throw new GraalError("Compilation request failed: %s", result.getFailureMessage()); } + HotSpotInstalledCode installedCode = task.getInstalledCode(); + assert installedCode != null : "installed code is null yet no failure detected"; long duration = System.nanoTime() - start; long memoryUsed = getCurrentThreadAllocatedBytes() - allocatedAtStart; return new CompilationResult(installedCode, duration, memoryUsed); } + private final AtomicInteger failedCompilations = new AtomicInteger(0); + /** * Compiles all the given methods, using libgraal if available. */ @@ -612,6 +624,7 @@ public void compileAll(List compilations, OptionValues op } private void compileAll(LibGraalParams libgraal, List compilations, OptionValues options) { + failedCompilations.set(0); int threadCount = getThreadCount(); AtomicLong compileTime = new AtomicLong(); @@ -630,6 +643,9 @@ private void compileAll(LibGraalParams libgraal, List com } else { results = compileAllMultiThreaded(libgraal, compilations, options, threadCount, compileTime, memoryUsed, codeSize); } + if (!ignoreFailures && failedCompilations.get() > 0) { + throw new GraalError("%d failures occurred during compilation", failedCompilations.get()); + } long elapsedTime = System.nanoTime() - start; @@ -664,7 +680,7 @@ private void compileAndRecord(Compilation task, LibGraalParams libgraal, OptionV Map results) { CompilationResult result = compile(task, libgraal, options); if (result == null) { - TTY.println("Compilation failed: %s", task); + failedCompilations.getAndAdd(1); return; } compileTime.getAndAdd(result.compileTime()); @@ -748,7 +764,7 @@ private Map compileAllMultiThreaded( TTY.println("%s : Using %d threads", testName(), threadCount); Map results = new ConcurrentHashMap<>(); - try (ThreadPoolExecutor threadPool = new ThreadPoolExecutor(numThreads, threadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), + try (ThreadPoolExecutor threadPool = new ThreadPoolExecutor(threadCount, threadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), new GraalCompileThreadFactory(libgraal))) { for (Compilation task : compilations) { threadPool.submit(() -> compileAndRecord(task, libgraal, options, compileTime, memoryUsed, codeSize, results)); diff --git a/vm/mx.vm/mx_vm_gate.py b/vm/mx.vm/mx_vm_gate.py index b2ba407f6dbb..aa2b5fe03484 100644 --- a/vm/mx.vm/mx_vm_gate.py +++ b/vm/mx.vm/mx_vm_gate.py @@ -451,6 +451,7 @@ def _test_libgraal_ctw(extra_vm_arguments): '-Djdk.graal.InlineDuringParsing=false', '-Djdk.graal.TrackNodeSourcePosition=true', '-Djdk.graal.LogFile=' + compiler_log_file, + '-DCompileTheWorld.IgnoreCompilationFailures=true', '-DCompileTheWorld.Verbose=true', '-DCompileTheWorld.MethodFilter=StackOverflowError.*,String.*', '-Djvmci.ForceTranslateFailure=nmethod/StackOverflowError:hotspot,method/String.hashCode:native,valueOf',