changeset 2634:4dd0573f510b

FrameState fixes.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Wed, 11 May 2011 10:52:37 +0200
parents 721a45190d6d
children 0f69be73d5ce
files graal/GraalCompiler/.classpath graal/GraalCompiler/src/com/sun/c1x/alloc/LinearScan.java graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java graal/GraalCompiler/src/com/sun/c1x/ir/NewArray.java graal/GraalCompiler/src/com/sun/c1x/ir/NewInstance.java graal/GraalCompiler/src/com/sun/c1x/ir/ResolveClass.java graal/GraalCompiler/src/com/sun/c1x/ir/StateSplit.java
diffstat 9 files changed, 100 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/graal/GraalCompiler/.classpath	Tue May 10 18:12:26 2011 +0200
+++ b/graal/GraalCompiler/.classpath	Wed May 11 10:52:37 2011 +0200
@@ -1,9 +1,9 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" exported="true" kind="src" path="/CRI"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/GraalGraph"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/GraalGraphviz"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" exported="true" kind="src" path="/CRI"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/GraalGraph"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/GraalGraphviz"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
--- a/graal/GraalCompiler/src/com/sun/c1x/alloc/LinearScan.java	Tue May 10 18:12:26 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/alloc/LinearScan.java	Wed May 11 10:52:37 2011 +0200
@@ -653,7 +653,7 @@
                                 if (!liveKill.get(operandNum)) {
                                     liveGen.set(operandNum);
                                     if (C1XOptions.TraceLinearScanLevel >= 4) {
-                                        TTY.println("  Setting liveGen for value %s, LIR opId %d, operand %d", Util.valueString(value), op.id, operandNum);
+                                        TTY.println("  Setting liveGen for value %s, LIR opId %d, operand %d because of state for " + op.toString(), Util.valueString(value), op.id, operandNum);
                                     }
                                 }
                             } else if (operand.isRegister()) {
--- a/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java	Tue May 10 18:12:26 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java	Wed May 11 10:52:37 2011 +0200
@@ -229,6 +229,19 @@
 
         for (Instruction instr = block; instr != null; instr = instr.next()) {
             FrameState stateAfter = instr.stateAfter();
+            FrameState stateBefore = null;
+            if (instr instanceof StateSplit && ((StateSplit) instr).stateBefore() != null) {
+                stateBefore = ((StateSplit) instr).stateBefore();
+            }
+            if (stateBefore != null) {
+                lastState = stateBefore;
+                if (C1XOptions.TraceLIRGeneratorLevel >= 2) {
+                    TTY.println("STATE CHANGE (stateBefore)");
+                    if (C1XOptions.TraceLIRGeneratorLevel >= 3) {
+                        TTY.println(stateBefore.toString());
+                    }
+                }
+            }
             if (!(instr instanceof BlockBegin)) {
                 walkState(instr, stateAfter);
                 doRoot(instr);
@@ -297,7 +310,7 @@
 
     @Override
     public void visitResolveClass(ResolveClass i) {
-        LIRDebugInfo info = stateFor(i, i.stateAfter());
+        LIRDebugInfo info = stateFor(i);
         XirSnippet snippet = xir.genResolveClass(site(i), i.type, i.portion);
         emitXir(snippet, i, info, null, true);
     }
@@ -313,7 +326,7 @@
     public void visitInstanceOf(InstanceOf x) {
         XirArgument obj = toXirArgument(x.object());
         XirSnippet snippet = xir.genInstanceOf(site(x), obj, toXirArgument(x.targetClassInstruction()), x.targetClass());
-        emitXir(snippet, x, maybeStateFor(x), null, true);
+        emitXir(snippet, x, stateFor(x), null, true);
     }
 
     @Override
@@ -321,7 +334,7 @@
         XirArgument obj = toXirArgument(x.object());
         XirArgument lockAddress = toXirArgument(x.lockAddress());
         XirSnippet snippet = xir.genMonitorEnter(site(x), obj, lockAddress);
-        emitXir(snippet, x, maybeStateFor(x), stateFor(x, x.stateAfter()), null, true, null);
+        emitXir(snippet, x, stateFor(x), stateFor(x, x.stateAfter()), null, true, null);
     }
 
     @Override
@@ -329,7 +342,7 @@
         XirArgument obj = toXirArgument(x.object());
         XirArgument lockAddress = toXirArgument(x.lockAddress());
         XirSnippet snippet = xir.genMonitorExit(site(x), obj, lockAddress);
-        emitXir(snippet, x, maybeStateFor(x), null, true);
+        emitXir(snippet, x, stateFor(x), null, true);
     }
 
     @Override
@@ -339,7 +352,7 @@
         XirArgument index = toXirArgument(x.index());
         XirArgument value = toXirArgument(x.value());
         XirSnippet snippet = xir.genArrayStore(site(x), array, index, length, value, x.elementKind(), null);
-        emitXir(snippet, x, maybeStateFor(x), null, true);
+        emitXir(snippet, x, stateFor(x), null, true);
     }
 
     @Override
