changeset 19585:d28482893f28

Fix construction of unwind BEFORE_EXCEPTION_BCI frame states when inlining in the graph builder.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Tue, 24 Feb 2015 20:23:42 +0100
parents 6ccf3993b7f2
children 5b24a15988fe
files graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java
diffstat 3 files changed, 37 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Feb 24 20:11:04 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Feb 24 20:23:42 2015 +0100
@@ -283,11 +283,11 @@
                     if (startInstruction == currentGraph.start()) {
                         StartNode startNode = currentGraph.start();
                         if (method.isSynchronized()) {
-                            startNode.setStateAfter(frameState.create(BytecodeFrame.BEFORE_BCI));
+                            startNode.setStateAfter(createFrameState(BytecodeFrame.BEFORE_BCI));
                         } else {
                             frameState.clearNonLiveLocals(startBlock, liveness, true);
                             assert bci() == 0;
-                            startNode.setStateAfter(frameState.create(bci()));
+                            startNode.setStateAfter(createFrameState(bci()));
                         }
                     }
 
@@ -297,7 +297,7 @@
                         MonitorEnterNode monitorEnter = genMonitorEnter(methodSynchronizedObject);
                         frameState.clearNonLiveLocals(startBlock, liveness, true);
                         assert bci() == 0;
-                        monitorEnter.setStateAfter(frameState.create(bci()));
+                        monitorEnter.setStateAfter(createFrameState(bci()));
                     }
 
                     if (graphBuilderConfig.insertNonSafepointDebugInfo()) {
@@ -714,7 +714,7 @@
                 append(new IfNode(currentGraph.unique(new IsNullNode(receiver)), exception, falseSucc, 0.01));
                 lastInstr = falseSucc;
 
-                exception.setStateAfter(frameState.create(bci()));
+                exception.setStateAfter(createFrameState(bci()));
                 exception.setNext(handleException(exception, bci()));
             }
 
@@ -725,7 +725,7 @@
                 append(new IfNode(currentGraph.unique(IntegerBelowNode.create(index, length, constantReflection)), trueSucc, exception, 0.99));
                 lastInstr = trueSucc;
 
-                exception.setStateAfter(frameState.create(bci()));
+                exception.setStateAfter(createFrameState(bci()));
                 exception.setNext(handleException(exception, bci()));
             }
 
@@ -964,7 +964,7 @@
 
                 HIRFrameStateBuilder startFrameState = new HIRFrameStateBuilder(targetMethod, currentGraph, checkTypes, () -> {
                     if (lazyFrameState[0] == null) {
-                        lazyFrameState[0] = frameState.create(bci());
+                        lazyFrameState[0] = createFrameState(bci());
                     }
                     return lazyFrameState[0];
                 });
@@ -984,15 +984,6 @@
                 if (calleeBeforeUnwindNode != null) {
                     ValueNode calleeUnwindValue = parser.getUnwindValue();
                     assert calleeUnwindValue != null;
-                    if (calleeBeforeUnwindNode instanceof AbstractMergeNode) {
-                        AbstractMergeNode mergeNode = (AbstractMergeNode) calleeBeforeUnwindNode;
-                        HIRFrameStateBuilder dispatchState = frameState.copy();
-                        dispatchState.clearStack();
-                        dispatchState.apush(calleeUnwindValue);
-                        dispatchState.setRethrowException(true);
-                        mergeNode.setStateAfter(dispatchState.create(bci()));
-
-                    }
                     calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci()));
                 }
 
@@ -1016,7 +1007,7 @@
                 DispatchBeginNode exceptionEdge = handleException(null, bci());
                 InvokeWithExceptionNode invoke = append(new InvokeWithExceptionNode(callTarget, exceptionEdge, bci()));
                 frameState.pushReturn(resultType, invoke);
-                invoke.setStateAfter(frameState.create(stream.nextBCI()));
+                invoke.setStateAfter(createFrameState(stream.nextBCI()));
                 return invoke;
             }
 
@@ -1573,7 +1564,7 @@
                     if (block instanceof ExceptionDispatchBlock) {
                         bci = ((ExceptionDispatchBlock) block).deoptBci;
                     }
-                    abstractMergeNode.setStateAfter(frameState.create(bci));
+                    abstractMergeNode.setStateAfter(createFrameState(bci));
                 }
             }
 
@@ -1614,7 +1605,7 @@
                     if (currentReturnValue != null) {
                         frameState.push(currentReturnValue.getKind(), currentReturnValue);
                     }
-                    monitorExit.setStateAfter(frameState.create(bci));
+                    monitorExit.setStateAfter(createFrameState(bci));
                     assert !frameState.rethrowException();
                 }
             }
@@ -1689,7 +1680,7 @@
 
                     // Create phi functions for all local variables and operand stack slots.
                     frameState.insertLoopPhis(liveness, block.loopId, loopBegin);
