use of org.graalvm.compiler.nodes.DeoptimizeNode in project graal by oracle.
the class BytecodeParser method handleUnresolvedNewInstance.
/**
* @param type the type being instantiated
*/
protected void handleUnresolvedNewInstance(JavaType type) {
assert !graphBuilderConfig.unresolvedIsError();
DeoptimizeNode deopt = append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
deopt.updateNodeSourcePosition(() -> createBytecodePosition());
}
use of org.graalvm.compiler.nodes.DeoptimizeNode in project graal by oracle.
the class BytecodeParser method createBlockTarget.
/**
* Returns a block begin node with the specified state. If the specified probability is 0, the
* block deoptimizes immediately.
*/
private AbstractBeginNode createBlockTarget(double probability, BciBlock block, FrameStateBuilder stateAfter) {
FixedNode target = createTarget(probability, block, stateAfter);
AbstractBeginNode begin = BeginNode.begin(target);
assert !(target instanceof DeoptimizeNode && begin instanceof BeginStateSplitNode && ((BeginStateSplitNode) begin).stateAfter() != null) : "We are not allowed to set the stateAfter of the begin node," + " because we have to deoptimize to a bci _before_ the actual if, so that the interpreter can update the profiling information.";
return begin;
}
use of org.graalvm.compiler.nodes.DeoptimizeNode in project graal by oracle.
the class BytecodeParser method appendInvoke.
protected Invoke appendInvoke(InvokeKind initialInvokeKind, ResolvedJavaMethod initialTargetMethod, ValueNode[] args) {
ResolvedJavaMethod targetMethod = initialTargetMethod;
InvokeKind invokeKind = initialInvokeKind;
if (initialInvokeKind.isIndirect()) {
ResolvedJavaType contextType = this.frameState.getMethod().getDeclaringClass();
ResolvedJavaMethod specialCallTarget = MethodCallTargetNode.findSpecialCallTarget(initialInvokeKind, args[0], initialTargetMethod, contextType);
if (specialCallTarget != null) {
invokeKind = InvokeKind.Special;
targetMethod = specialCallTarget;
}
}
JavaKind resultType = targetMethod.getSignature().getReturnKind();
if (!parsingIntrinsic() && DeoptALot.getValue(options)) {
append(new DeoptimizeNode(DeoptimizationAction.None, RuntimeConstraint));
frameState.pushReturn(resultType, ConstantNode.defaultForKind(resultType, graph));
return null;
}
JavaType returnType = targetMethod.getSignature().getReturnType(method.getDeclaringClass());
if (graphBuilderConfig.eagerResolving() || parsingIntrinsic()) {
returnType = returnType.resolve(targetMethod.getDeclaringClass());
}
if (invokeKind.hasReceiver()) {
args[0] = emitExplicitExceptions(args[0]);
}
if (initialInvokeKind == InvokeKind.Special && !targetMethod.isConstructor()) {
emitCheckForInvokeSuperSpecial(args);
}
InlineInfo inlineInfo = null;
try {
currentInvoke = new CurrentInvoke(args, invokeKind, returnType);
if (tryNodePluginForInvocation(args, targetMethod)) {
if (TraceParserPlugins.getValue(options)) {
traceWithContext("used node plugin for %s", targetMethod.format("%h.%n(%p)"));
}
return null;
}
if (invokeKind.hasReceiver() && args[0].isNullConstant()) {
append(new DeoptimizeNode(InvalidateRecompile, NullCheckException));
return null;
}
if (!invokeKind.isIndirect() || (UseGuardedIntrinsics.getValue(options) && !GeneratePIC.getValue(options))) {
if (tryInvocationPlugin(invokeKind, args, targetMethod, resultType, returnType)) {
if (TraceParserPlugins.getValue(options)) {
traceWithContext("used invocation plugin for %s", targetMethod.format("%h.%n(%p)"));
}
return null;
}
}
if (invokeKind.isDirect()) {
inlineInfo = tryInline(args, targetMethod);
if (inlineInfo == SUCCESSFULLY_INLINED) {
return null;
}
}
} finally {
currentInvoke = null;
}
int invokeBci = bci();
JavaTypeProfile profile = getProfileForInvoke(invokeKind);
ExceptionEdgeAction edgeAction = getActionForInvokeExceptionEdge(inlineInfo);
boolean partialIntrinsicExit = false;
if (intrinsicContext != null && intrinsicContext.isCallToOriginal(targetMethod)) {
partialIntrinsicExit = true;
ResolvedJavaMethod originalMethod = intrinsicContext.getOriginalMethod();
BytecodeParser intrinsicCallSiteParser = getNonIntrinsicAncestor();
if (intrinsicCallSiteParser != null) {
// When exiting a partial intrinsic, the invoke to the original
// must use the same context as the call to the intrinsic.
invokeBci = intrinsicCallSiteParser.bci();
profile = intrinsicCallSiteParser.getProfileForInvoke(invokeKind);
edgeAction = intrinsicCallSiteParser.getActionForInvokeExceptionEdge(inlineInfo);
} else {
// so the bci must be set to unknown, so that the inliner patches it later.
assert intrinsicContext.isPostParseInlined();
invokeBci = BytecodeFrame.UNKNOWN_BCI;
profile = null;
edgeAction = graph.method().getAnnotation(Snippet.class) == null ? ExceptionEdgeAction.INCLUDE_AND_HANDLE : ExceptionEdgeAction.OMIT;
}
if (originalMethod.isStatic()) {
invokeKind = InvokeKind.Static;
} else {
// The original call to the intrinsic must have been devirtualized
// otherwise we wouldn't be here.
invokeKind = InvokeKind.Special;
}
Signature sig = originalMethod.getSignature();
returnType = sig.getReturnType(method.getDeclaringClass());
resultType = sig.getReturnKind();
assert intrinsicContext.allowPartialIntrinsicArgumentMismatch() || checkPartialIntrinsicExit(intrinsicCallSiteParser == null ? null : intrinsicCallSiteParser.currentInvoke.args, args);
targetMethod = originalMethod;
}
Invoke invoke = createNonInlinedInvoke(edgeAction, invokeBci, args, targetMethod, invokeKind, resultType, returnType, profile);
if (partialIntrinsicExit) {
// This invoke must never be later inlined as it might select the intrinsic graph.
// Until there is a mechanism to guarantee that any late inlining will not select
// the intrinsic graph, prevent this invoke from being inlined.
invoke.setUseForInlining(false);
}
return invoke;
}
use of org.graalvm.compiler.nodes.DeoptimizeNode in project graal by oracle.
the class BytecodeParser method createExceptionDispatch.
private void createExceptionDispatch(ExceptionDispatchBlock block) {
lastInstr = finishInstruction(lastInstr, frameState);
assert frameState.stackSize() == 1 : frameState;
if (block.handler.isCatchAll()) {
assert block.getSuccessorCount() == 1;
appendGoto(block.getSuccessor(0));
return;
}
JavaType catchType = block.handler.getCatchType();
if (graphBuilderConfig.eagerResolving()) {
catchType = lookupType(block.handler.catchTypeCPI(), INSTANCEOF);
}
if (catchType instanceof ResolvedJavaType) {
TypeReference checkedCatchType = TypeReference.createTrusted(graph.getAssumptions(), (ResolvedJavaType) catchType);
if (graphBuilderConfig.getSkippedExceptionTypes() != null) {
for (ResolvedJavaType skippedType : graphBuilderConfig.getSkippedExceptionTypes()) {
if (skippedType.isAssignableFrom(checkedCatchType.getType())) {
BciBlock nextBlock = block.getSuccessorCount() == 1 ? blockMap.getUnwindBlock() : block.getSuccessor(1);
ValueNode exception = frameState.stack[0];
FixedNode trueSuccessor = graph.add(new DeoptimizeNode(InvalidateReprofile, UnreachedCode));
FixedNode nextDispatch = createTarget(nextBlock, frameState);
append(new IfNode(graph.addOrUniqueWithInputs(createInstanceOf(checkedCatchType, exception)), trueSuccessor, nextDispatch, 0));
return;
}
}
}
BciBlock nextBlock = block.getSuccessorCount() == 1 ? blockMap.getUnwindBlock() : block.getSuccessor(1);
ValueNode exception = frameState.stack[0];
/* Anchor for the piNode, which must be before any LoopExit inserted by createTarget. */
BeginNode piNodeAnchor = graph.add(new BeginNode());
ObjectStamp checkedStamp = StampFactory.objectNonNull(checkedCatchType);
PiNode piNode = graph.addWithoutUnique(new PiNode(exception, checkedStamp));
frameState.pop(JavaKind.Object);
frameState.push(JavaKind.Object, piNode);
FixedNode catchSuccessor = createTarget(block.getSuccessor(0), frameState);
frameState.pop(JavaKind.Object);
frameState.push(JavaKind.Object, exception);
FixedNode nextDispatch = createTarget(nextBlock, frameState);
piNodeAnchor.setNext(catchSuccessor);
IfNode ifNode = append(new IfNode(graph.unique(createInstanceOf(checkedCatchType, exception)), piNodeAnchor, nextDispatch, 0.5));
assert ifNode.trueSuccessor() == piNodeAnchor;
piNode.setGuard(ifNode.trueSuccessor());
} else {
handleUnresolvedExceptionType(catchType);
}
}
use of org.graalvm.compiler.nodes.DeoptimizeNode in project graal by oracle.
the class CollectDeoptimizationSourcePositionsPhase method run.
@Override
protected void run(StructuredGraph graph) {
List<NodeSourcePosition> deoptimzationSourcePositions = new ArrayList<>();
/*
* The debugId 0 is reserved for "unknown" to avoid any possible confusion with an
* uninitialized debugId.
*/
deoptimzationSourcePositions.add(null);
for (DeoptimizeNode node : graph.getNodes(DeoptimizeNode.TYPE)) {
node.setDebugId(deoptimzationSourcePositions.size());
deoptimzationSourcePositions.add(node.getNodeSourcePosition());
}
assert graph.getNodes(DynamicDeoptimizeNode.TYPE).isEmpty() : "must collect NodeSourcePosition before DeoptimizationGroupingPhase";
graph.addAfterFixed(graph.start(), graph.add(new DeoptSourcePositionInfoNode(deoptimzationSourcePositions)));
}
Aggregations