@@ -405,7 +418,7 @@
         });
 
         XirSnippet snippet = xir.genExceptionObject(site(x));
-        emitXir(snippet, x, maybeStateFor(x), null, true);
+        emitXir(snippet, x, stateFor(x), null, true);
     }
 
     @Override
@@ -548,7 +561,7 @@
         XirArgument index = toXirArgument(x.index());
         XirArgument length = toXirArgument(x.length());
         XirSnippet snippet = xir.genArrayLoad(site(x), array, index, length, x.elementKind(), null);
-        emitXir(snippet, x, maybeStateFor(x), null, true);
+        emitXir(snippet, x, stateFor(x), null, true);
     }
 
     protected GlobalStub stubFor(CiRuntimeCall runtimeCall) {
@@ -1464,13 +1477,6 @@
         }
     }
 
-    protected LIRDebugInfo maybeStateFor(Instruction x) {
-        if (x.stateAfter() == null) {
-            return null;
-        }
-        return stateFor(x, x.stateAfter());
-    }
-
     protected LIRDebugInfo stateFor(Instruction x) {
         assert lastState != null : "must have state before instruction for " + x;
         return stateFor(x, lastState);
@@ -1603,7 +1609,7 @@
         }
 
         public boolean requiresNullCheck() {
-            return current == null || current.canTrap();
+            return current == null || current.canTrap() || current instanceof InstanceOf || current instanceof CheckCast;
         }
 
         public boolean requiresBoundsCheck() {
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Tue May 10 18:12:26 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Wed May 11 10:52:37 2011 +0200
@@ -344,7 +344,8 @@
             // this is a load of class constant which might be unresolved
             RiType riType = (RiType) con;
             if (!riType.isResolved() || C1XOptions.TestPatching) {
-                frameState.push(CiKind.Object, append(new ResolveClass(riType, RiType.Representation.JavaClass, graph)));
+                ResolveClass rc = new ResolveClass(riType, RiType.Representation.JavaClass, graph, frameState.create(bci()));
+                frameState.push(CiKind.Object, append(rc));
             } else {
                 frameState.push(CiKind.Object, append(new Constant(riType.getEncoding(Representation.JavaClass), graph)));
             }
@@ -585,27 +586,42 @@
 
     void genNewInstance(int cpi) {
         RiType type = constantPool().lookupType(cpi, NEW);
+        FrameState stateBefore = null;
+        if (!type.isResolved()) {
+            stateBefore = frameState.create(bci());
+        }
         NewInstance n = new NewInstance(type, cpi, constantPool(), graph);
         if (memoryMap != null) {
             memoryMap.newInstance(n);
         }
+        n.setStateBefore(stateBefore);
         frameState.apush(append(n));
     }
 
     void genNewTypeArray(int typeCode) {
         CiKind kind = CiKind.fromArrayTypeCode(typeCode);
         RiType elementType = compilation.runtime.asRiType(kind);
-        frameState.apush(append(new NewTypeArray(frameState.ipop(), elementType, graph)));
+        NewTypeArray nta = new NewTypeArray(frameState.ipop(), elementType, graph);
+        frameState.apush(append(nta));
     }
 
     void genNewObjectArray(int cpi) {
         RiType type = constantPool().lookupType(cpi, ANEWARRAY);
+        FrameState stateBefore = null;
+        if (!type.isResolved()) {
+            stateBefore = frameState.create(bci());
+        }
         NewArray n = new NewObjectArray(type, frameState.ipop(), graph);
         frameState.apush(append(n));
+        n.setStateBefore(stateBefore);
     }
 
     void genNewMultiArray(int cpi) {
         RiType type = constantPool().lookupType(cpi, MULTIANEWARRAY);
+        FrameState stateBefore = null;
+        if (!type.isResolved()) {
+            stateBefore = frameState.create(bci());
+        }
         int rank = stream().readUByte(bci() + 3);
         Value[] dims = new Value[rank];
         for (int i = rank - 1; i >= 0; i--) {
@@ -613,26 +629,41 @@
         }
         NewArray n = new NewMultiArray(type, dims, cpi, constantPool(), graph);
         frameState.apush(append(n));
+        n.setStateBefore(stateBefore);
     }
 
     void genGetField(int cpi, RiField field) {
         // Must copy the state here, because the field holder must still be on the stack.
+        FrameState stateBefore = null;
+        if (!field.isResolved()) {
+            stateBefore = frameState.create(bci());
+        }
         LoadField load = new LoadField(frameState.apop(), field, graph);
         appendOptimizedLoadField(field.kind(), load);
+        load.setStateBefore(stateBefore);
     }
 
     void genPutField(int cpi, RiField field) {
         // Must copy the state here, because the field holder must still be on the stack.
+        FrameState stateBefore = null;
+        if (!field.isResolved()) {
+            stateBefore = frameState.create(bci());
+        }
         Value value = frameState.pop(field.kind().stackKind());
-        appendOptimizedStoreField(new StoreField(frameState.apop(), field, value, graph));
+        StoreField store = new StoreField(frameState.apop(), field, value, graph);
+        appendOptimizedStoreField(store);
+        store.setStateBefore(stateBefore);
     }
 
     void genGetStatic(int cpi, RiField field) {
         RiType holder = field.holder();
         boolean isInitialized = !C1XOptions.TestPatching && field.isResolved();
         CiConstant constantValue = null;
+        FrameState stateBefore = null;
         if (isInitialized) {
             constantValue = field.constantValue(null);
+        } else {
+            stateBefore = frameState.create(bci());
         }
         if (constantValue != null) {
             frameState.push(constantValue.kind.stackKind(), appendConstant(constantValue));
@@ -640,15 +671,21 @@
             Value container = genResolveClass(RiType.Representation.StaticFields, holder, field.isResolved(), cpi);
             LoadField load = new LoadField(container, field, graph);
             appendOptimizedLoadField(field.kind(), load);
+            load.setStateBefore(stateBefore);
         }
     }
 
     void genPutStatic(int cpi, RiField field) {
         RiType holder = field.holder();
+        FrameState stateBefore = null;
+        if (!field.isResolved()) {
+            stateBefore = frameState.create(bci());
+        }
         Value container = genResolveClass(RiType.Representation.StaticFields, holder, field.isResolved(), cpi);
         Value value = frameState.pop(field.kind().stackKind());
         StoreField store = new StoreField(container, field, value, graph);
         appendOptimizedStoreField(store);
+        store.setStateBefore(stateBefore);
     }
 
     private Value genResolveClass(RiType.Representation representation, RiType holder, boolean initialized, int cpi) {
@@ -656,7 +693,7 @@
         if (initialized) {
             holderInstr = appendConstant(holder.getEncoding(representation));
         } else {
-            ResolveClass rc = new ResolveClass(holder, representation, graph);
+            ResolveClass rc = new ResolveClass(holder, representation, graph, frameState.create(bci()));
             holderInstr = append(rc);
         }
         return holderInstr;
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java	Tue May 10 18:12:26 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java	Wed May 11 10:52:37 2011 +0200
@@ -39,7 +39,7 @@
  * about the basic block, including the successor and
  * predecessor blocks, exception handlers, liveness information, etc.
  */
-public final class BlockBegin extends Instruction {
+public final class BlockBegin extends StateSplit {
 
     private static final int INPUT_COUNT = 1;
     private static final int INPUT_STATE_BEFORE = 0;
@@ -58,24 +58,17 @@
     }
 
     /**
-     * The frame state before execution of the first instruction in this block.
-     */
-    public FrameState stateBefore() {
-        return (FrameState) inputs().get(super.inputCount() + INPUT_STATE_BEFORE);
-    }
-
-    public FrameState setStateBefore(FrameState n) {
-        assert stateBefore() == null;
-        return (FrameState) inputs().set(super.inputCount() + INPUT_STATE_BEFORE, n);
-    }
-
-    /**
      * The last node in the block (which contains the successors).
      */
     public BlockEnd end() {
         return (BlockEnd) successors().get(super.successorCount() + SUCCESSOR_END);
     }
 
+    @Override
+    public boolean needsStateAfter() {
+        return false;
+    }
+
     public void setEnd(BlockEnd end) {
         assert end != null;
         BlockEnd old = this.end();
@@ -124,8 +117,6 @@
      */
     private int blockFlags;
 
-    private FrameState stateAfter;
-
     /**
      * The {@link BlockBegin} nodes for which this node is a successor.
      */
@@ -215,15 +206,6 @@
         return loopIndex;
     }
 
-    public void setStateAfter(FrameState stateAfter) {
-        this.stateAfter = stateAfter;
-    }
-
-    @Override
-    public FrameState stateAfter() {
-        return stateAfter;
-    }
-
     /**
      * Gets the exception handlers that cover one or more instructions of this basic block.
      *
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/NewArray.java	Tue May 10 18:12:26 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/NewArray.java	Wed May 11 10:52:37 2011 +0200
@@ -28,7 +28,7 @@
 /**
  * The {@code NewArray} class is the base of all instructions that allocate arrays.
  */
-public abstract class NewArray extends Instruction {
+public abstract class NewArray extends StateSplit {
 
     private static final int INPUT_COUNT = 1;
     private static final int INPUT_LENGTH = 0;
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/NewInstance.java	Tue May 10 18:12:26 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/NewInstance.java	Wed May 11 10:52:37 2011 +0200
@@ -30,7 +30,7 @@
 /**
  * The {@code NewInstance} instruction represents the allocation of an instance class object.
  */
-public final class NewInstance extends Instruction {
+public final class NewInstance extends StateSplit {
 
     private static final int INPUT_COUNT = 0;
     private static final int SUCCESSOR_COUNT = 0;
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/ResolveClass.java	Tue May 10 18:12:26 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ResolveClass.java	Wed May 11 10:52:37 2011 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.graph.*;
 import com.sun.c1x.debug.*;
+import com.sun.c1x.value.*;
 import com.sun.cri.ci.*;
 import com.sun.cri.ri.*;
 
@@ -39,11 +40,12 @@
     public final RiType type;
     public final RiType.Representation portion;
 
-    public ResolveClass(RiType type, RiType.Representation r, Graph graph) {
+    public ResolveClass(RiType type, RiType.Representation r, Graph graph, FrameState stateBefore) {
         super(type.getRepresentationKind(r), INPUT_COUNT, SUCCESSOR_COUNT, graph);
         this.portion = r;
         this.type = type;
         setFlag(Flag.NonNull);
+        setStateBefore(stateBefore);
     }
 
     @Override
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/StateSplit.java	Tue May 10 18:12:26 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/StateSplit.java	Wed May 11 10:52:37 2011 +0200
@@ -32,8 +32,9 @@
  */
 public abstract class StateSplit extends Instruction {
 
-    private static final int INPUT_COUNT = 1;
+    private static final int INPUT_COUNT = 2;
     private static final int INPUT_STATE_AFTER = 0;
+    private static final int INPUT_STATE_BEFORE = 1;
 
     private static final int SUCCESSOR_COUNT = 0;
 
@@ -56,10 +57,25 @@
     }
 
     public FrameState setStateAfter(FrameState n) {
+        if (n != null && this instanceof BlockBegin) {
+            Exception e = new Exception();
+            e.printStackTrace();
+        }
         return (FrameState) inputs().set(super.inputCount() + INPUT_STATE_AFTER, n);
     }
 
     /**
+     * The state for this instruction.
+     */
+    public FrameState stateBefore() {
+        return (FrameState) inputs().get(super.inputCount() + INPUT_STATE_BEFORE);
+    }
+
+    public FrameState setStateBefore(FrameState n) {
+        return (FrameState) inputs().set(super.inputCount() + INPUT_STATE_BEFORE, n);
+    }
+
+    /**
      * Creates a new state split with the specified value type.
      * @param kind the type of the value that this instruction produces
      * @param inputCount