Search in sources :

Example 21 with MethodCallTargetNode

use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.

the class VerifyGetOptionsUsage method verify.

@Override
protected boolean verify(StructuredGraph graph, PhaseContext context) {
    MetaAccessProvider metaAccess = context.getMetaAccess();
    ResolvedJavaType canonicalizerToolClass = metaAccess.lookupJavaType(CanonicalizerTool.class);
    boolean hasTool = false;
    try {
        for (ResolvedJavaMethod.Parameter parameter : graph.method().getParameters()) {
            if (parameter.getType().getName().equals(canonicalizerToolClass.getName())) {
                hasTool = true;
                break;
            }
        }
    } catch (MalformedParametersException e) {
    // Lambdas sometimes have malformed parameters so ignore this.
    }
    if (hasTool) {
        ResolvedJavaMethod getOptionsMethod = metaAccess.lookupJavaMethod(lookupMethod(Node.class, "getOptions"));
        for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) {
            ResolvedJavaMethod callee = t.targetMethod();
            if (callee.equals(getOptionsMethod)) {
                if (hasTool) {
                    throw new VerificationError("Must use CanonicalizerTool.getOptions() instead of Node.getOptions() in method '%s' of class '%s'.", graph.method().getName(), graph.method().getDeclaringClass().getName());
                }
            }
        }
    }
    return true;
}
Also used : MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) Node(org.graalvm.compiler.graph.Node) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) MalformedParametersException(java.lang.reflect.MalformedParametersException) MetaAccessProvider(jdk.vm.ci.meta.MetaAccessProvider) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 22 with MethodCallTargetNode

use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.

the class VerifyGraphAddUsage method verify.

@Override
protected boolean verify(StructuredGraph graph, PhaseContext context) {
    boolean allowed = false;
    for (Class<?> cls : ALLOWED_CLASSES) {
        ResolvedJavaType declaringClass = graph.method().getDeclaringClass();
        if (context.getMetaAccess().lookupJavaType(cls).isAssignableFrom(declaringClass)) {
            allowed = true;
        }
    }
    if (!allowed) {
        ResolvedJavaMethod addOrUniqueMethod = context.getMetaAccess().lookupJavaMethod(ADD_OR_UNIQUE);
        for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) {
            ResolvedJavaMethod callee = t.targetMethod();
            if (callee.equals(addOrUniqueMethod)) {
                ValueNode nodeArgument = t.arguments().get(1);
                EconomicSet<Node> seen = EconomicSet.create();
                checkNonFactory(graph, seen, context, nodeArgument);
            }
        }
    }
    return true;
}
Also used : MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) PiNode(org.graalvm.compiler.nodes.PiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) ValueProxyNode(org.graalvm.compiler.nodes.ValueProxyNode) Node(org.graalvm.compiler.graph.Node) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 23 with MethodCallTargetNode

use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.

the class CInterfaceEnumTool method invokeEnumValue.

private InvokeNode invokeEnumValue(GraphBuilderTool b, CallTargetFactory callTargetFactory, FrameStateBuilder frameState, int bci, EnumInfo enumInfo, ResolvedJavaMethod valueMethod, ValueNode arg) {
    ResolvedJavaType returnType = (ResolvedJavaType) valueMethod.getSignature().getReturnType(null);
    ValueNode[] args = new ValueNode[2];
    args[0] = ConstantNode.forConstant(snippetReflection.forObject(enumInfo.getRuntimeData()), b.getMetaAccess(), b.getGraph());
    args[1] = arg;
    StampPair returnStamp = StampFactory.forDeclaredType(null, returnType, false);
    MethodCallTargetNode callTargetNode = b.append(callTargetFactory.createMethodCallTarget(InvokeKind.Virtual, valueMethod, args, returnStamp, bci));
    Stamp invokeStamp = StampFactory.forKind(returnType.getJavaKind());
    InvokeNode invoke = b.append(new InvokeNode(callTargetNode, bci, invokeStamp));
    frameState.push(returnType.getJavaKind(), invoke);
    FrameState stateWithInvoke = frameState.create(bci, invoke);
    frameState.pop(returnType.getJavaKind());
    invoke.setStateAfter(stateWithInvoke);
    return invoke;
}
Also used : MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) Stamp(org.graalvm.compiler.core.common.type.Stamp) ValueNode(org.graalvm.compiler.nodes.ValueNode) StampPair(org.graalvm.compiler.core.common.type.StampPair) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) FrameState(org.graalvm.compiler.nodes.FrameState) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Example 24 with MethodCallTargetNode

