8257471: fatal error: Fatal exception in JVMCI: Exception during JVMCI compiler initialization

Reviewed-by: kvn, never
This commit is contained in:
Doug Simon 2020-12-02 10:14:46 +00:00
parent 3e3745c2da
commit 7e37c7c544
3 changed files with 40 additions and 25 deletions

View File

@ -48,14 +48,16 @@ final class HotSpotJVMCICompilerConfig {
private static class DummyCompilerFactory implements JVMCICompilerFactory, JVMCICompiler {
private final String reason;
private final HotSpotJVMCIRuntime runtime;
DummyCompilerFactory(String reason) {
DummyCompilerFactory(String reason, HotSpotJVMCIRuntime runtime) {
this.reason = reason;
this.runtime = runtime;
}
@Override
public HotSpotCompilationRequestResult compileMethod(CompilationRequest request) {
throw new JVMCIError("no JVMCI compiler selected: " + reason);
throw runtime.exitHotSpotWithMessage(1, "Cannot use JVMCI compiler: %s%n", reason);
}
@Override
@ -64,7 +66,7 @@ final class HotSpotJVMCICompilerConfig {
}
@Override
public JVMCICompiler createCompiler(JVMCIRuntime runtime) {
public JVMCICompiler createCompiler(JVMCIRuntime rt) {
return this;
}
}
@ -81,15 +83,16 @@ final class HotSpotJVMCICompilerConfig {
* @throws SecurityException if a security manager is present and it denies
* {@link JVMCIPermission} for any {@link JVMCIServiceLocator} loaded by this method
*/
static JVMCICompilerFactory getCompilerFactory() {
static JVMCICompilerFactory getCompilerFactory(HotSpotJVMCIRuntime runtime) {
if (compilerFactory == null) {
JVMCICompilerFactory factory = null;
String compilerName = Option.Compiler.getString();
if (compilerName != null) {
String compPropertyName = Option.Compiler.getPropertyName();
if (compilerName.isEmpty()) {
factory = new DummyCompilerFactory(" empty \"\" is specified");
factory = new DummyCompilerFactory("Value of " + compPropertyName + " is empty", runtime);
} else if (compilerName.equals("null")) {
factory = new DummyCompilerFactory("\"null\" is specified");
factory = new DummyCompilerFactory("Value of " + compPropertyName + " is \"null\"", runtime);
} else {
for (JVMCICompilerFactory f : getJVMCICompilerFactories()) {
if (f.getCompilerName().equals(compilerName)) {
@ -98,29 +101,29 @@ final class HotSpotJVMCICompilerConfig {
}
if (factory == null) {
if (Services.IS_IN_NATIVE_IMAGE) {
throw new JVMCIError("JVMCI compiler '%s' not found in JVMCI native library.%n" +
"Use -XX:-UseJVMCINativeLibrary when specifying a JVMCI compiler available on a class path with %s.",
compilerName, Option.Compiler.getPropertyName());
throw runtime.exitHotSpotWithMessage(1, "JVMCI compiler '%s' not found in JVMCI native library.%n" +
"Use -XX:-UseJVMCINativeLibrary when specifying a JVMCI compiler available on a class path with %s.%n",
compilerName, compPropertyName);
}
throw new JVMCIError("JVMCI compiler '%s' not found", compilerName);
throw runtime.exitHotSpotWithMessage(1, "JVMCI compiler '%s' specified by %s not found%n", compilerName, compPropertyName);
}
}
} else {
// Auto select a single available compiler
String reason = "default compiler is not found";
String reason = "No JVMCI compiler found";
for (JVMCICompilerFactory f : getJVMCICompilerFactories()) {
if (factory == null) {
openJVMCITo(f.getClass().getModule());
factory = f;
} else {
// Multiple factories seen - cancel auto selection
reason = "multiple factories seen: \"" + factory.getCompilerName() + "\" and \"" + f.getCompilerName() + "\"";
reason = "Multiple JVMCI compilers found: \"" + factory.getCompilerName() + "\" and \"" + f.getCompilerName() + "\"";
factory = null;
break;
}
}
if (factory == null) {
factory = new DummyCompilerFactory(reason);
factory = new DummyCompilerFactory(reason, runtime);
}
}
factory.onSelection();

View File

@ -63,7 +63,6 @@ import jdk.vm.ci.runtime.JVMCICompiler;
import jdk.vm.ci.runtime.JVMCICompilerFactory;
import jdk.vm.ci.runtime.JVMCIRuntime;
import jdk.vm.ci.services.JVMCIServiceLocator;
import jdk.vm.ci.services.Services;
/**
* HotSpot implementation of a JVMCI runtime.
@ -380,9 +379,9 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime {
* Parses all system properties starting with {@value #JVMCI_OPTION_PROPERTY_PREFIX} and
* initializes the options based on their values.
*
* @param compilerToVm
* @param runtime
*/
static void parse(CompilerToVM compilerToVm) {
static void parse(HotSpotJVMCIRuntime runtime) {
Map<String, String> savedProps = jdk.vm.ci.services.Services.getSavedProperties();
for (Map.Entry<String, String> e : savedProps.entrySet()) {
String name = e.getKey();
@ -405,9 +404,7 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime {
}
}
msg.format("%nError: A fatal exception has occurred. Program will exit.%n");
byte[] msgBytes = msg.toString().getBytes();
compilerToVm.writeDebugOutput(msgBytes, 0, msgBytes.length, true, true);
compilerToVm.callSystemExit(1);
runtime.exitHotSpotWithMessage(1, msg.toString());
} else if (value instanceof Option) {
Option option = (Option) value;
option.init(e.getValue());
@ -536,7 +533,7 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime {
}
// Initialize the Option values.
Option.parse(compilerToVm);
Option.parse(this);
String hostArchitecture = config.getHostArchitectureName();
@ -549,7 +546,7 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime {
hostBackend = registerBackend(factory.createJVMCIBackend(this, null));
}
compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory();
compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory(this);
if (compilerFactory instanceof HotSpotJVMCICompilerFactory) {
hsCompilerFactory = (HotSpotJVMCICompilerFactory) compilerFactory;
if (hsCompilerFactory.getCompilationLevelAdjustment() != None) {
@ -1161,12 +1158,12 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime {
}
/**
* Informs HotSpot that no method whose module is in {@code modules} is to be compiled
* with {@link #compileMethod}.
* Informs HotSpot that no method whose module is in {@code modules} is to be compiled with
* {@link #compileMethod}.
*
* @param modules the set of modules containing JVMCI compiler classes
*/
public void excludeFromJVMCICompilation(Module...modules) {
public void excludeFromJVMCICompilation(Module... modules) {
this.excludeFromJVMCICompilation = modules.clone();
}
@ -1179,4 +1176,15 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime {
}
compilerToVm.callSystemExit(status);
}
/**
* Writes a message to HotSpot's log stream and then calls {@link System#exit(int)} in HotSpot's
* runtime.
*/
JVMCIError exitHotSpotWithMessage(int status, String format, Object... args) {
byte[] messageBytes = String.format(format, args).getBytes();
compilerToVm.writeDebugOutput(messageBytes, 0, messageBytes.length, true, true);
exitHotSpot(status);
throw JVMCIError.shouldNotReachHere();
}
}

View File

@ -80,6 +80,10 @@ public class TestEnableJVMCIProduct {
for (Expectation expectation : expectations) {
output.stdoutShouldMatch(expectation.pattern);
}
output.shouldHaveExitValue(0);
if (output.getExitValue() != 0) {
// This should only happen when JVMCI compilation is requested and the VM has no
// JVMCI compiler (e.g. Graal is not included in the build)
output.stdoutShouldMatch("No JVMCI compiler found");
}
}
}