Search in sources :

Example 1 with CallTargetNode

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

the class TruffleGraphBuilderPlugins method registerCompilerDirectivesPlugins.

public static void registerCompilerDirectivesPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, boolean canDelayIntrinsification) {
    final ResolvedJavaType compilerDirectivesType = getRuntime().resolveType(metaAccess, "com.oracle.truffle.api.CompilerDirectives");
    Registration r = new Registration(plugins, new ResolvedJavaSymbol(compilerDirectivesType));
    r.register0("inInterpreter", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(false));
            return true;
        }
    });
    r.register0("inCompiledCode", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
            return true;
        }
    });
    r.register0("inCompilationRoot", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            GraphBuilderContext.ExternalInliningContext inliningContext = b.getExternalInliningContext();
            if (inliningContext != null) {
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(inliningContext.getInlinedDepth() == 0));
                return true;
            }
            return false;
        }
    });
    r.register0("transferToInterpreter", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter));
            return true;
        }
    });
    r.register0("transferToInterpreterAndInvalidate", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter));
            return true;
        }
    });
    r.register1("interpreterOnly", Runnable.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
            return true;
        }
    });
    r.register1("interpreterOnly", Callable.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
            return true;
        }
    });
    r.register2("injectBranchProbability", double.class, boolean.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode probability, ValueNode condition) {
            b.addPush(JavaKind.Boolean, new BranchProbabilityNode(probability, condition));
            return true;
        }
    });
    r.register1("bailout", String.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode message) {
            if (canDelayIntrinsification) {
                /*
                     * We do not want to bailout yet, since we are still parsing individual methods
                     * and constant folding could still eliminate the call to bailout(). However, we
                     * also want to stop parsing, since we are sure that we will never need the
                     * graph beyond the bailout point.
                     *
                     * Therefore, we manually emit the call to bailout, which will be intrinsified
                     * later when intrinsifications can no longer be delayed. The call is followed
                     * by a NeverPartOfCompilationNode, which is a control sink and therefore stops
                     * any further parsing.
                     */
                StampPair returnStamp = b.getInvokeReturnStamp(b.getAssumptions());
                CallTargetNode callTarget = b.add(new MethodCallTargetNode(InvokeKind.Static, targetMethod, new ValueNode[] { message }, returnStamp, null));
                b.add(new InvokeNode(callTarget, b.bci()));
                b.add(new NeverPartOfCompilationNode("intrinsification of call to bailout() will abort entire compilation"));
                return true;
            }
            if (message.isConstant()) {
                throw b.bailout(message.asConstant().toValueString());
            }
            throw b.bailout("bailout (message is not compile-time constant, so no additional information is available)");
        }
    });
    r.register1("isCompilationConstant", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            if ((value instanceof BoxNode ? ((BoxNode) value).getValue() : value).isConstant()) {
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
            } else {
                b.addPush(JavaKind.Boolean, new IsCompilationConstantNode(value));
            }
            return true;
        }
    });
    r.register1("isPartialEvaluationConstant", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            if ((value instanceof BoxNode ? ((BoxNode) value).getValue() : value).isConstant()) {
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
            } else if (canDelayIntrinsification) {
                return false;
            } else {
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(false));
            }
            return true;
        }
    });
    r.register1("materialize", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            AllowMaterializeNode materializedValue = b.append(new AllowMaterializeNode(value));
            b.add(new ForceMaterializeNode(materializedValue));
            return true;
        }
    });
    r.register1("ensureVirtualized", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
            b.add(new EnsureVirtualizedNode(object, false));
            return true;
        }
    });
    r.register1("ensureVirtualizedHere", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
            b.add(new EnsureVirtualizedNode(object, true));
            return true;
        }
    });
    r.register2("castExact", Object.class, Class.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object, ValueNode javaClass) {
            ValueNode nullCheckedClass = b.addNonNullCast(javaClass);
            LogicNode condition = b.append(InstanceOfDynamicNode.create(b.getAssumptions(), b.getConstantReflection(), nullCheckedClass, object, true, true));
            if (condition.isTautology()) {
                b.addPush(JavaKind.Object, object);
            } else {
                FixedGuardNode fixedGuard = b.add(new FixedGuardNode(condition, DeoptimizationReason.ClassCastException, DeoptimizationAction.InvalidateReprofile, false));
                b.addPush(JavaKind.Object, DynamicPiNode.create(b.getAssumptions(), b.getConstantReflection(), object, fixedGuard, nullCheckedClass, true));
            }
            return true;
        }
    });
}
Also used : EnsureVirtualizedNode(org.graalvm.compiler.nodes.virtual.EnsureVirtualizedNode) BoxNode(org.graalvm.compiler.nodes.extended.BoxNode) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) BranchProbabilityNode(org.graalvm.compiler.nodes.extended.BranchProbabilityNode) AllowMaterializeNode(org.graalvm.compiler.truffle.compiler.nodes.frame.AllowMaterializeNode) ResolvedJavaSymbol(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.ResolvedJavaSymbol) NeverPartOfCompilationNode(org.graalvm.compiler.truffle.compiler.nodes.asserts.NeverPartOfCompilationNode) ForceMaterializeNode(org.graalvm.compiler.truffle.compiler.nodes.frame.ForceMaterializeNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) IsCompilationConstantNode(org.graalvm.compiler.truffle.compiler.nodes.IsCompilationConstantNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) ValueNode(org.graalvm.compiler.nodes.ValueNode) StampPair(org.graalvm.compiler.core.common.type.StampPair) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) InvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode)

