Search in sources :

Example 1 with NoClassInitializationPlugin

use of com.oracle.graal.pointsto.phases.NoClassInitializationPlugin in project graal by oracle.

the class IntrinsifyMethodHandlesInvocationPlugin method processInvokeWithMethodHandle.

@SuppressWarnings("try")
private boolean processInvokeWithMethodHandle(GraphBuilderContext b, Replacements replacements, ResolvedJavaMethod methodHandleMethod, ValueNode[] methodHandleArguments) {
    /*
         * When parsing for compilation, we must not intrinsify method handles that were not
         * intrinsified during analysis. Otherwise new code that was not seen as reachable by the
         * static analysis would be compiled.
         */
    if (reason != ParsingReason.PointsToAnalysis && intrinsificationRegistry.get(b.getMethod(), b.bci()) != Boolean.TRUE) {
        return false;
    }
    Plugins graphBuilderPlugins = new Plugins(parsingProviders.getReplacements().getGraphBuilderPlugins());
    registerInvocationPlugins(graphBuilderPlugins.getInvocationPlugins(), replacements);
    graphBuilderPlugins.prependParameterPlugin(new MethodHandlesParameterPlugin(methodHandleArguments));
    graphBuilderPlugins.clearInlineInvokePlugins();
    graphBuilderPlugins.prependInlineInvokePlugin(new MethodHandlesInlineInvokePlugin());
    graphBuilderPlugins.prependNodePlugin(new MethodHandlePlugin(parsingProviders.getConstantReflection().getMethodHandleAccess(), false));
    /* We do all the word type rewriting because parameters to the lambda can be word types. */
    SnippetReflectionProvider originalSnippetReflection = GraalAccess.getOriginalSnippetReflection();
    WordOperationPlugin wordOperationPlugin = new WordOperationPlugin(originalSnippetReflection, new SubstrateWordTypes(parsingProviders.getMetaAccess(), FrameAccess.getWordKind()));
    graphBuilderPlugins.appendInlineInvokePlugin(wordOperationPlugin);
    graphBuilderPlugins.appendTypePlugin(wordOperationPlugin);
    graphBuilderPlugins.appendTypePlugin(new TrustedInterfaceTypePlugin());
    graphBuilderPlugins.appendNodePlugin(wordOperationPlugin);
    graphBuilderPlugins.setClassInitializationPlugin(new NoClassInitializationPlugin());
    GraphBuilderConfiguration graphBuilderConfig = GraphBuilderConfiguration.getSnippetDefault(graphBuilderPlugins);
    GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(parsingProviders, graphBuilderConfig, OptimisticOptimizations.NONE, null);
    DebugContext debug = b.getDebug();
    StructuredGraph graph = new StructuredGraph.Builder(b.getOptions(), debug).method(NativeImageUtil.toOriginal(methodHandleMethod)).build();
    try (DebugContext.Scope s = debug.scope("IntrinsifyMethodHandles", graph)) {
        graphBuilder.apply(graph);
        /*
             * The canonicalizer converts unsafe field accesses for get/set method handles back to
             * high-level field load and store nodes.
             */
        CanonicalizerPhase.create().apply(graph, parsingProviders);
        debug.dump(DebugContext.VERBOSE_LEVEL, graph, "Intrinisfication graph before transplant");
        NodeMap<Node> transplanted = new NodeMap<>(graph);
        for (ParameterNode oParam : graph.getNodes(ParameterNode.TYPE)) {
            transplanted.put(oParam, methodHandleArguments[oParam.index()]);
        }
        Transplanter transplanter = new Transplanter(b, transplanted);
        try {
            transplanter.graph(graph);
            if (reason == ParsingReason.PointsToAnalysis) {
                /*
                     * Successfully intrinsified during analysis, remember that we can intrinsify
                     * when parsing for compilation.
                     */
                intrinsificationRegistry.add(b.getMethod(), b.bci(), Boolean.TRUE);
            }
            return true;
        } catch (AbortTransplantException ex) {
            /*
                 * The method handle cannot be intrinsified. If non-constant method handles are not
                 * supported, the code that throws an error at runtime was already appended, so
                 * nothing more to do. If non-constant method handles are supported, we return false
                 * so that the bytecode parser emit a regular invoke bytecode, i.e., the constant
                 * method handle is treated as if it were non-constant.
                 */
            return ex.handled;
        }
    } catch (Throwable ex) {
        throw debug.handle(ex);
    }
}
Also used : BeginNode(org.graalvm.compiler.nodes.BeginNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) AnchoringNode(org.graalvm.compiler.nodes.extended.AnchoringNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) PiNode(org.graalvm.compiler.nodes.PiNode) FinalFieldBarrierNode(org.graalvm.compiler.nodes.java.FinalFieldBarrierNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) NewArrayNode(org.graalvm.compiler.nodes.java.NewArrayNode) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) InstanceOfNode(org.graalvm.compiler.nodes.java.InstanceOfNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) GraphBuilderConfiguration(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration) DebugContext(org.graalvm.compiler.debug.DebugContext) SubstrateWordTypes(com.oracle.svm.core.graal.word.SubstrateWordTypes) NoClassInitializationPlugin(com.oracle.graal.pointsto.phases.NoClassInitializationPlugin) TrustedInterfaceTypePlugin(com.oracle.svm.core.graal.phases.TrustedInterfaceTypePlugin) SnippetReflectionProvider(org.graalvm.compiler.api.replacements.SnippetReflectionProvider) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) NodeMap(org.graalvm.compiler.graph.NodeMap) GraphBuilderPhase(org.graalvm.compiler.java.GraphBuilderPhase) InvocationPlugins(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins) Plugins(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins) MethodHandlePlugin(org.graalvm.compiler.replacements.MethodHandlePlugin) WordOperationPlugin(org.graalvm.compiler.word.WordOperationPlugin)

