use of org.graalvm.compiler.nodes.java.ExceptionObjectNode in project graal by oracle.
the class IntrinsicContext method createFrameState.
public FrameState createFrameState(StructuredGraph graph, SideEffectsState sideEffects, StateSplit forStateSplit, NodeSourcePosition sourcePosition) {
assert forStateSplit != graph.start();
if (forStateSplit.hasSideEffect()) {
if (sideEffects.isAfterSideEffect()) {
// Only the last side effect on any execution path in a replacement
// can inherit the stateAfter of the replaced node
FrameState invalid = graph.add(new FrameState(INVALID_FRAMESTATE_BCI));
if (graph.trackNodeSourcePosition()) {
invalid.setNodeSourcePosition(sourcePosition);
}
for (StateSplit lastSideEffect : sideEffects.sideEffects()) {
lastSideEffect.setStateAfter(invalid);
}
}
sideEffects.addSideEffect(forStateSplit);
FrameState frameState;
if (forStateSplit instanceof ExceptionObjectNode) {
frameState = graph.add(new FrameState(AFTER_EXCEPTION_BCI, (ExceptionObjectNode) forStateSplit));
} else {
frameState = graph.add(new FrameState(AFTER_BCI));
}
if (graph.trackNodeSourcePosition()) {
frameState.setNodeSourcePosition(sourcePosition);
}
return frameState;
} else {
if (forStateSplit instanceof AbstractMergeNode) {
// Merge nodes always need a frame state
if (sideEffects.isAfterSideEffect()) {
// A merge after one or more side effects
FrameState frameState = graph.add(new FrameState(AFTER_BCI));
if (graph.trackNodeSourcePosition()) {
frameState.setNodeSourcePosition(sourcePosition);
}
return frameState;
} else {
// A merge before any side effects
FrameState frameState = graph.add(new FrameState(BEFORE_BCI));
if (graph.trackNodeSourcePosition()) {
frameState.setNodeSourcePosition(sourcePosition);
}
return frameState;
}
} else {
// Other non-side-effects do not need a state
return null;
}
}
}
use of org.graalvm.compiler.nodes.java.ExceptionObjectNode 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.java.ExceptionObjectNode in project graal by oracle.
the class MultiTypeGuardInlineInfo method inlineMultipleMethods.
private EconomicSet<Node> inlineMultipleMethods(StructuredGraph graph, Providers providers) {
int numberOfMethods = concretes.size();
FixedNode continuation = invoke.next();
// setup merge and phi nodes for results and exceptions
AbstractMergeNode returnMerge = graph.add(new MergeNode());
returnMerge.setStateAfter(invoke.stateAfter());
PhiNode returnValuePhi = null;
if (invoke.asNode().getStackKind() != JavaKind.Void) {
returnValuePhi = graph.addWithoutUnique(new ValuePhiNode(invoke.asNode().stamp(NodeView.DEFAULT).unrestricted(), returnMerge));
}
AbstractMergeNode exceptionMerge = null;
PhiNode exceptionObjectPhi = null;
if (invoke instanceof InvokeWithExceptionNode) {
InvokeWithExceptionNode invokeWithException = (InvokeWithExceptionNode) invoke;
ExceptionObjectNode exceptionEdge = (ExceptionObjectNode) invokeWithException.exceptionEdge();
exceptionMerge = graph.add(new MergeNode());
FixedNode exceptionSux = exceptionEdge.next();
graph.addBeforeFixed(exceptionSux, exceptionMerge);
exceptionObjectPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(JavaKind.Object), exceptionMerge));
exceptionMerge.setStateAfter(exceptionEdge.stateAfter().duplicateModified(invoke.stateAfter().bci, true, JavaKind.Object, new JavaKind[] { JavaKind.Object }, new ValueNode[] { exceptionObjectPhi }));
}
// create one separate block for each invoked method
AbstractBeginNode[] successors = new AbstractBeginNode[numberOfMethods + 1];
for (int i = 0; i < numberOfMethods; i++) {
successors[i] = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, true);
}
// create the successor for an unknown type
FixedNode unknownTypeSux;
if (shouldFallbackToInvoke()) {
unknownTypeSux = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, false);
} else {
unknownTypeSux = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated));
}
successors[successors.length - 1] = BeginNode.begin(unknownTypeSux);
// replace the invoke exception edge
if (invoke instanceof InvokeWithExceptionNode) {
InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invoke;
ExceptionObjectNode exceptionEdge = (ExceptionObjectNode) invokeWithExceptionNode.exceptionEdge();
exceptionEdge.replaceAtUsages(exceptionObjectPhi);
exceptionEdge.setNext(null);
GraphUtil.killCFG(invokeWithExceptionNode.exceptionEdge());
}
assert invoke.asNode().isAlive();
// replace the invoke with a switch on the type of the actual receiver
boolean methodDispatch = createDispatchOnTypeBeforeInvoke(graph, successors, false, providers.getStampProvider(), providers.getConstantReflection());
assert invoke.next() == continuation;
invoke.setNext(null);
returnMerge.setNext(continuation);
if (returnValuePhi != null) {
invoke.asNode().replaceAtUsages(returnValuePhi);
}
invoke.asNode().safeDelete();
ArrayList<PiNode> replacementNodes = new ArrayList<>();
// prepare the anchors for the invokes
for (int i = 0; i < numberOfMethods; i++) {
AbstractBeginNode node = successors[i];
Invoke invokeForInlining = (Invoke) node.next();
ResolvedJavaType commonType;
if (methodDispatch) {
commonType = concretes.get(i).getDeclaringClass();
} else {
commonType = getLeastCommonType(i);
}
ValueNode receiver = ((MethodCallTargetNode) invokeForInlining.callTarget()).receiver();
boolean exact = (getTypeCount(i) == 1 && !methodDispatch);
PiNode anchoredReceiver = InliningUtil.createAnchoredReceiver(graph, node, commonType, receiver, exact);
invokeForInlining.callTarget().replaceFirstInput(receiver, anchoredReceiver);
assert !anchoredReceiver.isDeleted() : anchoredReceiver;
replacementNodes.add(anchoredReceiver);
}
if (shouldFallbackToInvoke()) {
replacementNodes.add(null);
}
EconomicSet<Node> canonicalizeNodes = EconomicSet.create(Equivalence.DEFAULT);
// do the actual inlining for every invoke
for (int i = 0; i < numberOfMethods; i++) {
Invoke invokeForInlining = (Invoke) successors[i].next();
canonicalizeNodes.addAll(doInline(i, invokeForInlining));
}
if (returnValuePhi != null) {
canonicalizeNodes.add(returnValuePhi);
}
return canonicalizeNodes;
}
use of org.graalvm.compiler.nodes.java.ExceptionObjectNode in project graal by oracle.
the class TruffleBoundaryPhase method run.
@Override
@SuppressWarnings("deprecation")
protected void run(StructuredGraph graph) {
for (Node n : graph.getNodes()) {
if (n instanceof InvokeWithExceptionNode) {
InvokeWithExceptionNode invoke = (InvokeWithExceptionNode) n;
ExceptionObjectNode exceptionObject = (ExceptionObjectNode) invoke.exceptionEdge();
FixedNode originalNext = exceptionObject.next();
if (!(originalNext instanceof DeoptimizeNode)) {
TruffleBoundary truffleBoundary = invoke.callTarget().targetMethod().getAnnotation(TruffleBoundary.class);
if (truffleBoundary != null) {
if (!truffleBoundary.throwsControlFlowException() && truffleBoundary.transferToInterpreterOnException()) {
addDeoptimizeNode(graph, originalNext);
}
}
}
}
}
}
use of org.graalvm.compiler.nodes.java.ExceptionObjectNode in project graal by oracle.
the class CEntryPointCallStubMethod method buildGraph.
@Override
public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) {
UniverseMetaAccess metaAccess = (UniverseMetaAccess) providers.getMetaAccess();
NativeLibraries nativeLibraries = CEntryPointCallStubSupport.singleton().getNativeLibraries();
HostedGraphKit kit = new HostedGraphKit(debug, providers, method);
StructuredGraph graph = kit.getGraph();
JavaType[] parameterTypes = method.toParameterTypes();
JavaType[] parameterLoadTypes = Arrays.copyOf(parameterTypes, parameterTypes.length);
EnumInfo[] parameterEnumInfos;
parameterEnumInfos = adaptParameterTypes(providers, nativeLibraries, kit, parameterTypes, parameterLoadTypes, purpose);
ValueNode[] args = kit.loadArguments(parameterLoadTypes).toArray(new ValueNode[0]);
InvokeNode prologueInvoke = generatePrologue(providers, kit, parameterLoadTypes, args);
adaptArgumentValues(providers, kit, parameterTypes, parameterEnumInfos, args);
ResolvedJavaMethod unwrappedTargetMethod = targetMethod;
while (unwrappedTargetMethod instanceof WrappedJavaMethod) {
unwrappedTargetMethod = ((WrappedJavaMethod) unwrappedTargetMethod).getWrapped();
}
ResolvedJavaMethod universeTargetMethod = lookupMethodInUniverse(metaAccess, unwrappedTargetMethod);
int invokeBci = kit.bci();
int exceptionEdgeBci = kit.bci();
// Also support non-static test methods (they are not allowed to use the receiver)
InvokeKind invokeKind = universeTargetMethod.isStatic() ? InvokeKind.Static : InvokeKind.Special;
ValueNode[] invokeArgs = args;
if (invokeKind != InvokeKind.Static) {
invokeArgs = new ValueNode[args.length + 1];
invokeArgs[0] = kit.createObject(null);
System.arraycopy(args, 0, invokeArgs, 1, args.length);
}
InvokeWithExceptionNode invoke = kit.startInvokeWithException(universeTargetMethod, invokeKind, kit.getFrameState(), invokeBci, exceptionEdgeBci, invokeArgs);
kit.exceptionPart();
ExceptionObjectNode exception = kit.exceptionObject();
generateExceptionHandler(providers, kit, exception, invoke.getStackKind());
kit.endInvokeWithException();
ValueNode returnValue = adaptReturnValue(method, providers, purpose, metaAccess, nativeLibraries, kit, invoke);
InvokeNode epilogueInvoke = generateEpilogue(providers, kit);
kit.createReturn(returnValue, returnValue.getStackKind());
inlinePrologueAndEpilogue(kit, prologueInvoke, epilogueInvoke, invoke.getStackKind());
assert graph.verify();
return graph;
}
Aggregations