Example 2 with CallTargetNode

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

the class SubstrateGraphKit method createIndirectCall.

public InvokeNode createIndirectCall(ValueNode targetAddress, ResolvedJavaMethod targetMethod, List<ValueNode> arguments, Signature signature, CallingConvention.Type callType) {
    assert arguments.size() == signature.getParameterCount(false);
    frameState.clearStack();
    Stamp stamp = returnStamp(signature);
    int bci = bci();
    CallTargetNode callTarget = getGraph().add(new IndirectCallTargetNode(targetAddress, arguments.toArray(new ValueNode[arguments.size()]), StampPair.createSingle(stamp), signature.toParameterTypes(null), targetMethod, callType, InvokeKind.Static));
    InvokeNode invoke = append(new InvokeNode(callTarget, bci));
    // Insert framestate.
    frameState.pushReturn(signature.getReturnKind(), invoke);
    FrameState stateAfter = frameState.create(bci, invoke);
    invoke.setStateAfter(stateAfter);
    return invoke;
}
Also used : Stamp(org.graalvm.compiler.core.common.type.Stamp) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) IndirectCallTargetNode(org.graalvm.compiler.nodes.IndirectCallTargetNode) FrameState(org.graalvm.compiler.nodes.FrameState) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode) IndirectCallTargetNode(org.graalvm.compiler.nodes.IndirectCallTargetNode)

Example 3 with CallTargetNode

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

the class AnalysisMethodCalleeWalker method walkCallees.

/**
 * Visit the callees of this method.
 */
VisitResult walkCallees(AnalysisMethod method, CallPathVisitor visitor) {
    final StructuredGraph graph = method.getTypeFlow().getGraph();
    if (graph != null) {
        for (Invoke invoke : graph.getInvokes()) {
            final CallTargetNode callTarget = invoke.callTarget();
            final AnalysisMethod callee = (AnalysisMethod) callTarget.targetMethod();
            walkMethodAndCallees(callee, method, invoke, visitor);
        }
    }
    return VisitResult.CONTINUE;
}
Also used : AnalysisMethod(com.oracle.graal.pointsto.meta.AnalysisMethod) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) Invoke(org.graalvm.compiler.nodes.Invoke) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode)

Example 4 with CallTargetNode

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

the class MethodHandlePlugin method handleInvoke.

@Override
public boolean handleInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
    IntrinsicMethod intrinsicMethod = methodHandleAccess.lookupMethodHandleIntrinsic(method);
    if (intrinsicMethod != null) {
        InvokeKind invokeKind = b.getInvokeKind();
        if (invokeKind != InvokeKind.Static) {
            args[0] = b.nullCheckedValue(args[0]);
        }
        StampPair invokeReturnStamp = b.getInvokeReturnStamp(b.getAssumptions());
        MethodHandleNode.GraphAdder adder = new MethodHandleNode.GraphAdder(b.getGraph()) {

            @Override
            public <T extends ValueNode> T add(T node) {
                return b.add(node);
            }
        };
        InvokeNode invoke = MethodHandleNode.tryResolveTargetInvoke(adder, methodHandleAccess, intrinsicMethod, method, b.bci(), invokeReturnStamp, args);
        if (invoke == null) {
            MethodHandleNode methodHandleNode = new MethodHandleNode(intrinsicMethod, invokeKind, method, b.bci(), invokeReturnStamp, args);
            if (invokeReturnStamp.getTrustedStamp().getStackKind() == JavaKind.Void) {
                b.add(methodHandleNode);
            } else {
                b.addPush(invokeReturnStamp.getTrustedStamp().getStackKind(), methodHandleNode);
            }
        } else {
            CallTargetNode callTarget = invoke.callTarget();
            NodeInputList<ValueNode> argumentsList = callTarget.arguments();
            for (int i = 0; i < argumentsList.size(); ++i) {
                argumentsList.initialize(i, b.append(argumentsList.get(i)));
            }
            boolean inlineEverything = false;
            if (safeForDeoptimization) {
                // If a MemberName suffix argument is dropped, the replaced call cannot
                // deoptimized since the necessary frame state cannot be reconstructed.
                // As such, it needs to recursively inline everything.
                inlineEverything = args.length != argumentsList.size();
            }
            if (inlineEverything && !callTarget.targetMethod().hasBytecodes()) {
                // we need to force-inline but we can not, leave the invoke as-is
                return false;
            }
            b.handleReplacedInvoke(invoke.getInvokeKind(), callTarget.targetMethod(), argumentsList.toArray(new ValueNode[argumentsList.size()]), inlineEverything);
        }
        return true;
    }
    return false;
}
Also used : MethodHandleNode(org.graalvm.compiler.replacements.nodes.MethodHandleNode) IntrinsicMethod(jdk.vm.ci.meta.MethodHandleAccessProvider.IntrinsicMethod) InvokeKind(org.graalvm.compiler.nodes.CallTargetNode.InvokeKind) StampPair(org.graalvm.compiler.core.common.type.StampPair) ValueNode(org.graalvm.compiler.nodes.ValueNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode)

