Search in sources :

Example 1 with UnwindNode

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

the class InliningUtil method finishInlining.

private static ValueNode finishInlining(Invoke invoke, StructuredGraph graph, FixedNode firstNode, List<ReturnNode> returnNodes, UnwindNode unwindNode, Assumptions inlinedAssumptions, StructuredGraph inlineGraph) {
    FixedNode invokeNode = invoke.asNode();
    FrameState stateAfter = invoke.stateAfter();
    assert stateAfter == null || stateAfter.isAlive();
    invokeNode.replaceAtPredecessor(firstNode);
    if (invoke instanceof InvokeWithExceptionNode) {
        InvokeWithExceptionNode invokeWithException = ((InvokeWithExceptionNode) invoke);
        if (unwindNode != null && unwindNode.isAlive()) {
            assert unwindNode.predecessor() != null;
            assert invokeWithException.exceptionEdge().successors().count() == 1;
            ExceptionObjectNode obj = (ExceptionObjectNode) invokeWithException.exceptionEdge();
            obj.replaceAtUsages(unwindNode.exception());
            Node n = obj.next();
            obj.setNext(null);
            unwindNode.replaceAndDelete(n);
            obj.replaceAtPredecessor(null);
            obj.safeDelete();
        } else {
            invokeWithException.killExceptionEdge();
        }
        // get rid of memory kill
        AbstractBeginNode begin = invokeWithException.next();
        if (begin instanceof KillingBeginNode) {
            AbstractBeginNode newBegin = new BeginNode();
            graph.addAfterFixed(begin, graph.add(newBegin));
            begin.replaceAtUsages(newBegin);
            graph.removeFixed(begin);
        }
    } else {
        if (unwindNode != null && unwindNode.isAlive()) {
            DeoptimizeNode deoptimizeNode = addDeoptimizeNode(graph, DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler);
            unwindNode.replaceAndDelete(deoptimizeNode);
        }
    }
    ValueNode returnValue;
    if (!returnNodes.isEmpty()) {
        FixedNode n = invoke.next();
        invoke.setNext(null);
        if (returnNodes.size() == 1) {
            ReturnNode returnNode = returnNodes.get(0);
            returnValue = returnNode.result();
            invokeNode.replaceAtUsages(returnValue);
            returnNode.replaceAndDelete(n);
        } else {
            MergeNode merge = graph.add(new MergeNode());
            merge.setStateAfter(stateAfter);
            returnValue = mergeReturns(merge, returnNodes);
            invokeNode.replaceAtUsages(returnValue);
            if (merge.isPhiAtMerge(returnValue)) {
                fixFrameStates(graph, merge, (PhiNode) returnValue);
            }
            merge.setNext(n);
        }
    } else {
        returnValue = null;
        invokeNode.replaceAtUsages(null);
        GraphUtil.killCFG(invoke.next());
    }
    // Copy assumptions from inlinee to caller
    Assumptions assumptions = graph.getAssumptions();
    if (assumptions != null) {
        if (inlinedAssumptions != null) {
            assumptions.record(inlinedAssumptions);
        }
    } else {
        assert inlinedAssumptions == null : String.format("cannot inline graph (%s) which makes assumptions into a graph (%s) that doesn't", inlineGraph, graph);
    }
    // Copy inlined methods from inlinee to caller
    graph.updateMethods(inlineGraph);
    // Update the set of accessed fields
    if (GraalOptions.GeneratePIC.getValue(graph.getOptions())) {
        graph.updateFields(inlineGraph);
    }
    if (inlineGraph.hasUnsafeAccess()) {
        graph.markUnsafeAccess();
    }
    assert inlineGraph.getSpeculationLog() == null || inlineGraph.getSpeculationLog() == graph.getSpeculationLog() : "Only the root graph should have a speculation log";
    return returnValue;
}
Also used : AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) PiNode(org.graalvm.compiler.nodes.PiNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) MonitorExitNode(org.graalvm.compiler.nodes.java.MonitorExitNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) GuardingNode(org.graalvm.compiler.nodes.extended.GuardingNode) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) StartNode(org.graalvm.compiler.nodes.StartNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) UnwindNode(org.graalvm.compiler.nodes.UnwindNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) ForeignCallNode(org.graalvm.compiler.nodes.extended.ForeignCallNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) FrameState(org.graalvm.compiler.nodes.FrameState) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) Assumptions(jdk.vm.ci.meta.Assumptions) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode)

Example 2 with UnwindNode

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

the class RemoveUnwindPhase method run.

@Override
protected void run(StructuredGraph graph) {
    SharedMethod method = (SharedMethod) graph.method();
    if (method.isDeoptTarget()) {
        /*
             * Deoptimization targets need need to have an exception entry point for every invoke.
             * This decouples deoptimization from exception handling: the exception handling
             * mechanism can just deliver an exception to a deoptimized method without any checks.
             */
        return;
    }
    List<InvokeWithExceptionNode> invocations = new ArrayList<>();
    for (UnwindNode node : graph.getNodes().filter(UnwindNode.class)) {
        walkBack(node.predecessor(), node, invocations);
    }
    /*
         * Modify graph only after all suitable invocations are found, to avoid problems with
         * deleted nodes during graph traversal.
         */
    for (InvokeWithExceptionNode node : invocations) {
        InvokeNode replacement = node.graph().add(new InvokeNode(node.callTarget(), node.bci(), node.stamp(NodeView.DEFAULT)));
        replacement.setStateAfter(node.stateAfter());
        node.killExceptionEdge();
        node.graph().replaceSplit(node, replacement, node.next());
    }
}
Also used : InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) ArrayList(java.util.ArrayList) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) SharedMethod(com.oracle.svm.core.meta.SharedMethod) UnwindNode(org.graalvm.compiler.nodes.UnwindNode)