-                    loopBegin.setStateAfter(frameState.create(block.startBci));
+                    loopBegin.setStateAfter(createFrameState(block.startBci));
 
                     /*
                      * We have seen all forward branches. All subsequent backward branches will
@@ -1735,7 +1726,7 @@
                         }
                         EntryMarkerNode x = append(new EntryMarkerNode());
                         frameState.insertProxies(x);
-                        x.setStateAfter(frameState.create(bci));
+                        x.setStateAfter(createFrameState(bci));
                     }
                     processBytecode(bci, opcode);
 
@@ -1755,7 +1746,7 @@
                         } else {
                             StateSplit stateSplit = (StateSplit) lastInstr;
                             if (stateSplit.stateAfter() == null) {
-                                stateSplit.setStateAfter(frameState.create(bci));
+                                stateSplit.setStateAfter(createFrameState(bci));
                             }
                         }
                     }
@@ -1785,7 +1776,7 @@
 
             private InfopointNode createInfoPointNode(InfopointReason reason) {
                 if (graphBuilderConfig.insertFullDebugInfo()) {
-                    return new FullInfopointNode(reason, frameState.create(bci()));
+                    return new FullInfopointNode(reason, createFrameState(bci()));
                 } else {
                     return new SimpleInfopointNode(reason, new BytecodePosition(null, method, bci()));
                 }
@@ -2022,11 +2013,15 @@
             }
 
             public BailoutException bailout(String string) {
-                FrameState currentFrameState = this.frameState.create(bci());
+                FrameState currentFrameState = createFrameState(bci());
                 StackTraceElement[] elements = GraphUtil.approxSourceStackTraceElement(currentFrameState);
                 BailoutException bailout = new BailoutException(string);
                 throw GraphUtil.createBailoutException(string, bailout, elements);
             }
+
+            private FrameState createFrameState(int bci) {
+                return frameState.create(bci);
+            }
         }
     }
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java	Tue Feb 24 20:11:04 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java	Tue Feb 24 20:23:42 2015 +0100
@@ -201,6 +201,10 @@
         FrameState outerFrameState = null;
         if (outerFrameStateSupplier != null) {
             outerFrameState = outerFrameStateSupplier.get();
+            if (bci == BytecodeFrame.AFTER_EXCEPTION_BCI) {
+                FrameState newFrameState = outerFrameState.duplicateModified(outerFrameState.bci, true, Kind.Void, this.peek(0));
+                return newFrameState;
+            }
         }
         return graph.add(new FrameState(outerFrameState, method, bci, locals, stack, stackSize, lockedObjects, Arrays.asList(monitorIds), rethrowException, false));
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Tue Feb 24 20:11:04 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Tue Feb 24 20:23:42 2015 +0100
@@ -251,14 +251,20 @@
      * changed to newBci.
      */
     private FrameState duplicateModified(int newBci, boolean newRethrowException, boolean newDuringCall, Kind popKind, ValueNode... pushedValues) {
-        ArrayList<ValueNode> copy = new ArrayList<>(values.subList(0, localsSize + stackSize));
-        if (popKind != Kind.Void) {
-            if (stackAt(stackSize() - 1) == null) {
+        ArrayList<ValueNode> copy;
+        if (newRethrowException && !rethrowException && popKind == Kind.Void) {
+            assert popKind == Kind.Void;
+            copy = new ArrayList<>(values.subList(0, localsSize));
+        } else {
+            copy = new ArrayList<>(values.subList(0, localsSize + stackSize));
+            if (popKind != Kind.Void) {
+                if (stackAt(stackSize() - 1) == null) {
+                    copy.remove(copy.size() - 1);
+                }
+                ValueNode lastSlot = copy.get(copy.size() - 1);
+                assert lastSlot.getKind().getStackKind() == popKind.getStackKind();
                 copy.remove(copy.size() - 1);
             }
-            ValueNode lastSlot = copy.get(copy.size() - 1);
-            assert lastSlot.getKind().getStackKind() == popKind.getStackKind();
-            copy.remove(copy.size() - 1);
         }
         for (ValueNode node : pushedValues) {
             copy.add(node);
@@ -269,7 +275,7 @@
         int newStackSize = copy.size() - localsSize;
         copy.addAll(values.subList(localsSize + stackSize, values.size()));
 
-        assert checkStackDepth(bci, stackSize, duringCall, newBci, newStackSize, newDuringCall);
+        assert checkStackDepth(bci, stackSize, duringCall, rethrowException, newBci, newStackSize, newDuringCall, newRethrowException);
         return graph().add(new FrameState(outerFrameState(), method, newBci, copy, localsSize, newStackSize, newRethrowException, newDuringCall, monitorIds, virtualObjectMappings));
     }
 
@@ -277,7 +283,7 @@
      * Perform a few sanity checks on the transformation of the stack state. The current expectation
      * is that a stateAfter is being transformed into a stateDuring, so the stack depth may change.
      */
-    private boolean checkStackDepth(int oldBci, int oldStackSize, boolean oldDuringCall, int newBci, int newStackSize, boolean newDuringCall) {
+    private boolean checkStackDepth(int oldBci, int oldStackSize, boolean oldDuringCall, boolean oldRethrowException, int newBci, int newStackSize, boolean newDuringCall, boolean newRethrowException) {
         /*
          * It would be nice to have a complete check of the shape of the FrameState based on a
          * dataflow of the bytecodes but for now just check for obvious expression stack depth
@@ -290,7 +296,7 @@
         }
         byte newCode = codes[newBci];
         if (oldBci == newBci) {
-            assert oldStackSize == newStackSize || oldDuringCall != newDuringCall : "bci is unchanged, stack depth shouldn't change";
+            assert oldStackSize == newStackSize || oldDuringCall != newDuringCall || oldRethrowException != newRethrowException : "bci is unchanged, stack depth shouldn't change";
         } else {
             byte oldCode = codes[oldBci];
             assert Bytecodes.lengthOf(newCode) + newBci == oldBci || Bytecodes.lengthOf(oldCode) + oldBci == newBci : "expecting roll back or forward";