Search in sources :

Example 1 with InterruptImageBuilding

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;
}
Also used : OptionValues(org.graalvm.compiler.options.OptionValues) HashMap(java.util.HashMap) AnalysisError(com.oracle.graal.pointsto.util.AnalysisError) AbstractBootImage(com.oracle.svm.hosted.image.AbstractBootImage) HostedOptionParser(com.oracle.svm.hosted.option.HostedOptionParser) CEntryPointData(com.oracle.svm.hosted.code.CEntryPointData) ParallelExecutionException(com.oracle.graal.pointsto.util.ParallelExecutionException) CEntryPoint(org.graalvm.nativeimage.c.function.CEntryPoint) InterruptImageBuilding(com.oracle.svm.core.util.InterruptImageBuilding) UserException(com.oracle.svm.core.util.UserError.UserException) DebugContext(org.graalvm.compiler.debug.DebugContext) Method(java.lang.reflect.Method) CEntryPoint(org.graalvm.nativeimage.c.function.CEntryPoint) GraalDebugHandlersFactory(org.graalvm.compiler.printer.GraalDebugHandlersFactory) JavaMainSupport(com.oracle.svm.core.JavaMainWrapper.JavaMainSupport) StopTimer(com.oracle.graal.pointsto.util.Timer.StopTimer) Timer(com.oracle.graal.pointsto.util.Timer) StopTimer(com.oracle.graal.pointsto.util.Timer.StopTimer) CCharPointerPointer(org.graalvm.nativeimage.c.type.CCharPointerPointer) ForkJoinPool(java.util.concurrent.ForkJoinPool)

Example 2 with InterruptImageBuilding

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();
    }
}
Also used : StopTimer(com.oracle.graal.pointsto.util.Timer.StopTimer) Timer(com.oracle.graal.pointsto.util.Timer) StopTimer(com.oracle.graal.pointsto.util.Timer.StopTimer) InterruptImageBuilding(com.oracle.svm.core.util.InterruptImageBuilding)

Example 3 with InterruptImageBuilding

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);
    }
}
Also used : InputStream(java.io.InputStream) InterruptImageBuilding(com.oracle.svm.core.util.InterruptImageBuilding) IOException(java.io.IOException)

Example 4 with InterruptImageBuilding

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()]);
}
Also used : OptionDescriptor(org.graalvm.compiler.options.OptionDescriptor) ArrayList(java.util.ArrayList) InterruptImageBuilding(com.oracle.svm.core.util.InterruptImageBuilding) HashSet(java.util.HashSet)

Example 5 with InterruptImageBuilding

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();
    }
}
Also used : HostedOptionValues(com.oracle.svm.core.option.HostedOptionValues) RuntimeOptionValues(com.oracle.svm.core.option.RuntimeOptionValues) OptionValues(org.graalvm.compiler.options.OptionValues) CancellationException(java.util.concurrent.CancellationException) RuntimeOptionValues(com.oracle.svm.core.option.RuntimeOptionValues) InterruptImageBuilding(com.oracle.svm.core.util.InterruptImageBuilding) UserError(com.oracle.svm.core.util.UserError) VMError(com.oracle.svm.core.util.VMError) HostedOptionValues(com.oracle.svm.core.option.HostedOptionValues) ExecutionException(java.util.concurrent.ExecutionException) CEntryPoint(org.graalvm.nativeimage.c.function.CEntryPoint)

Aggregations

InterruptImageBuilding (com.oracle.svm.core.util.InterruptImageBuilding)8 IOException (java.io.IOException)4 Timer (com.oracle.graal.pointsto.util.Timer)3 StopTimer (com.oracle.graal.pointsto.util.Timer.StopTimer)3 ArrayList (java.util.ArrayList)3 OptionValues (org.graalvm.compiler.options.OptionValues)3 CEntryPoint (org.graalvm.nativeimage.c.function.CEntryPoint)3 HostedOptionValues (com.oracle.svm.core.option.HostedOptionValues)2 RuntimeOptionValues (com.oracle.svm.core.option.RuntimeOptionValues)2 UserError (com.oracle.svm.core.util.UserError)2 VMError (com.oracle.svm.core.util.VMError)2 Path (java.nio.file.Path)2 CancellationException (java.util.concurrent.CancellationException)2 ExecutionException (java.util.concurrent.ExecutionException)2 AnalysisPolicy (com.oracle.graal.pointsto.AnalysisPolicy)1 UnsupportedFeatureException (com.oracle.graal.pointsto.constraints.UnsupportedFeatureException)1 SubstitutionProcessor (com.oracle.graal.pointsto.infrastructure.SubstitutionProcessor)1 AnalysisMetaAccess (com.oracle.graal.pointsto.meta.AnalysisMetaAccess)1 AnalysisMethod (com.oracle.graal.pointsto.meta.AnalysisMethod)1 AnalysisType (com.oracle.graal.pointsto.meta.AnalysisType)1