Example 3 with UnwindNode

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

the class SubstrateGraphKit method mergeUnwinds.

/**
 * A graph with multiple unwinds is invalid. Merge the various unwind paths.
 */
public void mergeUnwinds() {
    List<UnwindNode> unwinds = new ArrayList<>();
    for (Node node : getGraph().getNodes()) {
        if (node instanceof UnwindNode) {
            unwinds.add((UnwindNode) node);
        }
    }
    if (unwinds.size() > 1) {
        MergeNode unwindMergeNode = add(new MergeNode());
        ValueNode exceptionValue = InliningUtil.mergeValueProducers(unwindMergeNode, unwinds, null, UnwindNode::exception);
        UnwindNode unwindReplacement = add(new UnwindNode(exceptionValue));
        unwindMergeNode.setNext(unwindReplacement);
        FrameStateBuilder exceptionState = getFrameState().copy();
        exceptionState.clearStack();
        exceptionState.push(JavaKind.Object, exceptionValue);
        exceptionState.setRethrowException(true);
        unwindMergeNode.setStateAfter(exceptionState.create(BytecodeFrame.AFTER_EXCEPTION_BCI, unwindMergeNode));
    }
}
Also used : MergeNode(org.graalvm.compiler.nodes.MergeNode) DeoptEntryNode(com.oracle.svm.core.graal.nodes.DeoptEntryNode) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) BoxNode(org.graalvm.compiler.nodes.extended.BoxNode) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) CFunctionEpilogueNode(com.oracle.svm.core.nodes.CFunctionEpilogueNode) PiNode(org.graalvm.compiler.nodes.PiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) CFunctionPrologueNode(com.oracle.svm.core.nodes.CFunctionPrologueNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IndirectCallTargetNode(org.graalvm.compiler.nodes.IndirectCallTargetNode) UnwindNode(org.graalvm.compiler.nodes.UnwindNode) Node(org.graalvm.compiler.graph.Node) UnboxNode(org.graalvm.compiler.nodes.extended.UnboxNode) ArrayList(java.util.ArrayList) ValueNode(org.graalvm.compiler.nodes.ValueNode) FrameStateBuilder(org.graalvm.compiler.java.FrameStateBuilder) UnwindNode(org.graalvm.compiler.nodes.UnwindNode)

Example 4 with UnwindNode

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

the class BytecodeParser method createUnwind.

private void createUnwind() {
    assert frameState.stackSize() == 1 : frameState;
    synchronizedEpilogue(BytecodeFrame.AFTER_EXCEPTION_BCI, null, null);
    ValueNode exception = frameState.pop(JavaKind.Object);
    append(new UnwindNode(exception));
}
Also used : ValueNode(org.graalvm.compiler.nodes.ValueNode) UnwindNode(org.graalvm.compiler.nodes.UnwindNode)

Example 5 with UnwindNode

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

the class ReflectionSubstitutionType method throwFailedCast.

private static void throwFailedCast(HostedGraphKit graphKit, ResolvedJavaType expectedType, ValueNode actual) {
    ResolvedJavaMethod createFailedCast = graphKit.findMethod(ExceptionHelpers.class, "createFailedCast", true);
    JavaConstant expected = graphKit.getConstantReflection().asJavaClass(expectedType);
    ValueNode expectedNode = graphKit.createConstant(expected, JavaKind.Object);
    ValueNode exception = graphKit.createJavaCallWithExceptionAndUnwind(InvokeKind.Static, createFailedCast, expectedNode, actual);
    graphKit.append(new UnwindNode(exception));
}
Also used : ValueNode(org.graalvm.compiler.nodes.ValueNode) JavaConstant(jdk.vm.ci.meta.JavaConstant) UnwindNode(org.graalvm.compiler.nodes.UnwindNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Aggregations

UnwindNode (org.graalvm.compiler.nodes.UnwindNode)15 ValueNode (org.graalvm.compiler.nodes.ValueNode)12 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)6 InvokeWithExceptionNode (org.graalvm.compiler.nodes.InvokeWithExceptionNode)5 ReturnNode (org.graalvm.compiler.nodes.ReturnNode)5 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)5 NewInstanceNode (org.graalvm.compiler.nodes.java.NewInstanceNode)5 ArrayList (java.util.ArrayList)4 JavaConstant (jdk.vm.ci.meta.JavaConstant)4 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)4 Node (org.graalvm.compiler.graph.Node)4 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)4 CallTargetNode (org.graalvm.compiler.nodes.CallTargetNode)4 FixedNode (org.graalvm.compiler.nodes.FixedNode)4 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)4 MergeNode (org.graalvm.compiler.nodes.MergeNode)4 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)3 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)3 DeoptimizeNode (org.graalvm.compiler.nodes.DeoptimizeNode)3 EndNode (org.graalvm.compiler.nodes.EndNode)3