Example 5 with CallTargetNode

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

the class VerifyDebugUsage method verifyParameters.

private void verifyParameters(StructuredGraph callerGraph, MethodCallTargetNode debugCallTarget, List<? extends ValueNode> args, ResolvedJavaType stringType, int startArgIdx, int varArgsIndex) {
    ResolvedJavaMethod verifiedCallee = debugCallTarget.targetMethod();
    Integer dumpLevel = null;
    int argIdx = startArgIdx;
    int varArgsElementIndex = 0;
    boolean reportVarArgs = false;
    for (int i = 0; i < args.size(); i++) {
        ValueNode arg = args.get(i);
        if (arg instanceof Invoke) {
            reportVarArgs = varArgsIndex >= 0 && argIdx >= varArgsIndex;
            Invoke invoke = (Invoke) arg;
            CallTargetNode callTarget = invoke.callTarget();
            if (callTarget instanceof MethodCallTargetNode) {
                ResolvedJavaMethod m = ((MethodCallTargetNode) callTarget).targetMethod();
                if (m.getName().equals("toString")) {
                    int bci = invoke.bci();
                    int nonVarArgIdx = reportVarArgs ? argIdx - varArgsElementIndex : argIdx;
                    verifyStringConcat(callerGraph, verifiedCallee, bci, nonVarArgIdx, reportVarArgs ? varArgsElementIndex : -1, m);
                    verifyToStringCall(callerGraph, verifiedCallee, stringType, m, bci, nonVarArgIdx, reportVarArgs ? varArgsElementIndex : -1);
                } else if (m.getName().equals("format")) {
                    int bci = invoke.bci();
                    int nonVarArgIdx = reportVarArgs ? argIdx - varArgsElementIndex : argIdx;
                    verifyFormatCall(callerGraph, verifiedCallee, stringType, m, bci, nonVarArgIdx, reportVarArgs ? varArgsElementIndex : -1);
                }
            }
        }
        if (i == 1) {
            if (verifiedCallee.getName().equals("dump")) {
                dumpLevel = verifyDumpLevelParameter(callerGraph, debugCallTarget, verifiedCallee, arg);
            }
        } else if (i == 2) {
            if (dumpLevel != null) {
                verifyDumpObjectParameter(callerGraph, debugCallTarget, arg, verifiedCallee, dumpLevel);
            }
        }
        if (varArgsIndex >= 0 && i >= varArgsIndex) {
            varArgsElementIndex++;
        }
        argIdx++;
    }
}
Also used : MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) Invoke(org.graalvm.compiler.nodes.Invoke) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode)

Aggregations

CallTargetNode (org.graalvm.compiler.nodes.CallTargetNode)8 InvokeNode (org.graalvm.compiler.nodes.InvokeNode)5 MethodCallTargetNode (org.graalvm.compiler.nodes.java.MethodCallTargetNode)4 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)3 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)3 ValueNode (org.graalvm.compiler.nodes.ValueNode)3 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)2 Stamp (org.graalvm.compiler.core.common.type.Stamp)2 StampPair (org.graalvm.compiler.core.common.type.StampPair)2 Invoke (org.graalvm.compiler.nodes.Invoke)2 AnalysisMethod (com.oracle.graal.pointsto.meta.AnalysisMethod)1 FrameAccess (com.oracle.svm.core.amd64.FrameAccess)1 InvokeJavaFunctionPointer (com.oracle.svm.core.annotate.InvokeJavaFunctionPointer)1 CInterfaceLocationIdentity (com.oracle.svm.core.c.struct.CInterfaceLocationIdentity)1 SubstrateCallingConventionType (com.oracle.svm.core.graal.code.amd64.SubstrateCallingConventionType)1 CInterfaceReadNode (com.oracle.svm.core.graal.nodes.CInterfaceReadNode)1 CInterfaceWriteNode (com.oracle.svm.core.graal.nodes.CInterfaceWriteNode)1 SubstrateObjectConstant (com.oracle.svm.core.meta.SubstrateObjectConstant)1 UserError (com.oracle.svm.core.util.UserError)1 VMError.shouldNotReachHere (com.oracle.svm.core.util.VMError.shouldNotReachHere)1