Example 2 with NoClassInitializationPlugin

use of com.oracle.graal.pointsto.phases.NoClassInitializationPlugin in project graal by oracle.

the class UnsafeAutomaticSubstitutionProcessor method init.

public void init(ImageClassLoader loader, MetaAccessProvider originalMetaAccess) {
    ResolvedJavaMethod atomicIntegerFieldUpdaterNewUpdaterMethod;
    ResolvedJavaMethod atomicLongFieldUpdaterNewUpdaterMethod;
    ResolvedJavaMethod atomicReferenceFieldUpdaterNewUpdaterMethod;
    ResolvedJavaMethod fieldSetAccessibleMethod;
    ResolvedJavaMethod fieldGetMethod;
    try {
        Method fieldSetAccessible = Field.class.getMethod("setAccessible", boolean.class);
        fieldSetAccessibleMethod = originalMetaAccess.lookupJavaMethod(fieldSetAccessible);
        neverInlineSet.add(fieldSetAccessibleMethod);
        Method fieldGet = Field.class.getMethod("get", Object.class);
        fieldGetMethod = originalMetaAccess.lookupJavaMethod(fieldGet);
        neverInlineSet.add(fieldGetMethod);
        /*
             * Various factory methods in VarHandle query the array base/index or field offsets.
             * There is no need to analyze these calls because VarHandle accesses are intrinsified
             * to simple array and field access nodes in IntrinsifyMethodHandlesInvocationPlugin.
             */
        for (Method method : loader.findClassOrFail("java.lang.invoke.VarHandles").getDeclaredMethods()) {
            neverInlineSet.add(originalMetaAccess.lookupJavaMethod(method));
        }
        Class<?> unsafeClass;
        Class<?> sunMiscUnsafeClass;
        try {
            sunMiscUnsafeClass = Class.forName("sun.misc.Unsafe");
            unsafeClass = Class.forName("jdk.internal.misc.Unsafe");
        } catch (ClassNotFoundException cnfe) {
            throw VMError.shouldNotReachHere(cnfe);
        }
        resolvedUnsafeClass = originalMetaAccess.lookupJavaType(unsafeClass);
        resolvedSunMiscUnsafeClass = originalMetaAccess.lookupJavaType(sunMiscUnsafeClass);
        Method unsafeObjectFieldOffset = unsafeClass.getMethod("objectFieldOffset", java.lang.reflect.Field.class);
        unsafeObjectFieldOffsetFieldMethod = originalMetaAccess.lookupJavaMethod(unsafeObjectFieldOffset);
        noCheckedExceptionsSet.add(unsafeObjectFieldOffsetFieldMethod);
        neverInlineSet.add(unsafeObjectFieldOffsetFieldMethod);
        Method unsafeObjectClassStringOffset = unsafeClass.getMethod("objectFieldOffset", java.lang.Class.class, String.class);
        unsafeObjectFieldOffsetClassStringMethod = originalMetaAccess.lookupJavaMethod(unsafeObjectClassStringOffset);
        noCheckedExceptionsSet.add(unsafeObjectFieldOffsetClassStringMethod);
        neverInlineSet.add(unsafeObjectFieldOffsetClassStringMethod);
        if (JavaVersionUtil.JAVA_SPEC >= 17) {
            /*
                 * JDK 17 and later add checks for hidden classes and record classes in
                 * sun.misc.Unsafe before delegating to jdk.internal.misc.Unsafe. When inlined, the
                 * checks make control flow too complex to detect offset field assignments.
                 */
            Method sunMiscUnsafeObjectFieldOffset = sunMiscUnsafeClass.getMethod("objectFieldOffset", java.lang.reflect.Field.class);
            sunMiscUnsafeObjectFieldOffsetMethod = originalMetaAccess.lookupJavaMethod(sunMiscUnsafeObjectFieldOffset);
            noCheckedExceptionsSet.add(sunMiscUnsafeObjectFieldOffsetMethod);
            neverInlineSet.add(sunMiscUnsafeObjectFieldOffsetMethod);
        }
        Method unsafeArrayBaseOffset = unsafeClass.getMethod("arrayBaseOffset", java.lang.Class.class);
        unsafeArrayBaseOffsetMethod = originalMetaAccess.lookupJavaMethod(unsafeArrayBaseOffset);
        noCheckedExceptionsSet.add(unsafeArrayBaseOffsetMethod);
        neverInlineSet.add(unsafeArrayBaseOffsetMethod);
        Method unsafeArrayIndexScale = unsafeClass.getMethod("arrayIndexScale", java.lang.Class.class);
        unsafeArrayIndexScaleMethod = originalMetaAccess.lookupJavaMethod(unsafeArrayIndexScale);
        noCheckedExceptionsSet.add(unsafeArrayIndexScaleMethod);
        neverInlineSet.add(unsafeArrayIndexScaleMethod);
        Method integerNumberOfLeadingZeros = java.lang.Integer.class.getMethod("numberOfLeadingZeros", int.class);
        integerNumberOfLeadingZerosMethod = originalMetaAccess.lookupJavaMethod(integerNumberOfLeadingZeros);
        neverInlineSet.add(integerNumberOfLeadingZerosMethod);
        Method atomicIntegerFieldUpdaterNewUpdater = java.util.concurrent.atomic.AtomicIntegerFieldUpdater.class.getMethod("newUpdater", Class.class, String.class);
        atomicIntegerFieldUpdaterNewUpdaterMethod = originalMetaAccess.lookupJavaMethod(atomicIntegerFieldUpdaterNewUpdater);
        neverInlineSet.add(atomicIntegerFieldUpdaterNewUpdaterMethod);
        Method atomicLongFieldUpdaterNewUpdater = java.util.concurrent.atomic.AtomicLongFieldUpdater.class.getMethod("newUpdater", Class.class, String.class);
        atomicLongFieldUpdaterNewUpdaterMethod = originalMetaAccess.lookupJavaMethod(atomicLongFieldUpdaterNewUpdater);
        neverInlineSet.add(atomicLongFieldUpdaterNewUpdaterMethod);
        Method atomicReferenceFieldUpdaterNewUpdater = java.util.concurrent.atomic.AtomicReferenceFieldUpdater.class.getMethod("newUpdater", Class.class, Class.class, String.class);
        atomicReferenceFieldUpdaterNewUpdaterMethod = originalMetaAccess.lookupJavaMethod(atomicReferenceFieldUpdaterNewUpdater);
        neverInlineSet.add(atomicReferenceFieldUpdaterNewUpdaterMethod);
    } catch (NoSuchMethodException e) {
        throw VMError.shouldNotReachHere(e);
    }
    /*
         * Create the GraphBuilderPhase which builds the graph for the static initializers.
         *
         * The builder phase will inline the first level callees to detect cases where the offset
         * computation is performed by methods that wrap over the unsafe API. There are two
         * exceptions:
         *
         * 1. Don't inline the invokes that we are trying to match.
         *
         * 2. Don't inline Atomic*FieldUpdater.newUpdater() methods as they lead to false errors.
         * These methods reach calls to Unsafe.objectFieldOffset() whose value is recomputed by
         * RecomputeFieldValue.Kind.AtomicFieldUpdaterOffset.
         */
    StaticInitializerInlineInvokePlugin inlineInvokePlugin = new StaticInitializerInlineInvokePlugin(neverInlineSet);
    plugins = new Plugins(new InvocationPlugins());
    plugins.appendInlineInvokePlugin(inlineInvokePlugin);
    NoClassInitializationPlugin classInitializationPlugin = new NoClassInitializationPlugin();
    plugins.setClassInitializationPlugin(classInitializationPlugin);
    ReflectionPlugins.registerInvocationPlugins(loader, snippetReflection, annotationSubstitutions, classInitializationPlugin, plugins.getInvocationPlugins(), null, ParsingReason.UnsafeSubstitutionAnalysis);
    /*
         * Analyzing certain classes leads to false errors. We disable reporting for those classes
         * by default.
         */
    try {
        suppressWarnings.add(originalMetaAccess.lookupJavaType(Class.forName("sun.security.provider.ByteArrayAccess")));
    } catch (ClassNotFoundException e) {
        throw VMError.shouldNotReachHere(e);
    }
}
Also used : InvocationPlugins(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins) Method(java.lang.reflect.Method) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) NoClassInitializationPlugin(com.oracle.graal.pointsto.phases.NoClassInitializationPlugin) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) InvocationPlugins(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins) ReflectionPlugins(com.oracle.svm.hosted.snippets.ReflectionPlugins) Plugins(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins)

