Search in sources :

Example 11 with UnwindNode

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

the class BytecodeExceptionTest method throwBytecodeException.

protected boolean throwBytecodeException(GraphBuilderContext b, Class<? extends Throwable> exception, ValueNode... arguments) {
    BytecodeExceptionNode exceptionNode = b.add(new BytecodeExceptionNode(b.getMetaAccess(), exception, arguments));
    b.add(new UnwindNode(exceptionNode));
    return true;
}
Also used : BytecodeExceptionNode(org.graalvm.compiler.nodes.extended.BytecodeExceptionNode) UnwindNode(org.graalvm.compiler.nodes.UnwindNode)

Example 12 with UnwindNode

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

the class InliningUtil method inline.

/**
 * Performs an actual inlining, thereby replacing the given invoke with the given
 * {@code inlineGraph}.
 *
 * @param invoke the invoke that will be replaced
 * @param inlineGraph the graph that the invoke will be replaced with
 * @param receiverNullCheck true if a null check needs to be generated for non-static inlinings,
 *            false if no such check is required
 * @param inlineeMethod the actual method being inlined. Maybe be null for snippets.
 * @param reason the reason for inlining, used in tracing
 * @param phase the phase that invoked inlining
 */
@SuppressWarnings("try")
public static UnmodifiableEconomicMap<Node, Node> inline(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck, ResolvedJavaMethod inlineeMethod, String reason, String phase) {
    FixedNode invokeNode = invoke.asNode();
    StructuredGraph graph = invokeNode.graph();
    final NodeInputList<ValueNode> parameters = invoke.callTarget().arguments();
    assert inlineGraph.getGuardsStage().ordinal() >= graph.getGuardsStage().ordinal();
    assert !invokeNode.graph().isAfterFloatingReadPhase() : "inline isn't handled correctly after floating reads phase";
    if (receiverNullCheck && !((MethodCallTargetNode) invoke.callTarget()).isStatic()) {
        nonNullReceiver(invoke);
    }
    ArrayList<Node> nodes = new ArrayList<>(inlineGraph.getNodes().count());
    ArrayList<ReturnNode> returnNodes = new ArrayList<>(4);
    ArrayList<Invoke> partialIntrinsicExits = new ArrayList<>();
    UnwindNode unwindNode = null;
    final StartNode entryPointNode = inlineGraph.start();
    FixedNode firstCFGNode = entryPointNode.next();
    if (firstCFGNode == null) {
        throw new IllegalStateException("Inlined graph is in invalid state: " + inlineGraph);
    }
    for (Node node : inlineGraph.getNodes()) {
        if (node == entryPointNode || (node == entryPointNode.stateAfter() && node.usages().count() == 1) || node instanceof ParameterNode) {
        // Do nothing.
        } else {
            nodes.add(node);
            if (node instanceof ReturnNode) {
                returnNodes.add((ReturnNode) node);
            } else if (node instanceof Invoke) {
                Invoke invokeInInlineGraph = (Invoke) node;
                if (invokeInInlineGraph.bci() == BytecodeFrame.UNKNOWN_BCI) {
                    ResolvedJavaMethod target1 = inlineeMethod;
                    ResolvedJavaMethod target2 = invokeInInlineGraph.callTarget().targetMethod();
                    assert target1.equals(target2) : String.format("invoke in inlined method expected to be partial intrinsic exit (i.e., call to %s), not a call to %s", target1.format("%H.%n(%p)"), target2.format("%H.%n(%p)"));
                    partialIntrinsicExits.add(invokeInInlineGraph);
                }
            } else if (node instanceof UnwindNode) {
                assert unwindNode == null;
                unwindNode = (UnwindNode) node;
            }
        }
    }
    final AbstractBeginNode prevBegin = AbstractBeginNode.prevBegin(invokeNode);
    DuplicationReplacement localReplacement = new DuplicationReplacement() {

        @Override
        public Node replacement(Node node) {
            if (node instanceof ParameterNode) {
                return parameters.get(((ParameterNode) node).index());
            } else if (node == entryPointNode) {
                return prevBegin;
            }
            return node;
        }
    };
    assert invokeNode.successors().first() != null : invoke;
    assert invokeNode.predecessor() != null;
    Mark mark = graph.getMark();
    // Instead, attach the inlining log of the child graph to the current inlining log.
    EconomicMap<Node, Node> duplicates;
    try (InliningLog.UpdateScope scope = graph.getInliningLog().openDefaultUpdateScope()) {
        duplicates = graph.addDuplicates(nodes, inlineGraph, inlineGraph.getNodeCount(), localReplacement);
        if (scope != null) {
            graph.getInliningLog().addDecision(invoke, true, reason, phase, duplicates, inlineGraph.getInliningLog());
        }
    }
    FrameState stateAfter = invoke.stateAfter();
    assert stateAfter == null || stateAfter.isAlive();
    FrameState stateAtExceptionEdge = null;
    if (invoke instanceof InvokeWithExceptionNode) {
        InvokeWithExceptionNode invokeWithException = ((InvokeWithExceptionNode) invoke);
        if (unwindNode != null) {
            ExceptionObjectNode obj = (ExceptionObjectNode) invokeWithException.exceptionEdge();
            stateAtExceptionEdge = obj.stateAfter();
        }
    }
    updateSourcePositions(invoke, inlineGraph, duplicates, !Objects.equals(inlineGraph.method(), inlineeMethod), mark);
    if (stateAfter != null) {
        processFrameStates(invoke, inlineGraph, duplicates, stateAtExceptionEdge, returnNodes.size() > 1);
        int callerLockDepth = stateAfter.nestedLockDepth();
        if (callerLockDepth != 0) {
            for (MonitorIdNode original : inlineGraph.getNodes(MonitorIdNode.TYPE)) {
                MonitorIdNode monitor = (MonitorIdNode) duplicates.get(original);
                processMonitorId(invoke.stateAfter(), monitor);
            }
        }
    } else {
        assert checkContainsOnlyInvalidOrAfterFrameState(duplicates);
    }
    firstCFGNode = (FixedNode) duplicates.get(firstCFGNode);
    for (int i = 0; i < returnNodes.size(); i++) {
        returnNodes.set(i, (ReturnNode) duplicates.get(returnNodes.get(i)));
    }
    for (Invoke exit : partialIntrinsicExits) {
        // A partial intrinsic exit must be replaced with a call to
        // the intrinsified method.
        Invoke dup = (Invoke) duplicates.get(exit.asNode());
        if (dup instanceof InvokeNode) {
            InvokeNode repl = graph.add(new InvokeNode(invoke.callTarget(), invoke.bci()));
            dup.intrinsify(repl.asNode());
        } else {
            ((InvokeWithExceptionNode) dup).replaceWithNewBci(invoke.bci());
        }
    }
    if (unwindNode != null) {
        unwindNode = (UnwindNode) duplicates.get(unwindNode);
    }
    finishInlining(invoke, graph, firstCFGNode, returnNodes, unwindNode, inlineGraph.getAssumptions(), inlineGraph);
    GraphUtil.killCFG(invokeNode);
    return duplicates;
}
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) ArrayList(java.util.ArrayList) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) Mark(org.graalvm.compiler.graph.Graph.Mark) FixedNode(org.graalvm.compiler.nodes.FixedNode) FrameState(org.graalvm.compiler.nodes.FrameState) Invoke(org.graalvm.compiler.nodes.Invoke) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) UnwindNode(org.graalvm.compiler.nodes.UnwindNode) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) StartNode(org.graalvm.compiler.nodes.StartNode) DuplicationReplacement(org.graalvm.compiler.graph.Graph.DuplicationReplacement) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) InliningLog(org.graalvm.compiler.nodes.InliningLog) ValueNode(org.graalvm.compiler.nodes.ValueNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 13 with UnwindNode

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

the class ValueMergeUtil method mergeValueProducers.

public static <T> ValueNode mergeValueProducers(AbstractMergeNode merge, List<? extends T> valueProducers, Function<T, FixedWithNextNode> lastInstrFunction, Function<T, ValueNode> valueFunction) {
    ValueNode singleResult = null;
    PhiNode phiResult = null;
    for (T valueProducer : valueProducers) {
        ValueNode result = valueFunction.apply(valueProducer);
        if (result != null) {
            if (phiResult == null && (singleResult == null || singleResult == result)) {
                /* Only one result value, so no need yet for a phi node. */
                singleResult = result;
            } else if (phiResult == null) {
                /* Found a second result value, so create phi node. */
                phiResult = merge.graph().addWithoutUnique(new ValuePhiNode(result.stamp(NodeView.DEFAULT).unrestricted(), merge));
                for (int i = 0; i < merge.forwardEndCount(); i++) {
                    phiResult.addInput(singleResult);
                }
                phiResult.addInput(result);
            } else {
                /* Multiple return values, just add to existing phi node. */
                phiResult.addInput(result);
            }
        }
        // create and wire up a new EndNode
        EndNode endNode = merge.graph().add(new EndNode());
        merge.addForwardEnd(endNode);
        if (lastInstrFunction == null) {
            assert valueProducer instanceof ReturnNode || valueProducer instanceof UnwindNode;
            ((ControlSinkNode) valueProducer).replaceAndDelete(endNode);
        } else {
            FixedWithNextNode lastInstr = lastInstrFunction.apply(valueProducer);
            lastInstr.setNext(endNode);
        }
    }
    if (phiResult != null) {
        assert phiResult.verify();
        phiResult.inferStamp();
        return phiResult;
    } else {
        return singleResult;
    }
}
Also used : ReturnNode(org.graalvm.compiler.nodes.ReturnNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) EndNode(org.graalvm.compiler.nodes.EndNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) UnwindNode(org.graalvm.compiler.nodes.UnwindNode) ControlSinkNode(org.graalvm.compiler.nodes.ControlSinkNode)

Example 14 with UnwindNode

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

the class ReflectionSubstitutionType method throwInvocationTargetException.

private static void throwInvocationTargetException(HostedGraphKit graphKit) {
    ValueNode exception = graphKit.exceptionObject();
    ResolvedJavaType exceptionType = graphKit.getMetaAccess().lookupJavaType(InvocationTargetException.class);
    ValueNode ite = graphKit.append(new NewInstanceNode(exceptionType, true));
    ResolvedJavaMethod cons = null;
    for (ResolvedJavaMethod c : exceptionType.getDeclaredConstructors()) {
        if (c.getSignature().getParameterCount(false) == 1) {
            cons = c;
        }
    }
    graphKit.createJavaCallWithExceptionAndUnwind(InvokeKind.Special, cons, ite, exception);
    graphKit.append(new UnwindNode(ite));
}
Also used : NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) UnwindNode(org.graalvm.compiler.nodes.UnwindNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 15 with UnwindNode

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

the class ReflectionSubstitutionType method throwIllegalArgumentException.

private static void throwIllegalArgumentException(HostedGraphKit graphKit, String message) {
    ResolvedJavaType exceptionType = graphKit.getMetaAccess().lookupJavaType(IllegalArgumentException.class);
    ValueNode ite = graphKit.append(new NewInstanceNode(exceptionType, true));
    ResolvedJavaMethod cons = null;
    for (ResolvedJavaMethod c : exceptionType.getDeclaredConstructors()) {
        if (c.getSignature().getParameterCount(false) == 2) {
            cons = c;
        }
    }
    JavaConstant msg = graphKit.getConstantReflection().forString(message);
    ValueNode msgNode = graphKit.createConstant(msg, JavaKind.Object);
    ValueNode cause = graphKit.createConstant(JavaConstant.NULL_POINTER, JavaKind.Object);
    graphKit.createJavaCallWithExceptionAndUnwind(InvokeKind.Special, cons, ite, msgNode, cause);
    graphKit.append(new UnwindNode(ite));
}
Also used : NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) JavaConstant(jdk.vm.ci.meta.JavaConstant) UnwindNode(org.graalvm.compiler.nodes.UnwindNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) 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