use of com.oracle.svm.core.util.InterruptImageBuilding in project graal by oracle.
the class NativeImageGeneratorRunner method buildImage.
@SuppressWarnings("try")
private int buildImage(String[] arguments, String[] classpath, ClassLoader classLoader) {
if (!verifyValidJavaVersionAndPlatform()) {
return -1;
}
Timer totalTimer = new Timer("[total]", false);
ForkJoinPool analysisExecutor = null;
ForkJoinPool compilationExecutor = null;
try (StopTimer ignored = totalTimer.start()) {
ImageClassLoader imageClassLoader;
Timer classlistTimer = new Timer("classlist", false);
try (StopTimer ignored1 = classlistTimer.start()) {
imageClassLoader = ImageClassLoader.create(defaultPlatform(), classpath, classLoader);
}
HostedOptionParser optionParser = new HostedOptionParser(imageClassLoader);
String[] remainingArgs = optionParser.parse(arguments);
if (remainingArgs.length > 0) {
throw UserError.abort("Unknown options: " + Arrays.toString(remainingArgs));
}
/*
* We do not have the VMConfiguration and the HostedOptionValues set up yet, so we need
* to pass the OptionValues explicitly when accessing options.
*/
OptionValues parsedHostedOptions = new OptionValues(optionParser.getHostedValues());
DebugContext debug = DebugContext.create(parsedHostedOptions, new GraalDebugHandlersFactory(GraalAccess.getOriginalSnippetReflection()));
String imageName = NativeImageOptions.Name.getValue(parsedHostedOptions);
if (imageName.length() == 0) {
throw UserError.abort("No output file name specified. " + "Use '" + SubstrateOptionsParser.commandArgument(NativeImageOptions.Name, "<output-file>") + "'.");
}
// print the time here to avoid interactions with flags processing
classlistTimer.print();
Map<Method, CEntryPointData> entryPoints = new HashMap<>();
Method mainEntryPoint = null;
JavaMainSupport javaMainSupport = null;
AbstractBootImage.NativeImageKind k = AbstractBootImage.NativeImageKind.valueOf(NativeImageOptions.Kind.getValue(parsedHostedOptions));
if (k == AbstractBootImage.NativeImageKind.EXECUTABLE) {
String className = NativeImageOptions.Class.getValue(parsedHostedOptions);
if (className == null || className.length() == 0) {
throw UserError.abort("Must specify main entry point class when building " + AbstractBootImage.NativeImageKind.EXECUTABLE + " native image. " + "Use '" + SubstrateOptionsParser.commandArgument(NativeImageOptions.Class, "<fully-qualified-class-name>") + "'.");
}
Class<?> mainClass;
try {
mainClass = Class.forName(className, false, classLoader);
} catch (ClassNotFoundException ex) {
throw UserError.abort("Main entry point class '" + className + "' not found.");
}
String mainEntryPointName = NativeImageOptions.Method.getValue(parsedHostedOptions);
if (mainEntryPointName == null || mainEntryPointName.length() == 0) {
throw UserError.abort("Must specify main entry point method when building " + AbstractBootImage.NativeImageKind.EXECUTABLE + " native image. " + "Use '" + SubstrateOptionsParser.commandArgument(NativeImageOptions.Method, "<method-name>") + "'.");
}
try {
/* First look for an main method with the C-level signature for arguments. */
mainEntryPoint = mainClass.getDeclaredMethod(mainEntryPointName, int.class, CCharPointerPointer.class);
} catch (NoSuchMethodException ignored2) {
try {
/*
* If no C-level main method was found, look for a Java-level main method
* and use our wrapper to invoke it.
*/
Method javaMainMethod = mainClass.getDeclaredMethod(mainEntryPointName, String[].class);
javaMainMethod.setAccessible(true);
if (javaMainMethod.getReturnType() != void.class) {
throw UserError.abort("Java main method must have return type void. Change the return type of method '" + mainClass.getName() + "." + mainEntryPointName + "(String[])'.");
}
final int mainMethodModifiers = javaMainMethod.getModifiers();
if (!Modifier.isPublic(mainMethodModifiers)) {
throw UserError.abort("Method '" + mainClass.getName() + "." + mainEntryPointName + "(String[])' is not accessible. Please make it 'public'.");
}
javaMainSupport = new JavaMainSupport(javaMainMethod);
mainEntryPoint = JavaMainWrapper.class.getDeclaredMethod("run", int.class, CCharPointerPointer.class);
} catch (NoSuchMethodException ex) {
throw UserError.abort("Method '" + mainClass.getName() + "." + mainEntryPointName + "' is declared as the main entry point but it can not be found. " + "Make sure that class '" + mainClass.getName() + "' is on the classpath and that method '" + mainEntryPointName + "(String[])' exists in that class.");
}
}
CEntryPoint annotation = mainEntryPoint.getAnnotation(CEntryPoint.class);
if (annotation == null) {
throw UserError.abort("Entry point must have the '@" + CEntryPoint.class.getSimpleName() + "' annotation");
}
entryPoints.put(mainEntryPoint, CEntryPointData.create(mainEntryPoint));
Class<?>[] pt = mainEntryPoint.getParameterTypes();
if (pt.length != 2 || pt[0] != int.class || pt[1] != CCharPointerPointer.class || mainEntryPoint.getReturnType() != int.class) {
throw UserError.abort("Main entry point must have signature 'int main(int argc, CCharPointerPointer argv)'.");
}
}
int maxConcurrentThreads = NativeImageOptions.getMaximumNumberOfConcurrentThreads(parsedHostedOptions);
analysisExecutor = Inflation.createExecutor(debug, NativeImageOptions.getMaximumNumberOfAnalysisThreads(parsedHostedOptions));
compilationExecutor = Inflation.createExecutor(debug, maxConcurrentThreads);
generator = new NativeImageGenerator(imageClassLoader, optionParser);
generator.run(entryPoints, mainEntryPoint, javaMainSupport, imageName, k, SubstitutionProcessor.IDENTITY, analysisExecutor, compilationExecutor, optionParser.getRuntimeOptionNames());
} catch (InterruptImageBuilding e) {
if (analysisExecutor != null) {
analysisExecutor.shutdownNow();
}
if (compilationExecutor != null) {
compilationExecutor.shutdownNow();
}
e.getReason().ifPresent(NativeImageGeneratorRunner::info);
return 0;
} catch (UserException e) {
e.getMessages().iterator().forEachRemaining(NativeImageGeneratorRunner::reportUserError);
return -1;
} catch (AnalysisError e) {
NativeImageGeneratorRunner.reportUserError(e.getMessage());
return -1;
} catch (ParallelExecutionException pee) {
boolean hasUserError = false;
for (Throwable exception : pee.getExceptions()) {
if (exception instanceof UserException) {
((UserException) exception).getMessages().iterator().forEachRemaining(NativeImageGeneratorRunner::reportUserError);
hasUserError = true;
} else if (exception instanceof AnalysisError) {
NativeImageGeneratorRunner.reportUserError(exception.getMessage());
hasUserError = true;
}
}
if (hasUserError) {
return -1;
}
if (pee.getExceptions().size() > 1) {
System.err.println(pee.getExceptions().size() + " fatal errors detected:");
}
for (Throwable exception : pee.getExceptions()) {
NativeImageGeneratorRunner.reportFatalError(exception);
}
return -1;
} catch (Throwable e) {
NativeImageGeneratorRunner.reportFatalError(e);
return -1;
}
totalTimer.print();
return 0;
}
use of com.oracle.svm.core.util.InterruptImageBuilding in project graal by oracle.
the class CompileQueue method finish.
@SuppressWarnings("try")
public void finish(DebugContext debug) {
try {
try (StopTimer t = new Timer("(parse)").start()) {
parseAll();
}
// Checking @Uninterruptible annotations does not take long enough to justify a timer.
UninterruptibleAnnotationChecker.check(debug, universe.getMethods());
// Checking @RestrictHeapAccess annotations does not take long enough to justify a
// timer.
RestrictHeapAccessAnnotationChecker.check(debug, universe, universe.getMethods());
// Checking @MustNotSynchronize annotations does not take long enough to justify a
// timer.
MustNotSynchronizeAnnotationChecker.check(debug, universe.getMethods());
beforeCompileAll(debug);
if (SubstrateOptions.AOTInline.getValue()) {
try (StopTimer ignored = new Timer("(inline)").start()) {
inlineTrivialMethods(debug);
}
}
try (StopTimer t = new Timer("(compile)").start()) {
compileAll();
}
} catch (InterruptedException ie) {
throw new InterruptImageBuilding();
}
if (NativeImageOptions.PrintMethodHistogram.getValue()) {
printMethodHistogram();
}
}
use of com.oracle.svm.core.util.InterruptImageBuilding in project graal by oracle.
the class CCompilerInvoker method compileAndParseError.
public Path compileAndParseError(List<String> options, Path source, Path target) {
try {
Process compilingProcess = startCompiler(options, source.normalize(), target.normalize());
InputStream es = compilingProcess.getErrorStream();
List<String> lines = FileUtils.readAllLines(es);
int status = compilingProcess.waitFor();
boolean errorReported = false;
for (String line : lines) {
if (line.contains(": error:") || line.contains(": fatal error:")) {
reportCompilerError(source, line);
errorReported = true;
}
}
if (status != 0 && !errorReported) {
reportCompilerError(source, lines.toString());
}
compilingProcess.destroy();
return target;
} catch (InterruptedException ex) {
throw new InterruptImageBuilding();
} catch (IOException ex) {
throw shouldNotReachHere(ex);
}
}
use of com.oracle.svm.core.util.InterruptImageBuilding in project graal by oracle.
the class HostedOptionParser method parse.
public String[] parse(String[] args) {
List<String> remainingArgs = new ArrayList<>();
Set<String> errors = new HashSet<>();
InterruptImageBuilding interrupt = null;
for (String arg : args) {
boolean isImageBuildOption = false;
try {
isImageBuildOption |= SubstrateOptionsParser.parseHostedOption(SubstrateOptionsParser.HOSTED_OPTION_PREFIX, allHostedOptions, hostedValues, PLUS_MINUS, errors, arg, System.out);
} catch (InterruptImageBuilding e) {
interrupt = e;
}
try {
isImageBuildOption |= SubstrateOptionsParser.parseHostedOption(SubstrateOptionsParser.RUNTIME_OPTION_PREFIX, allRuntimeOptions, runtimeValues, PLUS_MINUS, errors, arg, System.out);
} catch (InterruptImageBuilding e) {
interrupt = e;
}
if (!isImageBuildOption) {
remainingArgs.add(arg);
}
}
if (interrupt != null) {
throw interrupt;
}
if (!errors.isEmpty()) {
throw UserError.abort(errors);
}
/*
* We cannot prevent that runtime-only options are accessed during native image generation.
* However, we set these options to null here, so that at least they do not have a sensible
* value.
*/
for (OptionDescriptor descriptor : allRuntimeOptions.values()) {
if (!allHostedOptions.containsValue(descriptor)) {
hostedValues.put(descriptor.getOptionKey(), null);
}
}
return remainingArgs.toArray(new String[remainingArgs.size()]);
}
use of com.oracle.svm.core.util.InterruptImageBuilding in project graal by oracle.
the class NativeImageGenerator method run.
/**
* Executes the image build. Only one image can be built with this generator.
*/
public void run(Map<Method, CEntryPointData> entryPoints, Method mainEntryPoint, JavaMainSupport javaMainSupport, String imageName, AbstractBootImage.NativeImageKind k, SubstitutionProcessor harnessSubstitutions, ForkJoinPool compilationExecutor, ForkJoinPool analysisExecutor, EconomicSet<String> allOptionNames) {
try {
if (!buildStarted.compareAndSet(false, true)) {
throw UserError.abort("An image build has already been performed with this generator.");
}
int maxConcurrentThreads = NativeImageOptions.getMaximumNumberOfConcurrentThreads(new OptionValues(optionProvider.getHostedValues()));
this.imageBuildPool = createForkJoinPool(maxConcurrentThreads);
imageBuildPool.submit(() -> {
try {
ImageSingletons.add(HostedOptionValues.class, new HostedOptionValues(optionProvider.getHostedValues()));
ImageSingletons.add(RuntimeOptionValues.class, new RuntimeOptionValues(optionProvider.getRuntimeValues(), allOptionNames));
doRun(entryPoints, mainEntryPoint, javaMainSupport, imageName, k, harnessSubstitutions, compilationExecutor, analysisExecutor);
} finally {
try {
/*
* Make sure we clean up after ourselves even in the case of an exception.
*/
if (deleteTempDirectory) {
deleteAll(tempDirectory());
}
featureHandler.forEachFeature(Feature::cleanup);
} catch (Throwable e) {
/*
* Suppress subsequent errors so that we unwind the original error brought
* us here.
*/
}
}
}).get();
} catch (InterruptedException | CancellationException e) {
System.out.println("Interrupted!");
throw new InterruptImageBuilding();
} catch (ExecutionException e) {
if (e.getCause() instanceof RuntimeException) {
throw (RuntimeException) e.getCause();
} else if (e.getCause() instanceof Error) {
throw (Error) e.getCause();
}
} finally {
shutdownPoolSafe();
}
}
Aggregations