use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.

the class IntrinsifyMethodHandlesInvocationPlugin method processInvokeWithMethodHandle.

@SuppressWarnings("try")
private void processInvokeWithMethodHandle(GraphBuilderContext b, BytecodeProvider bytecodeProvider, ResolvedJavaMethod methodHandleMethod, ValueNode[] methodHandleArguments) {
    Plugins graphBuilderPlugins = new Plugins(((ReplacementsImpl) originalProviders.getReplacements()).getGraphBuilderPlugins());
    registerInvocationPlugins(graphBuilderPlugins.getInvocationPlugins(), bytecodeProvider);
    graphBuilderPlugins.prependParameterPlugin(new MethodHandlesParameterPlugin(methodHandleArguments));
    graphBuilderPlugins.clearInlineInvokePlugins();
    graphBuilderPlugins.prependInlineInvokePlugin(new MethodHandlesInlineInvokePlugin());
    graphBuilderPlugins.prependNodePlugin(new MethodHandlePlugin(originalProviders.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 WordTypes(originalProviders.getMetaAccess(), FrameAccess.getWordKind()));
    graphBuilderPlugins.appendInlineInvokePlugin(wordOperationPlugin);
    graphBuilderPlugins.appendTypePlugin(wordOperationPlugin);
    graphBuilderPlugins.appendTypePlugin(new TrustedInterfaceTypePlugin());
    graphBuilderPlugins.appendNodePlugin(wordOperationPlugin);
    GraphBuilderConfiguration graphBuilderConfig = GraphBuilderConfiguration.getSnippetDefault(graphBuilderPlugins);
    GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(originalProviders.getMetaAccess(), originalProviders.getStampProvider(), originalProviders.getConstantReflection(), originalProviders.getConstantFieldProvider(), graphBuilderConfig, OptimisticOptimizations.NONE, null);
    DebugContext debug = b.getDebug();
    StructuredGraph graph = new StructuredGraph.Builder(b.getOptions(), debug).method(toOriginal(methodHandleMethod)).build();
    try (DebugContext.Scope s = debug.scope("IntrinsifyMethodHandles", graph)) {
        graphBuilder.apply(graph);
        /*
             * We do not care about the improved type information from Pi nodes, so we just delete
             * them to simplify our graph.
             */
        for (PiNode pi : graph.getNodes(PiNode.TYPE)) {
            pi.replaceAndDelete(pi.object());
        }
        /*
             * Support for MethodHandle that adapt the input type to a more generic type, i.e., a
             * MethodHandle that does a dynamic type check on a parameter.
             */
        for (UnaryOpLogicNode node : graph.getNodes().filter(UnaryOpLogicNode.class).filter(v -> v instanceof IsNullNode || v instanceof InstanceOfNode)) {
            ValueNode value = node.getValue();
            if (value instanceof ParameterNode) {
                /*
                     * We just assume that the InstanceOfNode or IsNullNode are used in an If and
                     * the true-successor is actually the branch we want. If that assumption is
                     * wrong, nothing bad happens - we will just continue to report the invocation
                     * as unsupported because the updated stamp for the parameter will not simplify
                     * the graph.
                     */
                if (node instanceof InstanceOfNode) {
                    InstanceOfNode inst = (InstanceOfNode) node;
                    TypeReference typeRef = inst.type();
                    value.setStamp(new ObjectStamp(typeRef.getType(), typeRef.isExact(), !inst.allowsNull(), false));
                } else {
                    assert node instanceof IsNullNode;
                    ResolvedJavaType type = value.stamp(NodeView.DEFAULT).javaType(originalProviders.getMetaAccess());
                    value.setStamp(new ObjectStamp(type, false, /* non-null */
                    true, false));
                }
            }
        }
        /*
             * The canonicalizer converts unsafe field accesses for get/set method handles back to
             * high-level field load and store nodes.
             */
        new CanonicalizerPhase().apply(graph, new PhaseContext(originalProviders));
        for (FixedGuardNode guard : graph.getNodes(FixedGuardNode.TYPE)) {
            if (guard.next() instanceof AccessFieldNode && guard.condition() instanceof IsNullNode && guard.isNegated() && ((IsNullNode) guard.condition()).getValue() == ((AccessFieldNode) guard.next()).object()) {
                /*
                     * Method handles to load and stores fields have null checks. Remove them, since
                     * the null check is implicitly done by the field access.
                     */
                GraphUtil.removeFixedWithUnusedInputs(guard);
            }
        }
        debug.dump(DebugContext.VERY_DETAILED_LEVEL, graph, "Final intrinisfication graph");
        /*
             * After parsing (and recursive inlining during parsing), the graph must contain only
             * one invocation (and therefore only one MethodCallTargetNode), plus the parameters,
             * constants, start, and return nodes.
             */
        Node singleFunctionality = null;
        ReturnNode singleReturn = null;
        for (Node node : graph.getNodes()) {
            if (node == graph.start() || node instanceof ParameterNode || node instanceof ConstantNode || node instanceof FrameState) {
                /* Ignore the allowed framework around the nodes we care about. */
                continue;
            } else if (node instanceof Invoke) {
                /* We check the MethodCallTargetNode, so we can ignore the invoke. */
                continue;
            } else if ((node instanceof MethodCallTargetNode || node instanceof LoadFieldNode || node instanceof StoreFieldNode) && singleFunctionality == null) {
                singleFunctionality = node;
                continue;
            } else if (node instanceof ReturnNode && singleReturn == null) {
                singleReturn = (ReturnNode) node;
                continue;
            }
            throw new UnsupportedFeatureException("Invoke with MethodHandle argument could not be reduced to at most a single call: " + methodHandleMethod.format("%H.%n(%p)"));
        }
        if (singleFunctionality instanceof MethodCallTargetNode) {
            MethodCallTargetNode singleCallTarget = (MethodCallTargetNode) singleFunctionality;
            assert singleReturn.result() == null || singleReturn.result() == singleCallTarget.invoke();
            /*
                 * Replace the originalTarget with the replacementTarget. Note that the
                 * replacementTarget node belongs to a different graph than originalTarget, so we
                 * need to match parameter back to the original graph and allocate a new
                 * MethodCallTargetNode for the original graph.
                 */
            ValueNode[] replacedArguments = new ValueNode[singleCallTarget.arguments().size()];
            for (int i = 0; i < replacedArguments.length; i++) {
                replacedArguments[i] = lookup(b, methodHandleArguments, singleCallTarget.arguments().get(i));
            }
            b.handleReplacedInvoke(singleCallTarget.invokeKind(), lookup(singleCallTarget.targetMethod()), replacedArguments, false);
        } else if (singleFunctionality instanceof LoadFieldNode) {
            LoadFieldNode fieldLoad = (LoadFieldNode) singleFunctionality;
            b.addPush(b.getInvokeReturnType().getJavaKind(), LoadFieldNode.create(null, lookup(b, methodHandleArguments, fieldLoad.object()), lookup(fieldLoad.field())));
        } else if (singleFunctionality instanceof StoreFieldNode) {
            StoreFieldNode fieldStore = (StoreFieldNode) singleFunctionality;
            b.add(new StoreFieldNode(lookup(b, methodHandleArguments, fieldStore.object()), lookup(fieldStore.field()), lookup(b, methodHandleArguments, fieldStore.value())));
        } else if (singleReturn.result() != null) {
            /* Replace the invocation with he constant result. */
            JavaConstant constantResult = singleReturn.result().asJavaConstant();
            assert b.getInvokeReturnType().getJavaKind() == constantResult.getJavaKind();
            b.addPush(constantResult.getJavaKind(), ConstantNode.forConstant(lookup(constantResult), universeProviders.getMetaAccess()));
        } else {
            /* No invoke and no return value, so nothing to do. */
            assert b.getInvokeReturnType().getJavaKind() == JavaKind.Void;
        }
    } catch (Throwable ex) {
        throw debug.handle(ex);
    }
}
Also used : ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) AccessFieldNode(org.graalvm.compiler.nodes.java.AccessFieldNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) PiNode(org.graalvm.compiler.nodes.PiNode) UnaryOpLogicNode(org.graalvm.compiler.nodes.UnaryOpLogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) InstanceOfNode(org.graalvm.compiler.nodes.java.InstanceOfNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) Node(org.graalvm.compiler.graph.Node) WordTypes(org.graalvm.compiler.word.WordTypes) JavaConstant(jdk.vm.ci.meta.JavaConstant) PiNode(org.graalvm.compiler.nodes.PiNode) FrameState(org.graalvm.compiler.nodes.FrameState) UnaryOpLogicNode(org.graalvm.compiler.nodes.UnaryOpLogicNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) Invoke(org.graalvm.compiler.nodes.Invoke) PhaseContext(org.graalvm.compiler.phases.tiers.PhaseContext) SnippetReflectionProvider(org.graalvm.compiler.api.replacements.SnippetReflectionProvider) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) GraphBuilderPhase(org.graalvm.compiler.java.GraphBuilderPhase) InvocationPlugins(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins) Plugins(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) UnsupportedFeatureException(com.oracle.graal.pointsto.constraints.UnsupportedFeatureException) GraphBuilderConfiguration(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration) DebugContext(org.graalvm.compiler.debug.DebugContext) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) TrustedInterfaceTypePlugin(com.oracle.svm.core.graal.phases.TrustedInterfaceTypePlugin) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) AccessFieldNode(org.graalvm.compiler.nodes.java.AccessFieldNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) CanonicalizerPhase(org.graalvm.compiler.phases.common.CanonicalizerPhase) InstanceOfNode(org.graalvm.compiler.nodes.java.InstanceOfNode) MethodHandlePlugin(org.graalvm.compiler.replacements.MethodHandlePlugin) WordOperationPlugin(org.graalvm.compiler.word.WordOperationPlugin)

