# HG changeset patch # User Gilles Duboscq # Date 1398185643 -7200 # Node ID 051935b55555db6e471218d1a4d9f3fec8c679a3 # Parent ad3441f45118e498e701f70dc0c7ce42cf0f0b71 Remove special handling of monitor exit with AFTER_EXCEPTION_BCI in inlining. Anything using a framestate that has no equivalent after inlining is replaced by a deopt. diff -r ad3441f45118 -r 051935b55555 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StateSplit.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StateSplit.java Tue Apr 22 18:31:01 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StateSplit.java Tue Apr 22 18:54:03 2014 +0200 @@ -29,6 +29,8 @@ */ public interface StateSplit extends NodeWithState { + FixedNode asNode(); + /** * Gets the {@link FrameState} corresponding to the state of the JVM after execution of this * node. diff -r ad3441f45118 -r 051935b55555 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Tue Apr 22 18:31:01 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Tue Apr 22 18:54:03 2014 +0200 @@ -1399,19 +1399,8 @@ } else { if (unwindNode != null) { UnwindNode unwindDuplicate = (UnwindNode) duplicates.get(unwindNode); - MonitorExitNode monitorExit = findPrecedingMonitorExit(unwindDuplicate); - DeoptimizeNode deoptimizeNode = new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler); - unwindDuplicate.replaceAndDelete(graph.add(deoptimizeNode)); - // move the deopt upwards if there is a monitor exit that tries to use the - // "after exception" frame state - // (because there is no "after exception" frame state!) - if (monitorExit != null) { - if (monitorExit.stateAfter() != null && monitorExit.stateAfter().bci == BytecodeFrame.AFTER_EXCEPTION_BCI) { - FrameState monitorFrameState = monitorExit.stateAfter(); - graph.removeFixed(monitorExit); - monitorFrameState.safeDelete(); - } - } + DeoptimizeNode deoptimizeNode = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler)); + unwindDuplicate.replaceAndDelete(deoptimizeNode); } } @@ -1420,22 +1409,25 @@ int callerLockDepth = stateAfter.nestedLockDepth(); for (FrameState original : inlineGraph.getNodes(FrameState.class)) { FrameState frameState = (FrameState) duplicates.get(original); - if (frameState != null) { + if (frameState != null && frameState.isAlive()) { assert frameState.bci != BytecodeFrame.BEFORE_BCI : frameState; if (frameState.bci == BytecodeFrame.AFTER_BCI) { frameState.replaceAndDelete(returnKind == Kind.Void ? stateAfter : stateAfter.duplicateModified(stateAfter.bci, stateAfter.rethrowException(), returnKind, frameState.stackAt(0))); - } else if (frameState.bci == BytecodeFrame.AFTER_EXCEPTION_BCI) { - if (frameState.isAlive()) { - assert stateAtExceptionEdge != null; + } else if (frameState.bci == BytecodeFrame.AFTER_EXCEPTION_BCI || (frameState.bci == BytecodeFrame.UNWIND_BCI && !frameState.method().isSynchronized())) { + if (stateAtExceptionEdge != null) { frameState.replaceAndDelete(stateAtExceptionEdge); } else { - assert stateAtExceptionEdge == null; + handleMissingAfterExceptionFrameState(frameState); } + } else if (frameState.bci == BytecodeFrame.UNWIND_BCI) { + handleMissingAfterExceptionFrameState(frameState); } else { // only handle the outermost frame states if (frameState.outerFrameState() == null) { assert frameState.bci == BytecodeFrame.INVALID_FRAMESTATE_BCI || frameState.method().equals(inlineGraph.method()); + assert frameState.bci != BytecodeFrame.AFTER_EXCEPTION_BCI && frameState.bci != BytecodeFrame.BEFORE_BCI && frameState.bci != BytecodeFrame.AFTER_EXCEPTION_BCI && + frameState.bci != BytecodeFrame.UNWIND_BCI : frameState.bci; if (outerFrameState == null) { outerFrameState = stateAfter.duplicateModified(invoke.bci(), stateAfter.rethrowException(), invokeNode.getKind()); outerFrameState.setDuringCall(true); @@ -1482,6 +1474,39 @@ return duplicates; } + protected static void handleMissingAfterExceptionFrameState(FrameState nonReplacableFrameState) { + Graph graph = nonReplacableFrameState.graph(); + NodeWorkList workList = graph.createNodeWorkList(); + workList.add(nonReplacableFrameState); + 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 MergeNode) { + MergeNode merge = (MergeNode) fixedStateSplit; + while (merge.isAlive()) { + AbstractEndNode end = merge.forwardEnds().first(); + DeoptimizeNode deoptimizeNode = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler)); + end.replaceAtPredecessor(deoptimizeNode); + GraphUtil.killCFG(end); + } + } else { + DeoptimizeNode deoptimizeNode = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler)); + fixedStateSplit.replaceAtPredecessor(deoptimizeNode); + GraphUtil.killCFG(fixedStateSplit); + } + } + } + } + } + public static ValueNode mergeReturns(MergeNode merge, List returnNodes) { PhiNode returnValuePhi = null;