Example 3 with NoClassInitializationPlugin

use of com.oracle.graal.pointsto.phases.NoClassInitializationPlugin in project graal by oracle.

the class LambdaProxyRenamingSubstitutionProcessor method getSubstitution.

private LambdaSubstitutionType getSubstitution(ResolvedJavaType original) {
    return typeSubstitutions.computeIfAbsent(original, (key) -> {
        OptionValues options = bb.getOptions();
        DebugContext debug = new Builder(options, new GraalDebugHandlersFactory(bb.getProviders().getSnippetReflection())).build();
        Providers providers = GraalAccess.getOriginalProviders();
        String lambdaTargetName = LambdaUtils.findStableLambdaName(new NoClassInitializationPlugin(), providers, key, options, debug, this);
        return new LambdaSubstitutionType(key, findUniqueLambdaProxyName(lambdaTargetName));
    });
}
Also used : OptionValues(org.graalvm.compiler.options.OptionValues) Builder(org.graalvm.compiler.debug.DebugContext.Builder) DebugContext(org.graalvm.compiler.debug.DebugContext) Providers(org.graalvm.compiler.phases.util.Providers) NoClassInitializationPlugin(com.oracle.graal.pointsto.phases.NoClassInitializationPlugin) GraalDebugHandlersFactory(org.graalvm.compiler.printer.GraalDebugHandlersFactory)

Aggregations

NoClassInitializationPlugin (com.oracle.graal.pointsto.phases.NoClassInitializationPlugin)3 DebugContext (org.graalvm.compiler.debug.DebugContext)2 Plugins (org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins)2 InvocationPlugins (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins)2 TrustedInterfaceTypePlugin (com.oracle.svm.core.graal.phases.TrustedInterfaceTypePlugin)1 SubstrateWordTypes (com.oracle.svm.core.graal.word.SubstrateWordTypes)1 ReflectionPlugins (com.oracle.svm.hosted.snippets.ReflectionPlugins)1 Method (java.lang.reflect.Method)1 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)1 SnippetReflectionProvider (org.graalvm.compiler.api.replacements.SnippetReflectionProvider)1 Builder (org.graalvm.compiler.debug.DebugContext.Builder)1 Node (org.graalvm.compiler.graph.Node)1 NodeMap (org.graalvm.compiler.graph.NodeMap)1 GraphBuilderPhase (org.graalvm.compiler.java.GraphBuilderPhase)1 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)1 BeginNode (org.graalvm.compiler.nodes.BeginNode)1 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)1 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)1 FixedNode (org.graalvm.compiler.nodes.FixedNode)1 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)1