Example 25 with MethodCallTargetNode

use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.

the class CInterfaceEnumTool method invokeEnumLookup.

private InvokeNode invokeEnumLookup(GraphBuilderTool b, CallTargetFactory callTargetFactory, FrameStateBuilder frameState, int bci, EnumInfo enumInfo, JavaKind parameterKind, ValueNode arg) {
    ValueNode[] args = new ValueNode[2];
    args[0] = ConstantNode.forConstant(snippetReflection.forObject(enumInfo.getRuntimeData()), b.getMetaAccess(), b.getGraph());
    assert !Modifier.isStatic(convertCToJavaMethod.getModifiers()) && convertCToJavaMethod.getSignature().getParameterCount(false) == 1;
    JavaKind expectedKind = convertCToJavaMethod.getSignature().getParameterType(0, null).getJavaKind();
    args[1] = CInterfaceInvocationPlugin.adaptPrimitiveType(b.getGraph(), arg, parameterKind, expectedKind, false);
    ResolvedJavaType convertReturnType = (ResolvedJavaType) convertCToJavaMethod.getSignature().getReturnType(null);
    StampPair returnStamp = StampFactory.forDeclaredType(null, convertReturnType, false);
    MethodCallTargetNode callTargetNode = b.append(callTargetFactory.createMethodCallTarget(InvokeKind.Virtual, convertCToJavaMethod, args, returnStamp, bci));
    Stamp invokeStamp = StampFactory.object(TypeReference.createWithoutAssumptions(convertReturnType));
    InvokeNode invoke = b.append(new InvokeNode(callTargetNode, bci, invokeStamp));
    frameState.push(convertReturnType.getJavaKind(), invoke);
    FrameState stateWithInvoke = frameState.create(bci, invoke);
    frameState.pop(convertReturnType.getJavaKind());
    invoke.setStateAfter(stateWithInvoke);
    return invoke;
}
Also used : MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) Stamp(org.graalvm.compiler.core.common.type.Stamp) ValueNode(org.graalvm.compiler.nodes.ValueNode) StampPair(org.graalvm.compiler.core.common.type.StampPair) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) FrameState(org.graalvm.compiler.nodes.FrameState) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaKind(jdk.vm.ci.meta.JavaKind)

Aggregations

MethodCallTargetNode (org.graalvm.compiler.nodes.java.MethodCallTargetNode)46 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)17 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)15 ValueNode (org.graalvm.compiler.nodes.ValueNode)15 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)11 Invoke (org.graalvm.compiler.nodes.Invoke)10 Node (org.graalvm.compiler.graph.Node)9 InvokeNode (org.graalvm.compiler.nodes.InvokeNode)9 ArrayList (java.util.ArrayList)7 StampPair (org.graalvm.compiler.core.common.type.StampPair)7 PiNode (org.graalvm.compiler.nodes.PiNode)7 DebugContext (org.graalvm.compiler.debug.DebugContext)6 CallTargetNode (org.graalvm.compiler.nodes.CallTargetNode)6 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)5 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)5 FrameState (org.graalvm.compiler.nodes.FrameState)5 JavaType (jdk.vm.ci.meta.JavaType)4 ObjectStamp (org.graalvm.compiler.core.common.type.ObjectStamp)4 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)4 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)4