use of org.graalvm.compiler.nodes.FrameState in project graal by oracle.
the class InliningUtil method handleMissingAfterExceptionFrameState.
public static FrameState handleMissingAfterExceptionFrameState(FrameState nonReplaceableFrameState, Invoke invoke, EconomicMap<Node, Node> replacements, boolean alwaysDuplicateStateAfter) {
StructuredGraph graph = nonReplaceableFrameState.graph();
NodeWorkList workList = graph.createNodeWorkList();
workList.add(nonReplaceableFrameState);
for (Node node : workList) {
FrameState fs = (FrameState) node;
for (Node usage : fs.usages().snapshot()) {
if (!usage.isAlive()) {
continue;
}
if (usage instanceof FrameState) {
workList.add(usage);
} else {
StateSplit stateSplit = (StateSplit) usage;
FixedNode fixedStateSplit = stateSplit.asNode();
if (fixedStateSplit instanceof AbstractMergeNode) {
AbstractMergeNode merge = (AbstractMergeNode) fixedStateSplit;
while (merge.isAlive()) {
AbstractEndNode end = merge.forwardEnds().first();
DeoptimizeNode deoptimizeNode = addDeoptimizeNode(graph, DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler);
end.replaceAtPredecessor(deoptimizeNode);
GraphUtil.killCFG(end);
}
} else if (fixedStateSplit instanceof ExceptionObjectNode) {
// The target invoke does not have an exception edge. This means that the
// bytecode parser made the wrong assumption of making an
// InvokeWithExceptionNode for the partial intrinsic exit. We therefore
// replace the InvokeWithExceptionNode with a normal
// InvokeNode -- the deoptimization occurs when the invoke throws.
InvokeWithExceptionNode oldInvoke = (InvokeWithExceptionNode) fixedStateSplit.predecessor();
FrameState oldFrameState = oldInvoke.stateAfter();
InvokeNode newInvoke = oldInvoke.replaceWithInvoke();
newInvoke.setStateAfter(oldFrameState.duplicate());
if (replacements != null) {
replacements.put(oldInvoke, newInvoke);
}
handleAfterBciFrameState(newInvoke.stateAfter(), invoke, alwaysDuplicateStateAfter);
} else {
FixedNode deoptimizeNode = addDeoptimizeNode(graph, DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler);
if (fixedStateSplit instanceof AbstractBeginNode) {
deoptimizeNode = BeginNode.begin(deoptimizeNode);
}
fixedStateSplit.replaceAtPredecessor(deoptimizeNode);
GraphUtil.killCFG(fixedStateSplit);
}
}
}
}
return nonReplaceableFrameState;
}
use of org.graalvm.compiler.nodes.FrameState in project graal by oracle.
the class InliningUtil method processFrameState.
public static FrameState processFrameState(FrameState frameState, Invoke invoke, EconomicMap<Node, Node> replacements, ResolvedJavaMethod inlinedMethod, FrameState stateAtExceptionEdge, FrameState outerFrameState, boolean alwaysDuplicateStateAfter, ResolvedJavaMethod invokeTargetMethod, List<ValueNode> invokeArgsList) {
assert outerFrameState == null || !outerFrameState.isDeleted() : outerFrameState;
final FrameState stateAtReturn = invoke.stateAfter();
JavaKind invokeReturnKind = invoke.asNode().getStackKind();
if (frameState.bci == BytecodeFrame.AFTER_BCI) {
return handleAfterBciFrameState(frameState, invoke, alwaysDuplicateStateAfter);
} else if (stateAtExceptionEdge != null && isStateAfterException(frameState)) {
// pop exception object from invoke's stateAfter and replace with this frameState's
// exception object (top of stack)
FrameState stateAfterException = stateAtExceptionEdge;
if (frameState.stackSize() > 0 && stateAtExceptionEdge.stackAt(0) != frameState.stackAt(0)) {
stateAfterException = stateAtExceptionEdge.duplicateModified(JavaKind.Object, JavaKind.Object, frameState.stackAt(0));
}
frameState.replaceAndDelete(stateAfterException);
return stateAfterException;
} else if ((frameState.bci == BytecodeFrame.UNWIND_BCI && frameState.graph().getGuardsStage() == GuardsStage.FLOATING_GUARDS) || frameState.bci == BytecodeFrame.AFTER_EXCEPTION_BCI) {
/*
* This path converts the frame states relevant for exception unwinding to
* deoptimization. This is only allowed in configurations when Graal compiles code for
* speculative execution (e.g., JIT compilation in HotSpot) but not when compiled code
* must be deoptimization free (e.g., AOT compilation for native image generation).
* There is currently no global flag in StructuredGraph to distinguish such modes, but
* the GuardsStage during inlining indicates the mode in which Graal operates.
*/
handleMissingAfterExceptionFrameState(frameState, invoke, replacements, alwaysDuplicateStateAfter);
return frameState;
} else if (frameState.bci == BytecodeFrame.BEFORE_BCI) {
// must re-execute the intrinsified invocation
assert frameState.outerFrameState() == null;
ValueNode[] invokeArgs = invokeArgsList.isEmpty() ? NO_ARGS : invokeArgsList.toArray(new ValueNode[invokeArgsList.size()]);
FrameState stateBeforeCall = stateAtReturn.duplicateModifiedBeforeCall(invoke.bci(), invokeReturnKind, invokeTargetMethod.getSignature().toParameterKinds(!invokeTargetMethod.isStatic()), invokeArgs);
frameState.replaceAndDelete(stateBeforeCall);
return stateBeforeCall;
} else {
// only handle the outermost frame states
if (frameState.outerFrameState() == null) {
assert checkInlineeFrameState(invoke, inlinedMethod, frameState);
frameState.setOuterFrameState(outerFrameState);
}
return frameState;
}
}
use of org.graalvm.compiler.nodes.FrameState in project graal by oracle.
the class MultiTypeGuardInlineInfo method duplicateInvokeForInlining.
private static Invoke duplicateInvokeForInlining(StructuredGraph graph, Invoke invoke, AbstractMergeNode exceptionMerge, PhiNode exceptionObjectPhi, boolean useForInlining) {
Invoke result = (Invoke) invoke.asNode().copyWithInputs();
Node callTarget = result.callTarget().copyWithInputs();
result.asNode().replaceFirstInput(result.callTarget(), callTarget);
result.setUseForInlining(useForInlining);
JavaKind kind = invoke.asNode().getStackKind();
if (kind != JavaKind.Void) {
FrameState stateAfter = invoke.stateAfter();
stateAfter = stateAfter.duplicate(stateAfter.bci);
stateAfter.replaceFirstInput(invoke.asNode(), result.asNode());
result.setStateAfter(stateAfter);
}
if (invoke instanceof InvokeWithExceptionNode) {
assert exceptionMerge != null && exceptionObjectPhi != null;
InvokeWithExceptionNode invokeWithException = (InvokeWithExceptionNode) invoke;
ExceptionObjectNode exceptionEdge = (ExceptionObjectNode) invokeWithException.exceptionEdge();
FrameState stateAfterException = exceptionEdge.stateAfter();
ExceptionObjectNode newExceptionEdge = (ExceptionObjectNode) exceptionEdge.copyWithInputs();
// set new state (pop old exception object, push new one)
newExceptionEdge.setStateAfter(stateAfterException.duplicateModified(JavaKind.Object, JavaKind.Object, newExceptionEdge));
EndNode endNode = graph.add(new EndNode());
newExceptionEdge.setNext(endNode);
exceptionMerge.addForwardEnd(endNode);
exceptionObjectPhi.addInput(newExceptionEdge);
((InvokeWithExceptionNode) result).setExceptionEdge(newExceptionEdge);
}
return result;
}
Aggregations