changeset 15318:f299b1ed79eb

ininling: while fixing framestates, modify callee framestates rather than caller ones.
author Gilles Duboscq <duboscq@ssw.jku.at>
date Wed, 23 Apr 2014 16:16:48 +0200
parents 54d06efb0392
children 7f63d1ae2799
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java
diffstat 2 files changed, 32 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Wed Apr 23 11:49:51 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Wed Apr 23 16:16:48 2014 +0200
@@ -220,6 +220,19 @@
      * correctly in slot encoding: a long or double will be followed by a null slot.
      */
     public FrameState duplicateModified(int newBci, boolean newRethrowException, Kind popKind, ValueNode... pushedValues) {
+        return duplicateModified(newBci, method, newRethrowException, popKind, pushedValues);
+    }
+
+    /**
+     * Creates a copy of this frame state with one stack element of type popKind popped from the
+     * stack and the values in pushedValues pushed on the stack. The pushedValues will be formatted
+     * correctly in slot encoding: a long or double will be followed by a null slot.
+     */
+    public FrameState duplicateModified(Kind popKind, ValueNode... pushedValues) {
+        return duplicateModified(bci, method, rethrowException, popKind, pushedValues);
+    }
+
+    private FrameState duplicateModified(int newBci, ResolvedJavaMethod newMethod, boolean newRethrowException, Kind popKind, ValueNode... pushedValues) {
         ArrayList<ValueNode> copy = new ArrayList<>(values.subList(0, localsSize + stackSize));
         if (popKind != Kind.Void) {
             if (stackAt(stackSize() - 1) == null) {
@@ -238,7 +251,7 @@
         int newStackSize = copy.size() - localsSize;
         copy.addAll(values.subList(localsSize + stackSize, values.size()));
 
-        FrameState other = graph().add(new FrameState(method, newBci, copy, localsSize, newStackSize, newRethrowException, false, monitorIds, virtualObjectMappings));
+        FrameState other = graph().add(new FrameState(newMethod, newBci, copy, localsSize, newStackSize, newRethrowException, false, monitorIds, virtualObjectMappings));
         other.setOuterFrameState(outerFrameState());
         return other;
     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Wed Apr 23 11:49:51 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Wed Apr 23 16:16:48 2014 +0200
@@ -1408,11 +1408,26 @@
                 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)));
+                        /*
+                         * pop return kind from invoke's stateAfter and replace with this
+                         * frameState's return value (top of stack)
+                         */
+                        Node otherFrameState = stateAfter;
+                        if (returnKind != Kind.Void && frameState.stackSize() > 0) {
+                            otherFrameState = stateAfter.duplicateModified(returnKind, frameState.stackAt(0));
+                        }
+                        frameState.replaceAndDelete(otherFrameState);
                     } else if (frameState.bci == BytecodeFrame.AFTER_EXCEPTION_BCI || (frameState.bci == BytecodeFrame.UNWIND_BCI && !frameState.method().isSynchronized())) {
                         if (stateAtExceptionEdge != null) {
-                            frameState.replaceAndDelete(stateAtExceptionEdge);
+                            /*
+                             * pop exception object from invoke's stateAfter and replace with this
+                             * frameState's exception object (top of stack)
+                             */
+                            Node newFrameState = stateAtExceptionEdge;
+                            if (frameState.stackSize() > 0 && stateAtExceptionEdge.stackAt(0) != frameState.stackAt(0)) {
+                                newFrameState = stateAtExceptionEdge.duplicateModified(Kind.Object, frameState.stackAt(0));
+                            }
+                            frameState.replaceAndDelete(newFrameState);
                         } else {
                             handleMissingAfterExceptionFrameState(frameState);
                         }