Search in sources :

Example 1 with Feature

use of org.graalvm.nativeimage.hosted.Feature in project graal by oracle.

the class FeatureHandler method registerFeatures.

@SuppressWarnings("unchecked")
public void registerFeatures(ImageClassLoader loader, DebugContext debug) {
    IsInConfigurationAccessImpl access = new IsInConfigurationAccessImpl(this, loader, debug);
    LinkedHashSet<Class<?>> automaticFeatures = new LinkedHashSet<>(loader.findAnnotatedClasses(AutomaticFeature.class, true));
    Map<Class<?>, Class<?>> specificAutomaticFeatures = new HashMap<>();
    for (Class<?> automaticFeature : automaticFeatures) {
        Class<Feature> mostSpecific = (Class<Feature>) automaticFeature;
        boolean foundMostSpecific = false;
        do {
            List<Class<? extends Feature>> featureSubclasses = loader.findSubclasses(mostSpecific, true);
            featureSubclasses.remove(mostSpecific);
            featureSubclasses.removeIf(o -> !automaticFeatures.contains(o));
            if (featureSubclasses.isEmpty()) {
                foundMostSpecific = true;
            } else {
                if (featureSubclasses.size() > 1) {
                    String candidates = featureSubclasses.stream().map(Class::getName).collect(Collectors.joining(" "));
                    VMError.shouldNotReachHere("Ambiguous @AutomaticFeature extension. Conflicting candidates: " + candidates);
                }
                mostSpecific = (Class<Feature>) featureSubclasses.get(0);
            }
        } while (!foundMostSpecific);
        if (mostSpecific != automaticFeature) {
            specificAutomaticFeatures.put(automaticFeature, mostSpecific);
        }
    }
    /* Remove specific since they get registered via their base */
    for (Class<?> specific : specificAutomaticFeatures.values()) {
        automaticFeatures.remove(specific);
    }
    Function<Class<?>, Class<?>> specificClassProvider = specificAutomaticFeatures::get;
    for (Class<?> featureClass : automaticFeatures) {
        registerFeature(featureClass, specificClassProvider, access);
    }
    for (String featureName : OptionUtils.flatten(",", Options.Features.getValue())) {
        try {
            registerFeature(Class.forName(featureName, true, loader.getClassLoader()), specificClassProvider, access);
        } catch (ClassNotFoundException e) {
            throw UserError.abort("Feature %s class not found on the classpath. Ensure that the name is correct and that the class is on the classpath.", featureName);
        }
    }
    if (NativeImageOptions.PrintFeatures.getValue()) {
        ReportUtils.report("feature information", SubstrateOptions.reportsPath(), "feature_info", "csv", out -> {
            out.println("Feature, Required Features");
            for (Feature featureInstance : featureInstances) {
                out.print(featureInstance.getClass().getTypeName());
                String requiredFeaturesString = featureInstance.getRequiredFeatures().stream().map(Class::getTypeName).collect(Collectors.joining(" ", "[", "]"));
                out.print(", ");
                out.println(requiredFeaturesString);
            }
        });
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) HashMap(java.util.HashMap) IsInConfigurationAccessImpl(com.oracle.svm.hosted.FeatureImpl.IsInConfigurationAccessImpl) GraalFeature(com.oracle.svm.core.graal.GraalFeature) AutomaticFeature(com.oracle.svm.core.annotate.AutomaticFeature) Feature(org.graalvm.nativeimage.hosted.Feature) AutomaticFeature(com.oracle.svm.core.annotate.AutomaticFeature)

Example 2 with Feature

use of org.graalvm.nativeimage.hosted.Feature in project graal by oracle.

the class NativeImageGenerator method doRun.

@SuppressWarnings("try")
private void doRun(Map<Method, CEntryPointData> entryPoints, JavaMainSupport javaMainSupport, String imageName, NativeImageKind k, SubstitutionProcessor harnessSubstitutions, ForkJoinPool compilationExecutor, ForkJoinPool analysisExecutor) {
    List<HostedMethod> hostedEntryPoints = new ArrayList<>();
    OptionValues options = HostedOptionValues.singleton();
    SnippetReflectionProvider originalSnippetReflection = GraalAccess.getOriginalSnippetReflection();
    try (DebugContext debug = new Builder(options, new GraalDebugHandlersFactory(originalSnippetReflection)).build();
        DebugCloseable featureCleanup = () -> featureHandler.forEachFeature(Feature::cleanup)) {
        setupNativeImage(imageName, options, entryPoints, javaMainSupport, harnessSubstitutions, analysisExecutor, originalSnippetReflection, debug);
        reporter.printFeatures(featureHandler.getUserFeatureNames());
        boolean returnAfterAnalysis = runPointsToAnalysis(imageName, options, debug);
        if (returnAfterAnalysis) {
            return;
        }
        NativeImageHeap heap;
        HostedMetaAccess hMetaAccess;
        SharedRuntimeConfigurationBuilder runtime;
        try (ReporterClosable c = reporter.printUniverse()) {
            bb.getHeartbeatCallback().run();
            hUniverse = new HostedUniverse(bb);
            hMetaAccess = new HostedMetaAccess(hUniverse, bb.getMetaAccess());
            ((SVMImageHeapScanner) aUniverse.getHeapScanner()).setHostedMetaAccess(hMetaAccess);
            BeforeUniverseBuildingAccessImpl beforeUniverseBuildingConfig = new BeforeUniverseBuildingAccessImpl(featureHandler, loader, debug, hMetaAccess);
            featureHandler.forEachFeature(feature -> feature.beforeUniverseBuilding(beforeUniverseBuildingConfig));
            new UniverseBuilder(aUniverse, bb.getMetaAccess(), hUniverse, hMetaAccess, HostedConfiguration.instance().createStaticAnalysisResultsBuilder(bb, hUniverse), bb.getUnsupportedFeatures()).build(debug);
            BuildPhaseProvider.markHostedUniverseBuilt();
            ClassInitializationSupport classInitializationSupport = bb.getHostVM().getClassInitializationSupport();
            runtime = new HostedRuntimeConfigurationBuilder(options, bb.getHostVM(), hUniverse, hMetaAccess, bb.getProviders(), nativeLibraries, classInitializationSupport, GraalAccess.getOriginalProviders().getLoopsDataProvider()).build();
            registerGraphBuilderPlugins(featureHandler, runtime.getRuntimeConfig(), (HostedProviders) runtime.getRuntimeConfig().getProviders(), bb.getMetaAccess(), aUniverse, hMetaAccess, hUniverse, nativeLibraries, loader, ParsingReason.AOTCompilation, bb.getAnnotationSubstitutionProcessor(), new SubstrateClassInitializationPlugin((SVMHost) aUniverse.hostVM()), classInitializationSupport, ConfigurationValues.getTarget());
            if (NativeImageOptions.PrintUniverse.getValue()) {
                printTypes();
            }
            /* Find the entry point methods in the hosted world. */
            for (AnalysisMethod m : aUniverse.getMethods()) {
                if (m.isEntryPoint()) {
                    HostedMethod found = hUniverse.lookup(m);
                    assert found != null;
                    hostedEntryPoints.add(found);
                }
            }
            if (hostedEntryPoints.size() == 0) {
                throw UserError.abort("Warning: no entry points found, i.e., no method annotated with @%s", CEntryPoint.class.getSimpleName());
            }
            bb.getUnsupportedFeatures().report(bb);
            recordRestrictHeapAccessCallees(aUniverse.getMethods());
            /*
                 * After this point, all TypeFlow (and therefore also TypeState) objects are
                 * unreachable and can be garbage collected. This is important to keep the overall
                 * memory footprint low. However, this also means we no longer have complete call
                 * chain information. Only the summarized information stored in the
                 * StaticAnalysisResult objects is available after this point.
                 */
            bb.cleanupAfterAnalysis();
        } catch (UnsupportedFeatureException ufe) {
            throw FallbackFeature.reportAsFallback(ufe);
        }
        heap = new NativeImageHeap(aUniverse, hUniverse, hMetaAccess, ImageSingletons.lookup(ImageHeapLayouter.class));
        BeforeCompilationAccessImpl beforeCompilationConfig = new BeforeCompilationAccessImpl(featureHandler, loader, aUniverse, hUniverse, heap, debug, runtime);
        featureHandler.forEachFeature(feature -> feature.beforeCompilation(beforeCompilationConfig));
        runtime.updateLazyState(hMetaAccess);
        NativeImageCodeCache codeCache;
        CompileQueue compileQueue;
        try (StopTimer t = TimerCollection.createTimerAndStart(TimerCollection.Registry.COMPILE_TOTAL)) {
            compileQueue = HostedConfiguration.instance().createCompileQueue(debug, featureHandler, hUniverse, runtime, DeoptTester.enabled(), bb.getProviders().getSnippetReflection(), compilationExecutor);
            compileQueue.finish(debug);
            /* release memory taken by graphs for the image writing */
            hUniverse.getMethods().forEach(HostedMethod::clear);
            codeCache = NativeImageCodeCacheFactory.get().newCodeCache(compileQueue, heap, loader.platform, ImageSingletons.lookup(TemporaryBuildDirectoryProvider.class).getTemporaryBuildDirectory());
            codeCache.layoutConstants();
            codeCache.layoutMethods(debug, imageName, bb, compilationExecutor);
            AfterCompilationAccessImpl config = new AfterCompilationAccessImpl(featureHandler, loader, aUniverse, hUniverse, compileQueue.getCompilationTasks(), heap, debug, runtime);
            featureHandler.forEachFeature(feature -> feature.afterCompilation(config));
        }
        CodeCacheProvider codeCacheProvider = runtime.getRuntimeConfig().getBackendForNormalMethod().getProviders().getCodeCache();
        reporter.printCreationStart();
        try (Indent indent = debug.logAndIndent("create native image")) {
            try (DebugContext.Scope buildScope = debug.scope("CreateImage", codeCacheProvider)) {
                try (StopTimer t = TimerCollection.createTimerAndStart(TimerCollection.Registry.IMAGE)) {
                    bb.getHeartbeatCallback().run();
                    // Start building the model of the native image heap.
                    heap.addInitialObjects();
                    // Then build the model of the code cache, which can
                    // add objects to the native image heap.
                    codeCache.addConstantsToHeap();
                    // Finish building the model of the native image heap.
                    heap.addTrailingObjects();
                    AfterHeapLayoutAccessImpl config = new AfterHeapLayoutAccessImpl(featureHandler, loader, heap, hMetaAccess, debug);
                    featureHandler.forEachFeature(feature -> feature.afterHeapLayout(config));
                    this.image = AbstractImage.create(k, hUniverse, hMetaAccess, nativeLibraries, heap, codeCache, hostedEntryPoints, loader.getClassLoader());
                    image.build(imageName, debug);
                    if (NativeImageOptions.PrintUniverse.getValue()) {
                        /*
                             * This debug output must be printed _after_ and not _during_ image
                             * building, because it adds some PrintStream objects to static fields,
                             * which disrupts the heap.
                             */
                        codeCache.printCompilationResults();
                    }
                }
            } catch (Throwable e) {
                throw VMError.shouldNotReachHere(e);
            }
        }
        try (StopTimer t = TimerCollection.createTimerAndStart(TimerCollection.Registry.WRITE)) {
            bb.getHeartbeatCallback().run();
            BeforeImageWriteAccessImpl beforeConfig = new BeforeImageWriteAccessImpl(featureHandler, loader, imageName, image, runtime.getRuntimeConfig(), aUniverse, hUniverse, optionProvider, hMetaAccess, debug);
            featureHandler.forEachFeature(feature -> feature.beforeImageWrite(beforeConfig));
            /*
                 * This will write the debug info too -- i.e. we may be writing more than one file,
                 * if the debug info is in a separate file. We need to push writing the file to the
                 * image implementation, because whether the debug info and image share a file or
                 * not is an implementation detail of the image.
                 */
            Path tmpDir = ImageSingletons.lookup(TemporaryBuildDirectoryProvider.class).getTemporaryBuildDirectory();
            LinkerInvocation inv = image.write(debug, generatedFiles(HostedOptionValues.singleton()), tmpDir, imageName, beforeConfig);
            if (NativeImageOptions.ExitAfterRelocatableImageWrite.getValue()) {
                return;
            }
            AfterImageWriteAccessImpl afterConfig = new AfterImageWriteAccessImpl(featureHandler, loader, hUniverse, inv, tmpDir, image.getImageKind(), debug);
            featureHandler.forEachFeature(feature -> feature.afterImageWrite(afterConfig));
        }
        reporter.printCreationEnd(image.getImageSize(), bb.getUniverse(), heap.getObjectCount(), image.getImageHeapSize(), codeCache.getCodeCacheSize(), codeCache.getCompilations().size(), image.getDebugInfoSize());
        if (SubstrateOptions.BuildOutputBreakdowns.getValue()) {
            ProgressReporter.singleton().printBreakdowns(compileQueue.getCompilationTasks(), image.getHeap().getObjects());
        }
    }
}
Also used : Indent(org.graalvm.compiler.debug.Indent) HostedOptionValues(com.oracle.svm.core.option.HostedOptionValues) RuntimeOptionValues(com.oracle.svm.core.option.RuntimeOptionValues) OptionValues(org.graalvm.compiler.options.OptionValues) AfterCompilationAccessImpl(com.oracle.svm.hosted.FeatureImpl.AfterCompilationAccessImpl) AfterImageWriteAccessImpl(com.oracle.svm.hosted.FeatureImpl.AfterImageWriteAccessImpl) ReporterClosable(com.oracle.svm.hosted.ProgressReporter.ReporterClosable) HostedRuntimeConfigurationBuilder(com.oracle.svm.hosted.code.HostedRuntimeConfigurationBuilder) UniverseBuilder(com.oracle.svm.hosted.meta.UniverseBuilder) Builder(org.graalvm.compiler.debug.DebugContext.Builder) SharedRuntimeConfigurationBuilder(com.oracle.svm.hosted.code.SharedRuntimeConfigurationBuilder) BeforeImageWriteAccessImpl(com.oracle.svm.hosted.FeatureImpl.BeforeImageWriteAccessImpl) ArrayList(java.util.ArrayList) LinkerInvocation(com.oracle.svm.core.LinkerInvocation) BeforeUniverseBuildingAccessImpl(com.oracle.svm.hosted.FeatureImpl.BeforeUniverseBuildingAccessImpl) HostedRuntimeConfigurationBuilder(com.oracle.svm.hosted.code.HostedRuntimeConfigurationBuilder) CodeCacheProvider(jdk.vm.ci.code.CodeCacheProvider) LocalizationFeature(com.oracle.svm.hosted.jdk.localization.LocalizationFeature) ClassInitializationFeature(com.oracle.svm.hosted.classinitialization.ClassInitializationFeature) Feature(org.graalvm.nativeimage.hosted.Feature) SubstrateClassInitializationPlugin(com.oracle.svm.hosted.phases.SubstrateClassInitializationPlugin) SVMImageHeapScanner(com.oracle.svm.hosted.heap.SVMImageHeapScanner) SnippetReflectionProvider(org.graalvm.compiler.api.replacements.SnippetReflectionProvider) HostedSnippetReflectionProvider(com.oracle.svm.hosted.meta.HostedSnippetReflectionProvider) SubstrateSnippetReflectionProvider(com.oracle.svm.core.graal.meta.SubstrateSnippetReflectionProvider) CEntryPoint(org.graalvm.nativeimage.c.function.CEntryPoint) Path(java.nio.file.Path) CompileQueue(com.oracle.svm.hosted.code.CompileQueue) UnsupportedFeatureException(com.oracle.graal.pointsto.constraints.UnsupportedFeatureException) AfterHeapLayoutAccessImpl(com.oracle.svm.hosted.FeatureImpl.AfterHeapLayoutAccessImpl) NativeImageHeap(com.oracle.svm.hosted.image.NativeImageHeap) NativeImageCodeCache(com.oracle.svm.hosted.image.NativeImageCodeCache) DebugContext(org.graalvm.compiler.debug.DebugContext) HostedUniverse(com.oracle.svm.hosted.meta.HostedUniverse) HostedMetaAccess(com.oracle.svm.hosted.meta.HostedMetaAccess) SharedRuntimeConfigurationBuilder(com.oracle.svm.hosted.code.SharedRuntimeConfigurationBuilder) GraalDebugHandlersFactory(org.graalvm.compiler.printer.GraalDebugHandlersFactory) UniverseBuilder(com.oracle.svm.hosted.meta.UniverseBuilder) AnalysisMethod(com.oracle.graal.pointsto.meta.AnalysisMethod) PointsToAnalysisMethod(com.oracle.graal.pointsto.meta.PointsToAnalysisMethod) HostedMethod(com.oracle.svm.hosted.meta.HostedMethod) StopTimer(com.oracle.graal.pointsto.util.Timer.StopTimer) DebugCloseable(org.graalvm.compiler.debug.DebugCloseable) ClassInitializationSupport(com.oracle.svm.hosted.classinitialization.ClassInitializationSupport) RuntimeClassInitializationSupport(org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport) TemporaryBuildDirectoryProvider(com.oracle.svm.core.c.libc.TemporaryBuildDirectoryProvider) BeforeCompilationAccessImpl(com.oracle.svm.hosted.FeatureImpl.BeforeCompilationAccessImpl)

Example 3 with Feature

use of org.graalvm.nativeimage.hosted.Feature in project graal by oracle.

the class FeatureHandler method registerFeature.

/**
 * Instantiates the given feature class and (recursively) all feature classes it requires.
 *
 * @param access
 */
@SuppressWarnings("unchecked")
private void registerFeature(Class<?> baseFeatureClass, Function<Class<?>, Class<?>> specificClassProvider, IsInConfigurationAccessImpl access) {
    if (!Feature.class.isAssignableFrom(baseFeatureClass)) {
        throw UserError.abort("Class does not implement %s: %s", Feature.class.getName(), baseFeatureClass.getName());
    }
    if (registeredFeatures.contains(baseFeatureClass)) {
        return;
    }
    /*
         * Immediately add to the registeredFeatures to avoid infinite recursion in case of cyclic
         * dependencies.
         */
    registeredFeatures.add(baseFeatureClass);
    Class<?> specificClass = specificClassProvider.apply(baseFeatureClass);
    Class<?> featureClass = specificClass != null ? specificClass : baseFeatureClass;
    Feature feature;
    try {
        feature = (Feature) ReflectionUtil.newInstance(featureClass);
    } catch (ReflectionUtilError ex) {
        throw UserError.abort(ex.getCause(), "Error instantiating Feature class %s. Ensure the class is not abstract and has a no-argument constructor.", featureClass.getTypeName());
    }
    if (!feature.isInConfiguration(access)) {
        return;
    }
    /*
         * All features are automatically added to the VMConfiguration, to allow convenient
         * configuration checks.
         */
    ImageSingletons.add((Class<Feature>) baseFeatureClass, feature);
    /*
         * First add dependent features so that initializers are executed in order of dependencies.
         */
    for (Class<? extends Feature> requiredFeatureClass : feature.getRequiredFeatures()) {
        registerFeature(requiredFeatureClass, specificClassProvider, access);
    }
    featureInstances.add(feature);
}
Also used : ReflectionUtilError(com.oracle.svm.util.ReflectionUtil.ReflectionUtilError) GraalFeature(com.oracle.svm.core.graal.GraalFeature) AutomaticFeature(com.oracle.svm.core.annotate.AutomaticFeature) Feature(org.graalvm.nativeimage.hosted.Feature)

Aggregations

Feature (org.graalvm.nativeimage.hosted.Feature)3 AutomaticFeature (com.oracle.svm.core.annotate.AutomaticFeature)2 GraalFeature (com.oracle.svm.core.graal.GraalFeature)2 UnsupportedFeatureException (com.oracle.graal.pointsto.constraints.UnsupportedFeatureException)1 AnalysisMethod (com.oracle.graal.pointsto.meta.AnalysisMethod)1 PointsToAnalysisMethod (com.oracle.graal.pointsto.meta.PointsToAnalysisMethod)1 StopTimer (com.oracle.graal.pointsto.util.Timer.StopTimer)1 LinkerInvocation (com.oracle.svm.core.LinkerInvocation)1 TemporaryBuildDirectoryProvider (com.oracle.svm.core.c.libc.TemporaryBuildDirectoryProvider)1 SubstrateSnippetReflectionProvider (com.oracle.svm.core.graal.meta.SubstrateSnippetReflectionProvider)1 HostedOptionValues (com.oracle.svm.core.option.HostedOptionValues)1 RuntimeOptionValues (com.oracle.svm.core.option.RuntimeOptionValues)1 AfterCompilationAccessImpl (com.oracle.svm.hosted.FeatureImpl.AfterCompilationAccessImpl)1 AfterHeapLayoutAccessImpl (com.oracle.svm.hosted.FeatureImpl.AfterHeapLayoutAccessImpl)1 AfterImageWriteAccessImpl (com.oracle.svm.hosted.FeatureImpl.AfterImageWriteAccessImpl)1 BeforeCompilationAccessImpl (com.oracle.svm.hosted.FeatureImpl.BeforeCompilationAccessImpl)1 BeforeImageWriteAccessImpl (com.oracle.svm.hosted.FeatureImpl.BeforeImageWriteAccessImpl)1 BeforeUniverseBuildingAccessImpl (com.oracle.svm.hosted.FeatureImpl.BeforeUniverseBuildingAccessImpl)1 IsInConfigurationAccessImpl (com.oracle.svm.hosted.FeatureImpl.IsInConfigurationAccessImpl)1 ReporterClosable (com.oracle.svm.hosted.ProgressReporter.ReporterClosable)1