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;
}
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());
}
}
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));
}
}
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));
}
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));
}
Aggregations