changeset 9753:6c2a7fc32416

Merge.
author Doug Simon <doug.simon@oracle.com>
date Thu, 16 May 2013 23:30:04 +0200
parents 82689c1c0dab (current diff) 4c2c99854535 (diff)
children 98b004bf3985
files graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java
diffstat 12 files changed, 228 insertions(+), 219 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Thu May 16 23:26:59 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Thu May 16 23:30:04 2013 +0200
@@ -53,7 +53,7 @@
 
     void shutdownCompiler() throws Throwable;
 
-    void startCompiler() throws Throwable;
+    void startCompiler(boolean bootstrapEnabled) throws Throwable;
 
     void bootstrap() throws Throwable;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Thu May 16 23:26:59 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Thu May 16 23:30:04 2013 +0200
@@ -101,7 +101,9 @@
         assert unsafe.getObject(mirror, offset) == type;
     }
 
-    public void startCompiler() throws Throwable {
+    public void startCompiler(boolean bootstrapEnabled) throws Throwable {
+
+        bootstrapRunning = bootstrapEnabled;
 
         HotSpotVMConfig config = graalRuntime.getConfig();
         long offset = config.graalMirrorInClassOffset;
@@ -339,7 +341,6 @@
         TTY.flush();
         long startTime = System.currentTimeMillis();
 
-        bootstrapRunning = true;
         boolean firstRun = true;
         do {
             // Initialize compile queue with a selected set of methods.
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java	Thu May 16 23:26:59 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java	Thu May 16 23:30:04 2013 +0200
@@ -358,6 +358,7 @@
      * @param object the object whose monitor will be locked.
      */
     public void pushLock(ValueNode object) {
+        assert object.isAlive() && object.kind() == Kind.Object : "unexpected value: " + object;
         locks = Arrays.copyOf(locks, locks.length + 1);
         locks[locks.length - 1] = object;
     }
@@ -406,7 +407,7 @@
      * @param x the instruction which produces the value for the local
      */
     public void storeLocal(int i, ValueNode x) {
-        assert x == null || x.kind() != Kind.Void && x.kind() != Kind.Illegal : "unexpected value: " + x;
+        assert x == null || x.isAlive() && x.kind() != Kind.Void && x.kind() != Kind.Illegal : "unexpected value: " + x;
         locals[i] = x;
         if (x != null && isTwoSlot(x.kind())) {
             // if this is a double word, then kill i+1
@@ -422,7 +423,7 @@
     }
 
     private void storeStack(int i, ValueNode x) {
-        assert x == null || stack[i] == null || x.kind() == stack[i].kind() : "Method does not handle changes from one-slot to two-slot values";
+        assert x == null || x.isAlive() && (stack[i] == null || x.kind() == stack[i].kind()) : "Method does not handle changes from one-slot to two-slot values or non-alive values";
         stack[i] = x;
     }
 
@@ -433,7 +434,7 @@
      * @param x the instruction to push onto the stack
      */
     public void push(Kind kind, ValueNode x) {
-        assert !x.isDeleted() && x.kind() != Kind.Void && x.kind() != Kind.Illegal;
+        assert x.isAlive() && x.kind() != Kind.Void && x.kind() != Kind.Illegal;
         xpush(assertKind(kind, x));
         if (isTwoSlot(kind)) {
             xpush(null);
@@ -446,7 +447,7 @@
      * @param x the instruction to push onto the stack
      */
     public void xpush(ValueNode x) {
-        assert x == null || (!x.isDeleted() && x.kind() != Kind.Void && x.kind() != Kind.Illegal);
+        assert x == null || (x.isAlive() && x.kind() != Kind.Void && x.kind() != Kind.Illegal);
         stack[stackSize++] = x;
     }
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Thu May 16 23:26:59 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Thu May 16 23:30:04 2013 +0200
@@ -304,8 +304,8 @@
      * @param type the unresolved type of the constant
      */
     protected void handleUnresolvedLoadConstant(JavaType type) {
-        append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)));
-        frameState.push(Kind.Object, append(ConstantNode.forObject(null, runtime, currentGraph)));
+        append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        frameState.push(Kind.Object, appendConstant(Constant.NULL_OBJECT));
     }
 
     /**
@@ -313,7 +313,7 @@
      * @param object the object value whose type is being checked against {@code type}
      */
     protected void handleUnresolvedCheckCast(JavaType type, ValueNode object) {
-        append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new IsNullNode(object)), Unresolved, InvalidateRecompile)));
+        append(new FixedGuardNode(currentGraph.unique(new IsNullNode(object)), Unresolved, InvalidateRecompile));
         frameState.apush(appendConstant(Constant.NULL_OBJECT));
     }
 
@@ -324,8 +324,7 @@
     protected void handleUnresolvedInstanceOf(JavaType type, ValueNode object) {
         BlockPlaceholderNode successor = currentGraph.add(new BlockPlaceholderNode());
         DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved));
-        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IsNullNode(object)), successor, deopt, 1));
-        append(ifNode);
+        append(new IfNode(currentGraph.unique(new IsNullNode(object)), successor, deopt, 1));
         lastInstr = successor;
         frameState.ipush(appendConstant(Constant.INT_0));
     }
@@ -334,7 +333,7 @@
      * @param type the type being instantiated
      */
     protected void handleUnresolvedNewInstance(JavaType type) {
-        append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)));
+        append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
         frameState.apush(appendConstant(Constant.NULL_OBJECT));
     }
 
@@ -343,7 +342,7 @@
      * @param length the length of the array
      */
     protected void handleUnresolvedNewObjectArray(JavaType type, ValueNode length) {
-        append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)));
+        append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
         frameState.apush(appendConstant(Constant.NULL_OBJECT));
     }
 
@@ -352,7 +351,7 @@
      * @param dims the dimensions for the multi-array
      */
     protected void handleUnresolvedNewMultiArray(JavaType type, ValueNode[] dims) {
-        append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)));
+        append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
         frameState.apush(appendConstant(Constant.NULL_OBJECT));
     }
 
@@ -362,8 +361,8 @@
      */
     protected void handleUnresolvedLoadField(JavaField field, ValueNode receiver) {
         Kind kind = field.getKind();
-        append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)));
-        frameState.push(kind.getStackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
+        append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
+        frameState.push(kind.getStackKind(), appendConstant(Constant.defaultForKind(kind)));
     }
 
     /**
@@ -372,7 +371,7 @@
      * @param receiver the object containing the field or {@code null} if {@code field} is static
      */
     protected void handleUnresolvedStoreField(JavaField field, ValueNode value, ValueNode receiver) {
-        append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)));
+        append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
     }
 
     /**
@@ -380,16 +379,16 @@
      * @param type
      */
     protected void handleUnresolvedExceptionType(Representation representation, JavaType type) {
-        append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)));
+        append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
     }
 
     protected void handleUnresolvedInvoke(JavaMethod javaMethod, InvokeKind invokeKind) {
         boolean withReceiver = invokeKind != InvokeKind.Static;
-        append(currentGraph.add(new DeoptimizeNode(InvalidateRecompile, Unresolved)));
+        append(new DeoptimizeNode(InvalidateRecompile, Unresolved));
         frameState.popArguments(javaMethod.getSignature().getParameterSlots(withReceiver), javaMethod.getSignature().getParameterCount(withReceiver));
         Kind kind = javaMethod.getSignature().getReturnKind();
         if (kind != Kind.Void) {
-            frameState.push(kind.getStackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
+            frameState.push(kind.getStackKind(), appendConstant(Constant.defaultForKind(kind)));
         }
     }
 
@@ -432,7 +431,7 @@
             // this is a load of class constant which might be unresolved
             JavaType type = (JavaType) con;
             if (type instanceof ResolvedJavaType) {
-                frameState.push(Kind.Object, append(ConstantNode.forConstant(((ResolvedJavaType) type).getEncoding(Representation.JavaClass), runtime, currentGraph)));
+                frameState.push(Kind.Object, appendConstant(((ResolvedJavaType) type).getEncoding(Representation.JavaClass)));
             } else {
                 handleUnresolvedLoadConstant(type);
             }
@@ -449,8 +448,7 @@
 
         ValueNode index = frameState.ipop();
         ValueNode array = frameState.apop();
-        ValueNode v = append(currentGraph.add(new LoadIndexedNode(array, index, kind)));
-        frameState.push(kind.getStackKind(), v);
+        frameState.push(kind.getStackKind(), append(new LoadIndexedNode(array, index, kind)));
     }
 
     private void genStoreIndexed(Kind kind) {
@@ -459,8 +457,7 @@
         ValueNode value = frameState.pop(kind.getStackKind());
         ValueNode index = frameState.ipop();
         ValueNode array = frameState.apop();
-        StoreIndexedNode result = currentGraph.add(new StoreIndexedNode(array, index, kind, value));
-        append(result);
+        append(new StoreIndexedNode(array, index, kind, value));
     }
 
     private void stackOp(int opcode) {
@@ -585,8 +582,7 @@
             default:
                 throw new GraalInternalError("should not reach");
         }
-        ValueNode result1 = append(currentGraph.unique(v));
-        frameState.push(result, result1);
+        frameState.push(result, append(v));
     }
 
     private void genIntegerDivOp(Kind result, int opcode) {
@@ -605,12 +601,11 @@
             default:
                 throw new GraalInternalError("should not reach");
         }
-        ValueNode result1 = append(currentGraph.add(v));
-        frameState.push(result, result1);
+        frameState.push(result, append(v));
     }
 
     private void genNegateOp(Kind kind) {
-        frameState.push(kind, append(currentGraph.unique(new NegateNode(frameState.pop(kind)))));
+        frameState.push(kind, append(new NegateNode(frameState.pop(kind))));
     }
 
     private void genShiftOp(Kind kind, int opcode) {
@@ -633,7 +628,7 @@
             default:
                 throw new GraalInternalError("should not reach");
         }
-        frameState.push(kind, append(currentGraph.unique(v)));
+        frameState.push(kind, append(v));
     }
 
     private void genLogicOp(Kind kind, int opcode) {
@@ -656,26 +651,26 @@
             default:
                 throw new GraalInternalError("should not reach");
         }
-        frameState.push(kind, append(currentGraph.unique(v)));
+        frameState.push(kind, append(v));
     }
 
     private void genCompareOp(Kind kind, boolean isUnorderedLess) {
         ValueNode y = frameState.pop(kind);
         ValueNode x = frameState.pop(kind);
-        frameState.ipush(append(currentGraph.unique(new NormalizeCompareNode(x, y, isUnorderedLess))));
+        frameState.ipush(append(new NormalizeCompareNode(x, y, isUnorderedLess)));
     }
 
     private void genConvert(ConvertNode.Op opcode) {
         ValueNode input = frameState.pop(opcode.from.getStackKind());
-        frameState.push(opcode.to.getStackKind(), append(currentGraph.unique(new ConvertNode(opcode, input))));
+        frameState.push(opcode.to.getStackKind(), append(new ConvertNode(opcode, input)));
     }
 
     private void genIncrement() {
         int index = stream().readLocalIndex();
         int delta = stream().readIncrement();
         ValueNode x = frameState.loadLocal(index);
-        ValueNode y = append(ConstantNode.forInt(delta, currentGraph));
-        frameState.storeLocal(index, append(currentGraph.unique(new IntegerAddNode(Kind.Int, x, y))));
+        ValueNode y = appendConstant(Constant.forInt(delta));
+        frameState.storeLocal(index, append(new IntegerAddNode(Kind.Int, x, y)));
     }
 
     private void genGoto() {
@@ -725,7 +720,7 @@
         AbstractBeginNode falseSuccessor = createBlockTarget(1 - probability, falseBlock, frameState);
 
         IfNode ifNode = negate ? new IfNode(condition, falseSuccessor, trueSuccessor, 1 - probability) : new IfNode(condition, trueSuccessor, falseSuccessor, probability);
-        append(currentGraph.add(ifNode));
+        append(ifNode);
     }
 
     private void genIfZero(Condition cond) {
@@ -749,9 +744,8 @@
 
     private void genThrow() {
         ValueNode exception = frameState.apop();
-        FixedGuardNode node = currentGraph.add(new FixedGuardNode(currentGraph.unique(new IsNullNode(exception)), NullCheckException, InvalidateReprofile, true));
-        append(node);
-        append(handleException(exception, bci()));
+        append(new FixedGuardNode(currentGraph.unique(new IsNullNode(exception)), NullCheckException, InvalidateReprofile, true));
+        lastInstr.setNext(handleException(exception, bci()));
     }
 
     private JavaType lookupType(int cpi, int bytecode) {
@@ -803,9 +797,8 @@
         ValueNode object = frameState.apop();
         if (type instanceof ResolvedJavaType) {
             JavaTypeProfile profileForTypeCheck = getProfileForTypeCheck((ResolvedJavaType) type);
-            CheckCastNode checkCast = currentGraph.add(new CheckCastNode((ResolvedJavaType) type, object, profileForTypeCheck, false));
-            append(checkCast);
-            frameState.apush(checkCast);
+            CheckCastNode checkCastNode = append(new CheckCastNode((ResolvedJavaType) type, object, profileForTypeCheck, false));
+            frameState.apush(checkCastNode);
         } else {
             handleUnresolvedCheckCast(type, object);
         }
@@ -818,8 +811,7 @@
         if (type instanceof ResolvedJavaType) {
             ResolvedJavaType resolvedType = (ResolvedJavaType) type;
             InstanceOfNode instanceOfNode = new InstanceOfNode((ResolvedJavaType) type, object, getProfileForTypeCheck(resolvedType));
-            ConditionalNode conditional = currentGraph.unique(new ConditionalNode(currentGraph.unique(instanceOfNode), ConstantNode.forInt(1, currentGraph), ConstantNode.forInt(0, currentGraph)));
-            frameState.ipush(append(conditional));
+            frameState.ipush(append(new ConditionalNode(currentGraph.unique(instanceOfNode), ConstantNode.forInt(1, currentGraph), ConstantNode.forInt(0, currentGraph))));
         } else {
             handleUnresolvedInstanceOf(type, object);
         }
@@ -828,8 +820,7 @@
     void genNewInstance(int cpi) {
         JavaType type = lookupType(cpi, NEW);
         if (type instanceof ResolvedJavaType && ((ResolvedJavaType) type).isInitialized()) {
-            NewInstanceNode n = currentGraph.add(new NewInstanceNode((ResolvedJavaType) type, true));
-            frameState.apush(append(n));
+            frameState.apush(append(new NewInstanceNode((ResolvedJavaType) type, true)));
         } else {
             handleUnresolvedNewInstance(type);
         }
@@ -870,16 +861,14 @@
     private void genNewPrimitiveArray(int typeCode) {
         Class<?> clazz = arrayTypeCodeToClass(typeCode);
         ResolvedJavaType elementType = runtime.lookupJavaType(clazz);
-        NewArrayNode nta = currentGraph.add(new NewArrayNode(elementType, frameState.ipop(), true));
-        frameState.apush(append(nta));
+        frameState.apush(append(new NewArrayNode(elementType, frameState.ipop(), true)));
     }
 
     private void genNewObjectArray(int cpi) {
         JavaType type = lookupType(cpi, ANEWARRAY);
         ValueNode length = frameState.ipop();
         if (type instanceof ResolvedJavaType) {
-            NewArrayNode n = currentGraph.add(new NewArrayNode((ResolvedJavaType) type, length, true));
-            frameState.apush(append(n));
+            frameState.apush(append(new NewArrayNode((ResolvedJavaType) type, length, true)));
         } else {
             handleUnresolvedNewObjectArray(type, length);
         }
@@ -894,8 +883,7 @@
             dims[i] = frameState.ipop();
         }
         if (type instanceof ResolvedJavaType) {
-            FixedWithNextNode n = currentGraph.add(new NewMultiArrayNode((ResolvedJavaType) type, dims));
-            frameState.apush(append(n));
+            frameState.apush(append(new NewMultiArrayNode((ResolvedJavaType) type, dims)));
         } else {
             handleUnresolvedNewMultiArray(type, dims);
         }
@@ -907,8 +895,7 @@
         Kind kind = field.getKind();
         ValueNode receiver = frameState.apop();
         if ((field instanceof ResolvedJavaField) && ((ResolvedJavaField) field).getDeclaringClass().isInitialized()) {
-            LoadFieldNode load = currentGraph.add(new LoadFieldNode(receiver, (ResolvedJavaField) field));
-            appendOptimizedLoadField(kind, load);
+            appendOptimizedLoadField(kind, new LoadFieldNode(receiver, (ResolvedJavaField) field));
         } else {
             handleUnresolvedLoadField(field, receiver);
         }
@@ -931,9 +918,7 @@
         }
         BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode());
         BlockPlaceholderNode falseSucc = currentGraph.add(new BlockPlaceholderNode());
-        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 0.1));
-
-        append(ifNode);
+        append(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 0.1));
         lastInstr = falseSucc;
 
         if (GraalOptions.OmitHotExceptionStacktrace) {
@@ -957,9 +942,7 @@
     private void emitBoundsCheck(ValueNode index, ValueNode length) {
         BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode());
         BlockPlaceholderNode falseSucc = currentGraph.add(new BlockPlaceholderNode());
-        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 0.9));
-
-        append(ifNode);
+        append(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 0.9));
         lastInstr = trueSucc;
 
         if (GraalOptions.OmitHotExceptionStacktrace) {
@@ -981,7 +964,7 @@
 
         emitNullCheck(receiver);
         if (outOfBoundsIndex != null) {
-            ValueNode length = append(currentGraph.add(new ArrayLengthNode(receiver)));
+            ValueNode length = append(new ArrayLengthNode(receiver));
             emitBoundsCheck(outOfBoundsIndex, length);
         }
         Debug.metric("ExplicitExceptions").increment();
@@ -993,8 +976,7 @@
         ValueNode value = frameState.pop(field.getKind().getStackKind());
         ValueNode receiver = frameState.apop();
         if (field instanceof ResolvedJavaField && ((ResolvedJavaField) field).getDeclaringClass().isInitialized()) {
-            StoreFieldNode store = currentGraph.add(new StoreFieldNode(receiver, (ResolvedJavaField) field, value));
-            appendOptimizedStoreField(store);
+            appendOptimizedStoreField(new StoreFieldNode(receiver, (ResolvedJavaField) field, value));
         } else {
             handleUnresolvedStoreField(field, value, receiver);
         }
@@ -1003,8 +985,7 @@
     private void genGetStatic(JavaField field) {
         Kind kind = field.getKind();
         if (field instanceof ResolvedJavaField && ((ResolvedJavaType) field.getDeclaringClass()).isInitialized()) {
-            LoadFieldNode load = currentGraph.add(new LoadFieldNode(null, (ResolvedJavaField) field));
-            appendOptimizedLoadField(kind, load);
+            appendOptimizedLoadField(kind, new LoadFieldNode(null, (ResolvedJavaField) field));
         } else {
             handleUnresolvedLoadField(field, null);
         }
@@ -1013,8 +994,7 @@
     private void genPutStatic(JavaField field) {
         ValueNode value = frameState.pop(field.getKind().getStackKind());
         if (field instanceof ResolvedJavaField && ((ResolvedJavaType) field.getDeclaringClass()).isInitialized()) {
-            StoreFieldNode store = currentGraph.add(new StoreFieldNode(null, (ResolvedJavaField) field, value));
-            appendOptimizedStoreField(store);
+            appendOptimizedStoreField(new StoreFieldNode(null, (ResolvedJavaField) field, value));
         } else {
             handleUnresolvedStoreField(field, value, null);
         }
@@ -1141,8 +1121,7 @@
     private void appendInvoke(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args) {
         Kind resultType = targetMethod.getSignature().getReturnKind();
         if (GraalOptions.DeoptALot) {
-            DeoptimizeNode deoptimize = currentGraph.add(new DeoptimizeNode(DeoptimizationAction.None, RuntimeConstraint));
-            append(deoptimize);
+            append(new DeoptimizeNode(DeoptimizationAction.None, RuntimeConstraint));
             frameState.pushReturn(resultType, ConstantNode.defaultForKind(resultType, currentGraph));
             return;
         }
@@ -1163,15 +1142,12 @@
         // be conservative if information was not recorded (could result in endless recompiles
         // otherwise)
         if (graphBuilderConfig.omitAllExceptionEdges() || (optimisticOpts.useExceptionProbability() && profilingInfo.getExceptionSeen(bci()) == TriState.FALSE)) {
-            InvokeNode invoke = new InvokeNode(callTarget, bci());
-            ValueNode result = appendWithBCI(currentGraph.add(invoke));
-            frameState.pushReturn(resultType, result);
-            return invoke;
+            frameState.pushReturn(resultType, append(new InvokeNode(callTarget, bci())));
+            return new InvokeNode(callTarget, bci());
         } else {
             DispatchBeginNode exceptionEdge = handleException(null, bci());
-            InvokeWithExceptionNode invoke = currentGraph.add(new InvokeWithExceptionNode(callTarget, exceptionEdge, bci()));
-            ValueNode result = append(invoke);
-            frameState.pushReturn(resultType, result);
+            InvokeWithExceptionNode invoke = append(new InvokeWithExceptionNode(callTarget, exceptionEdge, bci()));
+            frameState.pushReturn(resultType, invoke);
             Block nextBlock = currentBlock.successors.get(0);
 
             assert bci() == currentBlock.endBci;
@@ -1192,19 +1168,17 @@
     }
 
     private MonitorEnterNode genMonitorEnter(ValueNode x) {
-        MonitorEnterNode monitorEnter = currentGraph.add(new MonitorEnterNode(x, frameState.lockDepth()));
+        MonitorEnterNode monitorEnter = append(new MonitorEnterNode(x, frameState.lockDepth()));
         frameState.pushLock(x);
-        appendWithBCI(monitorEnter);
         return monitorEnter;
     }
 
     private MonitorExitNode genMonitorExit(ValueNode x) {
         ValueNode lockedObject = frameState.popLock();
-        MonitorExitNode monitorExit = currentGraph.add(new MonitorExitNode(x, frameState.lockDepth()));
         if (GraphUtil.originalValue(lockedObject) != GraphUtil.originalValue(x)) {
             throw new BailoutException("unbalanced monitors: mismatch at monitorexit, %s != %s", GraphUtil.originalValue(x), GraphUtil.originalValue(lockedObject));
         }
-        appendWithBCI(monitorExit);
+        MonitorExitNode monitorExit = append(new MonitorExitNode(x, frameState.lockDepth()));
         return monitorExit;
     }
 
@@ -1227,7 +1201,7 @@
         ValueNode local = frameState.loadLocal(localIndex);
         JsrScope scope = currentBlock.jsrScope;
         int retAddress = scope.nextReturnAddress();
-        append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new IntegerEqualsNode(local, ConstantNode.forInt(retAddress, currentGraph))), JavaSubroutineMismatch, InvalidateReprofile)));
+        append(new FixedGuardNode(currentGraph.unique(new IntegerEqualsNode(local, ConstantNode.forInt(retAddress, currentGraph))), JavaSubroutineMismatch, InvalidateReprofile));
         if (!successor.jsrScope.equals(scope.pop())) {
             throw new JsrNotSupportedBailout("unstructured control flow (ret leaves more than one scope)");
         }
@@ -1314,12 +1288,11 @@
         }
 
         double[] successorProbabilities = successorProbabilites(actualSuccessors.size(), keySuccessors, keyProbabilities);
-        IntegerSwitchNode switchNode = currentGraph.add(new IntegerSwitchNode(value, actualSuccessors.size(), keys, keyProbabilities, keySuccessors));
+        IntegerSwitchNode switchNode = append(new IntegerSwitchNode(value, actualSuccessors.size(), keys, keyProbabilities, keySuccessors));
         for (int i = 0; i < actualSuccessors.size(); i++) {
             switchNode.setBlockSuccessor(i, createBlockTarget(successorProbabilities[i], actualSuccessors.get(i), frameState));
         }
 
-        append(switchNode);
     }
 
     private static class SuccessorInfo {
@@ -1338,26 +1311,37 @@
         return ConstantNode.forConstant(constant, runtime, currentGraph);
     }
 
-    private ValueNode append(FixedNode fixed) {
-        lastInstr.setNext(fixed);
+    private <T extends ControlSinkNode> T append(T fixed) {
+        assert !fixed.isAlive() && !fixed.isDeleted() : "instruction should not have been appended yet";
+        assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")";
+        T added = currentGraph.add(fixed);
+        lastInstr.setNext(added);
         lastInstr = null;
-        return fixed;
-    }
-
-    protected ValueNode append(FixedWithNextNode x) {
-        return appendWithBCI(x);
+        return added;
     }
 
-    private static ValueNode append(ValueNode v) {
-        return v;
+    private <T extends ControlSplitNode> T append(T fixed) {
+        assert !fixed.isAlive() && !fixed.isDeleted() : "instruction should not have been appended yet";
+        assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")";
+        T added = currentGraph.add(fixed);
+        lastInstr.setNext(added);
+        lastInstr = null;
+        return added;
     }
 
-    protected ValueNode appendWithBCI(FixedWithNextNode x) {
-        assert x.predecessor() == null : "instruction should not have been appended yet";
+    protected <T extends FixedWithNextNode> T append(T fixed) {
+        assert !fixed.isAlive() && !fixed.isDeleted() : "instruction should not have been appended yet";
         assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")";
-        lastInstr.setNext(x);
-        lastInstr = x;
-        return x;
+        T added = currentGraph.add(fixed);
+        lastInstr.setNext(added);
+        lastInstr = added;
+        return added;
+    }
+
+    private <T extends FloatingNode> T append(T v) {
+        assert !(v instanceof ConstantNode);
+        T added = currentGraph.unique(v);
+        return added;
     }
 
     private static class Target {
@@ -1524,7 +1508,7 @@
 
     private ValueNode synchronizedObject(FrameStateBuilder state, ResolvedJavaMethod target) {
         if (isStatic(target.getModifiers())) {
-            return append(ConstantNode.forConstant(target.getDeclaringClass().getEncoding(Representation.JavaClass), runtime, currentGraph));
+            return appendConstant(target.getDeclaringClass().getEncoding(Representation.JavaClass));
         } else {
             return state.loadLocal(0);
         }
@@ -1589,11 +1573,9 @@
     private void createUnwind() {
         assert frameState.stackSize() == 1 : frameState;
         ValueNode exception = frameState.apop();
-        FixedGuardNode guard = currentGraph.add(new FixedGuardNode(currentGraph.unique(new IsNullNode(exception)), NullCheckException, InvalidateReprofile, true));
-        append(guard);
+        append(new FixedGuardNode(currentGraph.unique(new IsNullNode(exception)), NullCheckException, InvalidateReprofile, true));
         synchronizedEpilogue(FrameState.AFTER_EXCEPTION_BCI);
-        UnwindNode unwindNode = currentGraph.add(new UnwindNode(exception));
-        append(unwindNode);
+        append(new UnwindNode(exception));
     }
 
     private void createReturn() {
@@ -1602,7 +1584,7 @@
         assert frameState.stackSize() == 0;
 
         if (Modifier.isSynchronized(method.getModifiers())) {
-            append(currentGraph.add(new ValueAnchorNode(true, x)));
+            append(new ValueAnchorNode(true, x));
             assert !frameState.rethrowException();
         }
 
@@ -1610,15 +1592,13 @@
         if (frameState.lockDepth() != 0) {
             throw new BailoutException("unbalanced monitors");
         }
-        ReturnNode returnNode = currentGraph.add(new ReturnNode(x));
 
         if (graphBuilderConfig.eagerInfopointMode()) {
-            InfopointNode ipn = currentGraph.add(new InfopointNode(InfopointReason.METHOD_END));
+            InfopointNode ipn = append(new InfopointNode(InfopointReason.METHOD_END));
             ipn.setStateAfter(frameState.create(FrameState.AFTER_BCI));
-            append(ipn);
         }
 
-        append(returnNode);
+        append(new ReturnNode(x));
     }
 
     private void synchronizedEpilogue(int bci) {
@@ -1664,8 +1644,7 @@
             frameState.push(Kind.Object, exception);
             FixedNode nextDispatch = createTarget(nextBlock, frameState);
             checkCast.setNext(catchSuccessor);
-            IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new InstanceOfNode((ResolvedJavaType) catchType, exception, null)), checkCast, nextDispatch, 0.5));
-            append(ifNode);
+            append(new IfNode(currentGraph.unique(new InstanceOfNode((ResolvedJavaType) catchType, exception, null)), checkCast, nextDispatch, 0.5));
         }
     }
 
@@ -1731,9 +1710,8 @@
             if (graphBuilderConfig.eagerInfopointMode() && lnt != null) {
                 currentLineNumber = lnt.getLineNumber(bci);
                 if (currentLineNumber != previousLineNumber) {
-                    InfopointNode ipn = currentGraph.add(new InfopointNode(InfopointReason.LINE_NUMBER));
+                    InfopointNode ipn = append(new InfopointNode(InfopointReason.LINE_NUMBER));
                     ipn.setStateAfter(frameState.create(bci));
-                    append(ipn);
                     previousLineNumber = currentLineNumber;
                 }
             }
@@ -1746,8 +1724,7 @@
                 if (block.jsrScope != JsrScope.EMPTY_SCOPE) {
                     throw new BailoutException("OSR into a JSR scope is not supported");
                 }
-                EntryMarkerNode x = currentGraph.add(new EntryMarkerNode());
-                append(x);
+                EntryMarkerNode x = append(new EntryMarkerNode());
                 frameState.insertProxies(x);
                 x.setStateAfter(frameState.create(bci));
             }
@@ -2036,6 +2013,6 @@
     }
 
     private void genArrayLength() {
-        frameState.ipush(append(currentGraph.add(new ArrayLengthNode(frameState.apop()))));
+        frameState.ipush(append(new ArrayLengthNode(frameState.apop())));
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Thu May 16 23:26:59 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Thu May 16 23:30:04 2013 +0200
@@ -218,7 +218,7 @@
     }
 
     /**
-     * Unlinks a node from all its control flow neighbours and then removes it from its graph. The
+     * Unlinks a node from all its control flow neighbors and then removes it from its graph. The
      * node must have no {@linkplain Node#usages() usages}.
      * 
      * @param node the node to be unlinked and removed
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Thu May 16 23:26:59 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Thu May 16 23:30:04 2013 +0200
@@ -99,27 +99,34 @@
 
     @Override
     protected void run(final StructuredGraph graph) {
-        InliningData data = new InliningData();
-        data.pushGraph(graph, 1.0, 1.0);
+        InliningData data = new InliningData(graph, compilationAssumptions);
 
         while (data.hasUnprocessedGraphs()) {
+            MethodInvocation currentInvocation = data.currentInvocation();
             GraphInfo graphInfo = data.currentGraph();
-            if (graphInfo.hasRemainingInvokes() && inliningPolicy.continueInlining(data)) {
+            if (!currentInvocation.isRoot() && !inliningPolicy.isWorthInlining(currentInvocation.callee(), data.inliningDepth(), currentInvocation.probability(), currentInvocation.relevance(), false)) {
+                int remainingGraphs = currentInvocation.totalGraphs() - currentInvocation.processedGraphs();
+                assert remainingGraphs > 0;
+                data.popGraphs(remainingGraphs);
+                data.popInvocation();
+            } else if (graphInfo.hasRemainingInvokes() && inliningPolicy.continueInlining(graphInfo.graph())) {
                 processNextInvoke(data, graphInfo);
             } else {
                 data.popGraph();
-                MethodInvocation currentInvocation = data.currentInvocation();
-                if (currentInvocation != null) {
+                if (!currentInvocation.isRoot()) {
                     assert currentInvocation.callee().invoke().asNode().isAlive();
                     currentInvocation.incrementProcessedGraphs();
-                    if (currentInvocation.processedAllGraphs()) {
+                    if (currentInvocation.processedGraphs() == currentInvocation.totalGraphs()) {
                         data.popInvocation();
                         MethodInvocation parentInvoke = data.currentInvocation();
-                        tryToInline(data.currentGraph(), currentInvocation, parentInvoke);
+                        tryToInline(data.currentGraph(), currentInvocation, parentInvoke, data.inliningDepth() + 1);
                     }
                 }
             }
         }
+
+        assert data.inliningDepth() == 0;
+        assert data.graphCount() == 0;
     }
 
     /**
@@ -128,32 +135,35 @@
     private void processNextInvoke(InliningData data, GraphInfo graphInfo) {
         Invoke invoke = graphInfo.popInvoke();
         MethodInvocation callerInvocation = data.currentInvocation();
-        Assumptions parentAssumptions = callerInvocation == null ? compilationAssumptions : callerInvocation.assumptions();
+        Assumptions parentAssumptions = callerInvocation.assumptions();
         InlineInfo info = InliningUtil.getInlineInfo(data, invoke, maxMethodPerInlining, replacements, parentAssumptions, optimisticOpts);
 
-        double invokeProbability = graphInfo.invokeProbability(invoke);
-        double invokeRelevance = graphInfo.invokeRelevance(invoke);
-        if (info != null && inliningPolicy.isWorthInlining(info, invokeProbability, invokeRelevance, false)) {
-            MethodInvocation calleeInvocation = data.pushInvocation(info, parentAssumptions, invokeProbability, invokeRelevance);
+        if (info != null) {
+            double invokeProbability = graphInfo.invokeProbability(invoke);
+            double invokeRelevance = graphInfo.invokeRelevance(invoke);
+
+            if (inliningPolicy.isWorthInlining(info, data.inliningDepth(), invokeProbability, invokeRelevance, false)) {
+                MethodInvocation calleeInvocation = data.pushInvocation(info, parentAssumptions, invokeProbability, invokeRelevance);
 
-            for (int i = 0; i < info.numberOfMethods(); i++) {
-                InlineableElement elem = getInlineableElement(info.methodAt(i), info.invoke(), calleeInvocation.assumptions());
-                info.setInlinableElement(i, elem);
-                if (elem instanceof StructuredGraph) {
-                    data.pushGraph((StructuredGraph) elem, invokeProbability * info.probabilityAt(i), invokeRelevance * info.relevanceAt(i));
-                } else {
-                    assert elem instanceof InlineableMacroNode;
-                    data.pushDummyGraph();
+                for (int i = 0; i < info.numberOfMethods(); i++) {
+                    InlineableElement elem = getInlineableElement(info.methodAt(i), info.invoke(), calleeInvocation.assumptions());
+                    info.setInlinableElement(i, elem);
+                    if (elem instanceof StructuredGraph) {
+                        data.pushGraph((StructuredGraph) elem, invokeProbability * info.probabilityAt(i), invokeRelevance * info.relevanceAt(i));
+                    } else {
+                        assert elem instanceof InlineableMacroNode;
+                        data.pushDummyGraph();
+                    }
                 }
             }
         }
     }
 
-    private void tryToInline(GraphInfo callerGraphInfo, MethodInvocation calleeInfo, MethodInvocation parentInvocation) {
+    private void tryToInline(GraphInfo callerGraphInfo, MethodInvocation calleeInfo, MethodInvocation parentInvocation, int inliningDepth) {
         InlineInfo callee = calleeInfo.callee();
-        Assumptions callerAssumptions = parentInvocation == null ? compilationAssumptions : parentInvocation.assumptions();
+        Assumptions callerAssumptions = parentInvocation.assumptions();
 
-        if (inliningPolicy.isWorthInlining(callee, calleeInfo.probability(), calleeInfo.relevance(), true)) {
+        if (inliningPolicy.isWorthInlining(callee, inliningDepth, calleeInfo.probability(), calleeInfo.relevance(), true)) {
             doInline(callerGraphInfo, calleeInfo, callerAssumptions);
         } else if (optimisticOpts.devirtualizeInvokes()) {
             callee.tryToDevirtualizeInvoke(runtime, callerAssumptions);
@@ -399,32 +409,26 @@
             super(replacements, hints);
         }
 
-        public boolean continueInlining(InliningData data) {
-            if (data.currentGraph().graph().getNodeCount() >= GraalOptions.MaximumDesiredSize) {
+        public boolean continueInlining(StructuredGraph currentGraph) {
+            if (currentGraph.getNodeCount() >= GraalOptions.MaximumDesiredSize) {
                 InliningUtil.logInliningDecision("inlining is cut off by MaximumDesiredSize");
                 metricInliningStoppedByMaxDesiredSize.increment();
                 return false;
             }
-
-            MethodInvocation currentInvocation = data.currentInvocation();
-            if (currentInvocation == null) {
-                return true;
-            }
-
-            return isWorthInlining(currentInvocation.callee(), currentInvocation.probability(), currentInvocation.relevance(), false);
+            return true;
         }
 
         @Override
-        public boolean isWorthInlining(InlineInfo info, double probability, double relevance, boolean fullyProcessed) {
+        public boolean isWorthInlining(InlineInfo info, int inliningDepth, double probability, double relevance, boolean fullyProcessed) {
             if (isIntrinsic(info)) {
-                return InliningUtil.logInlinedMethod(info, fullyProcessed, "intrinsic");
+                return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "intrinsic");
             }
 
             double inliningBonus = getInliningBonus(info);
 
             int lowLevelGraphSize = previousLowLevelGraphSize(info);
             if (GraalOptions.SmallCompiledLowLevelGraphSize > 0 && lowLevelGraphSize > GraalOptions.SmallCompiledLowLevelGraphSize * inliningBonus) {
-                return InliningUtil.logNotInlinedMethod(info, "too large previous low-level graph: %d", lowLevelGraphSize);
+                return InliningUtil.logNotInlinedMethod(info, inliningDepth, "too large previous low-level graph: %d", lowLevelGraphSize);
             }
 
             /*
@@ -436,20 +440,20 @@
 
             int nodes = determineNodeCount(info);
             if (nodes < GraalOptions.TrivialInliningSize * inliningBonus) {
-                return InliningUtil.logInlinedMethod(info, fullyProcessed, "trivial (nodes=%d)", nodes);
+                return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "trivial (nodes=%d)", nodes);
             }
 
             double invokes = determineInvokeProbability(info);
             if (GraalOptions.LimitInlinedInvokes > 0 && fullyProcessed && invokes > GraalOptions.LimitInlinedInvokes * inliningBonus) {
-                return InliningUtil.logNotInlinedMethod(info, "invoke probability is too high (%f)", invokes);
+                return InliningUtil.logNotInlinedMethod(info, inliningDepth, "invoke probability is too high (%f)", invokes);
             }
 
             double maximumNodes = computeMaximumSize(relevance, (int) (GraalOptions.MaximumInliningSize * inliningBonus));
             if (nodes < maximumNodes) {
-                return InliningUtil.logInlinedMethod(info, fullyProcessed, "relevance-based (relevance=%f, nodes=%d)", relevance, nodes);
+                return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "relevance-based (relevance=%f, nodes=%d)", relevance, nodes);
             }
 
-            return InliningUtil.logNotInlinedMethod(info, "(relevance=%f, probability=%f, bonus=%f)", relevance, probability, inliningBonus);
+            return InliningUtil.logNotInlinedMethod(info, inliningDepth, "(relevance=%f, probability=%f, bonus=%f)", relevance, probability, inliningBonus);
         }
     }
 
@@ -466,8 +470,8 @@
             assert start.isAlive();
         }
 
-        public Stack<Invoke> apply() {
-            Stack<Invoke> invokes = new Stack<>();
+        public LinkedList<Invoke> apply() {
+            LinkedList<Invoke> invokes = new LinkedList<>();
             FixedNode current;
             forcedQueue(start);
 
@@ -476,7 +480,7 @@
 
                 if (current instanceof Invoke) {
                     if (current != start) {
-                        invokes.push((Invoke) current);
+                        invokes.addLast((Invoke) current);
                     }
                     queueSuccessors(current);
                 } else if (current instanceof LoopBeginNode) {
@@ -552,22 +556,30 @@
      */
     static class InliningData {
 
-        private static final GraphInfo DummyGraphInfo = new GraphInfo(null, new Stack<Invoke>(), 1.0, 1.0);
+        private static final GraphInfo DummyGraphInfo = new GraphInfo(null, new LinkedList<Invoke>(), 1.0, 1.0);
 
         private final ArrayDeque<GraphInfo> graphQueue;
         private final ArrayDeque<MethodInvocation> invocationQueue;
 
-        private int maxGraphs = 1;
+        private int maxGraphs;
 
-        public InliningData() {
+        public InliningData(StructuredGraph rootGraph, Assumptions rootAssumptions) {
             this.graphQueue = new ArrayDeque<>();
             this.invocationQueue = new ArrayDeque<>();
+            this.maxGraphs = 1;
+
+            invocationQueue.push(new MethodInvocation(null, rootAssumptions, 1.0, 1.0));
+            pushGraph(rootGraph, 1.0, 1.0);
+        }
+
+        public int graphCount() {
+            return graphQueue.size();
         }
 
         public void pushGraph(StructuredGraph graph, double probability, double relevance) {
             assert !contains(graph);
             NodeBitMap visitedFixedNodes = graph.createNodeBitMap();
-            Stack<Invoke> invokes = new InliningIterator(graph.start(), visitedFixedNodes).apply();
+            LinkedList<Invoke> invokes = new InliningIterator(graph.start(), visitedFixedNodes).apply();
             assert invokes.size() == count(graph.getInvokes());
             graphQueue.push(new GraphInfo(graph, invokes, probability, relevance));
             assert graphQueue.size() <= maxGraphs;
@@ -590,6 +602,13 @@
             assert graphQueue.size() <= maxGraphs;
         }
 
+        public void popGraphs(int count) {
+            assert count >= 0;
+            for (int i = 0; i < count; i++) {
+                graphQueue.pop();
+            }
+        }
+
         public MethodInvocation currentInvocation() {
             return invocationQueue.peek();
         }
@@ -619,7 +638,8 @@
         }
 
         public int inliningDepth() {
-            return invocationQueue.size();
+            assert invocationQueue.size() > 0;
+            return invocationQueue.size() - 1;
         }
 
         @Override
@@ -683,9 +703,13 @@
             assert processedGraphs <= callee.numberOfMethods();
         }
 
-        public boolean processedAllGraphs() {
+        public int processedGraphs() {
             assert processedGraphs <= callee.numberOfMethods();
-            return processedGraphs == callee.numberOfMethods();
+            return processedGraphs;
+        }
+
+        public int totalGraphs() {
+            return callee.numberOfMethods();
         }
 
         public InlineInfo callee() {
@@ -703,19 +727,23 @@
         public double relevance() {
             return relevance;
         }
+
+        public boolean isRoot() {
+            return callee == null;
+        }
     }
 
     private static class GraphInfo {
 
         private final StructuredGraph graph;
-        private final Stack<Invoke> remainingInvokes;
+        private final LinkedList<Invoke> remainingInvokes;
         private final double probability;
         private final double relevance;
 
         private NodesToDoubles nodeProbabilities;
         private NodesToDoubles nodeRelevance;
 
-        public GraphInfo(StructuredGraph graph, Stack<Invoke> invokes, double probability, double relevance) {
+        public GraphInfo(StructuredGraph graph, LinkedList<Invoke> invokes, double probability, double relevance) {
             this.graph = graph;
             this.remainingInvokes = invokes;
             this.probability = probability;
@@ -739,7 +767,7 @@
         }
 
         public Invoke popInvoke() {
-            return remainingInvokes.pop();
+            return remainingInvokes.removeFirst();
         }
 
         public void pushInvoke(Invoke invoke) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Thu May 16 23:26:59 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Thu May 16 23:30:04 2013 +0200
@@ -59,9 +59,9 @@
 
     public interface InliningPolicy {
 
-        boolean continueInlining(InliningData data);
+        boolean continueInlining(StructuredGraph graph);
 
-        boolean isWorthInlining(InlineInfo info, double probability, double relevance, boolean fullyProcessed);
+        boolean isWorthInlining(InlineInfo info, int inliningDepth, double probability, double relevance, boolean fullyProcessed);
     }
 
     public static class InlineableMacroNode implements InlineableElement {
@@ -90,14 +90,14 @@
     /**
      * Print a HotSpot-style inlining message to the console.
      */
-    private static void printInlining(final InlineInfo info, final boolean success, final String msg, final Object... args) {
-        printInlining(info.methodAt(0), info.invoke(), success, msg, args);
+    private static void printInlining(final InlineInfo info, final int inliningDepth, final boolean success, final String msg, final Object... args) {
+        printInlining(info.methodAt(0), info.invoke(), inliningDepth, success, msg, args);
     }
 
     /**
      * Print a HotSpot-style inlining message to the console.
      */
-    private static void printInlining(final ResolvedJavaMethod method, final Invoke invoke, final boolean success, final String msg, final Object... args) {
+    private static void printInlining(final ResolvedJavaMethod method, final Invoke invoke, final int inliningDepth, final boolean success, final String msg, final Object... args) {
         if (GraalOptions.HotSpotPrintInlining) {
             final int mod = method.getModifiers();
             // 1234567
@@ -108,25 +108,24 @@
             TTY.print("%c%c%c%c%c ", ' ', Modifier.isSynchronized(mod) ? 's' : ' ', ' ', ' ', Modifier.isNative(mod) ? 'n' : ' ');
             TTY.print("     ");        // more indent
             TTY.print("    ");         // initial inlining indent
-            final int level = computeInliningLevel(invoke);
-            for (int i = 0; i < level; i++) {
+            for (int i = 0; i < inliningDepth; i++) {
                 TTY.print("  ");
             }
             TTY.println(String.format("@ %d  %s   %s%s", invoke.bci(), methodName(method, null), success ? "" : "not inlining ", String.format(msg, args)));
         }
     }
 
-    public static boolean logInlinedMethod(InlineInfo info, boolean allowLogging, String msg, Object... args) {
-        return logInliningDecision(info, allowLogging, true, msg, args);
+    public static boolean logInlinedMethod(InlineInfo info, int inliningDepth, boolean allowLogging, String msg, Object... args) {
+        return logInliningDecision(info, inliningDepth, allowLogging, true, msg, args);
     }
 
-    public static boolean logNotInlinedMethod(InlineInfo info, String msg, Object... args) {
-        return logInliningDecision(info, true, false, msg, args);
+    public static boolean logNotInlinedMethod(InlineInfo info, int inliningDepth, String msg, Object... args) {
+        return logInliningDecision(info, inliningDepth, true, false, msg, args);
     }
 
-    public static boolean logInliningDecision(InlineInfo info, boolean allowLogging, boolean success, String msg, final Object... args) {
+    public static boolean logInliningDecision(InlineInfo info, int inliningDepth, boolean allowLogging, boolean success, String msg, final Object... args) {
         if (allowLogging) {
-            printInlining(info, success, msg, args);
+            printInlining(info, inliningDepth, success, msg, args);
             if (shouldLogInliningDecision()) {
                 logInliningDecision(methodName(info), success, msg, args);
             }
@@ -151,12 +150,12 @@
         return false;
     }
 
-    private static InlineInfo logNotInlinedMethodAndReturnNull(Invoke invoke, ResolvedJavaMethod method, String msg) {
-        return logNotInlinedMethodAndReturnNull(invoke, method, msg, new Object[0]);
+    private static InlineInfo logNotInlinedMethodAndReturnNull(Invoke invoke, int inliningDepth, ResolvedJavaMethod method, String msg) {
+        return logNotInlinedMethodAndReturnNull(invoke, inliningDepth, method, msg, new Object[0]);
     }
 
-    private static InlineInfo logNotInlinedMethodAndReturnNull(Invoke invoke, ResolvedJavaMethod method, String msg, Object... args) {
-        printInlining(method, invoke, false, msg, args);
+    private static InlineInfo logNotInlinedMethodAndReturnNull(Invoke invoke, int inliningDepth, ResolvedJavaMethod method, String msg, Object... args) {
+        printInlining(method, invoke, inliningDepth, false, msg, args);
         if (shouldLogInliningDecision()) {
             String methodString = methodName(method, invoke);
             logInliningDecision(methodString, false, msg, args);
@@ -164,8 +163,8 @@
         return null;
     }
 
-    private static boolean logNotInlinedMethodAndReturnFalse(Invoke invoke, ResolvedJavaMethod method, String msg) {
-        printInlining(method, invoke, false, msg, new Object[0]);
+    private static boolean logNotInlinedMethodAndReturnFalse(Invoke invoke, int inliningDepth, ResolvedJavaMethod method, String msg) {
+        printInlining(method, invoke, inliningDepth, false, msg, new Object[0]);
         if (shouldLogInliningDecision()) {
             String methodString = methodName(method, invoke);
             logInliningDecision(methodString, false, msg, new Object[0]);
@@ -1085,18 +1084,18 @@
             TypeProfileProxyNode typeProfileProxyNode = (TypeProfileProxyNode) receiver;
             typeProfile = typeProfileProxyNode.getProfile();
         } else {
-            return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "no type profile exists");
+            return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "no type profile exists");
         }
 
         ProfiledType[] ptypes = typeProfile.getTypes();
         if (ptypes == null || ptypes.length <= 0) {
-            return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "no types in profile");
+            return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "no types in profile");
         }
 
         double notRecordedTypeProbability = typeProfile.getNotRecordedProbability();
         if (ptypes.length == 1 && notRecordedTypeProbability == 0) {
             if (!optimisticOpts.inlineMonomorphicCalls()) {
-                return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "inlining monomorphic calls is disabled");
+                return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "inlining monomorphic calls is disabled");
             }
 
             ResolvedJavaType type = ptypes[0].getType();
@@ -1109,12 +1108,12 @@
             invoke.setPolymorphic(true);
 
             if (!optimisticOpts.inlinePolymorphicCalls() && notRecordedTypeProbability == 0) {
-                return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "inlining polymorphic calls is disabled (%d types)", ptypes.length);
+                return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "inlining polymorphic calls is disabled (%d types)", ptypes.length);
             }
             if (!optimisticOpts.inlineMegamorphicCalls() && notRecordedTypeProbability > 0) {
                 // due to filtering impossible types, notRecordedTypeProbability can be > 0 although
                 // the number of types is lower than what can be recorded in a type profile
-                return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "inlining megamorphic calls is disabled (%d types, %f %% not recorded types)", ptypes.length,
+                return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "inlining megamorphic calls is disabled (%d types, %f %% not recorded types)", ptypes.length,
                                 notRecordedTypeProbability * 100);
             }
 
@@ -1135,7 +1134,7 @@
             }
 
             if (concreteMethods.size() > maxNumberOfMethods) {
-                return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "polymorphic call with more than %d target methods", maxNumberOfMethods);
+                return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "polymorphic call with more than %d target methods", maxNumberOfMethods);
             }
 
             // Clear methods that fall below the threshold.
@@ -1151,7 +1150,8 @@
 
                 if (newConcreteMethods.size() == 0) {
                     // No method left that is worth inlining.
-                    return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "no methods remaining after filtering less frequent methods (%d methods previously)", concreteMethods.size());
+                    return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "no methods remaining after filtering less frequent methods (%d methods previously)",
+                                    concreteMethods.size());
                 }
 
                 concreteMethods = newConcreteMethods;
@@ -1174,12 +1174,12 @@
 
             if (usedTypes.size() == 0) {
                 // No type left that is worth checking for.
-                return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "no types remaining after filtering less frequent types (%d types previously)", ptypes.length);
+                return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "no types remaining after filtering less frequent types (%d types previously)", ptypes.length);
             }
 
             for (ResolvedJavaMethod concrete : concreteMethods) {
                 if (!checkTargetConditions(data, replacements, invoke, concrete, optimisticOpts)) {
-                    return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "it is a polymorphic method call and at least one invoked method cannot be inlined");
+                    return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "it is a polymorphic method call and at least one invoked method cannot be inlined");
                 }
             }
             return new MultiTypeGuardInlineInfo(invoke, concreteMethods, concreteMethodsProbabilities, usedTypes, typesToConcretes, notRecordedTypeProbability);
@@ -1214,34 +1214,24 @@
 
     private static boolean checkTargetConditions(InliningData data, Replacements replacements, Invoke invoke, ResolvedJavaMethod method, OptimisticOptimizations optimisticOpts) {
         if (method == null) {
-            return logNotInlinedMethodAndReturnFalse(invoke, method, "the method is not resolved");
+            return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the method is not resolved");
         } else if (Modifier.isNative(method.getModifiers()) && (!GraalOptions.Intrinsify || !InliningUtil.canIntrinsify(replacements, method))) {
-            return logNotInlinedMethodAndReturnFalse(invoke, method, "it is a non-intrinsic native method");
+            return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is a non-intrinsic native method");
         } else if (Modifier.isAbstract(method.getModifiers())) {
-            return logNotInlinedMethodAndReturnFalse(invoke, method, "it is an abstract method");
+            return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is an abstract method");
         } else if (!method.getDeclaringClass().isInitialized()) {
-            return logNotInlinedMethodAndReturnFalse(invoke, method, "the method's class is not initialized");
+            return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the method's class is not initialized");
         } else if (!method.canBeInlined()) {
-            return logNotInlinedMethodAndReturnFalse(invoke, method, "it is marked non-inlinable");
+            return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is marked non-inlinable");
         } else if (data.countRecursiveInlining(method) > GraalOptions.MaximumRecursiveInlining) {
-            return logNotInlinedMethodAndReturnFalse(invoke, method, "it exceeds the maximum recursive inlining depth");
+            return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it exceeds the maximum recursive inlining depth");
         } else if (new OptimisticOptimizations(method).lessOptimisticThan(optimisticOpts)) {
-            return logNotInlinedMethodAndReturnFalse(invoke, method, "the callee uses less optimistic optimizations than caller");
+            return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the callee uses less optimistic optimizations than caller");
         } else {
             return true;
         }
     }
 
-    private static int computeInliningLevel(Invoke invoke) {
-        int count = -1;
-        FrameState curState = invoke.stateAfter();
-        while (curState != null) {
-            count++;
-            curState = curState.outerFrameState();
-        }
-        return count;
-    }
-
     static MonitorExitNode findPrecedingMonitorExit(UnwindNode unwind) {
         Node pred = unwind.predecessor();
         while (pred != null) {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Thu May 16 23:26:59 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Thu May 16 23:30:04 2013 +0200
@@ -95,6 +95,7 @@
                             FixedNode fixed = (FixedNode) node;
                             if (identity == LocationNode.ANY_LOCATION || read.location().getLocationIdentity() == identity) {
                                 addPhantomReference(read, fixed);
+                                iter.remove();
                             }
                         }
                     }
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java	Thu May 16 23:26:59 2013 +0200
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java	Thu May 16 23:30:04 2013 +0200
@@ -114,6 +114,16 @@
     }
 
     private boolean isWord(ValueNode node) {
+        if (node instanceof ProxyNode) {
+            /*
+             * The proxy node will eventually get the same stamp as the value it is proxying.
+             * However, since we cannot guarantee the order in which isWord is called during the
+             * verification phase, the stamp assignment for the value might not have happened yet.
+             * Therefore, we check the proxied value directly instead of the proxy.
+             */
+            return isWord(((ProxyNode) node).value());
+        }
+
         return wordAccess.isWord(node);
     }
 
--- a/src/share/vm/graal/graalCompiler.cpp	Thu May 16 23:26:59 2013 +0200
+++ b/src/share/vm/graal/graalCompiler.cpp	Thu May 16 23:30:04 2013 +0200
@@ -95,7 +95,7 @@
       }
     }
     if (UseCompiler) {
-      VMToCompiler::startCompiler();
+      VMToCompiler::startCompiler(BootstrapGraal);
       _initialized = true;
       if (BootstrapGraal) {
         // We turn off CompileTheWorld and complete the VM startup so that
--- a/src/share/vm/graal/graalVMToCompiler.cpp	Thu May 16 23:26:59 2013 +0200
+++ b/src/share/vm/graal/graalVMToCompiler.cpp	Thu May 16 23:30:04 2013 +0200
@@ -123,12 +123,13 @@
   }
 }
 
-void VMToCompiler::startCompiler() {
+void VMToCompiler::startCompiler(jboolean bootstrap_enabled) {
   JavaThread* THREAD = JavaThread::current();
   JavaValue result(T_VOID);
   JavaCallArguments args;
   args.push_oop(instance());
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::startCompiler_name(), vmSymbols::void_method_signature(), &args, THREAD);
+  args.push_int(bootstrap_enabled);
+  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::startCompiler_name(), vmSymbols::bool_void_signature(), &args, THREAD);
   check_pending_exception("Error while calling startCompiler");
 }
 
--- a/src/share/vm/graal/graalVMToCompiler.hpp	Thu May 16 23:26:59 2013 +0200
+++ b/src/share/vm/graal/graalVMToCompiler.hpp	Thu May 16 23:30:04 2013 +0200
@@ -59,8 +59,8 @@
   // public abstract void shutdownCompiler();
   static void shutdownCompiler();
   
-  // public abstract void startCompiler();
-  static void startCompiler();
+  // public abstract void startCompiler(boolean bootstrapEnabled);
+  static void startCompiler(jboolean bootstrap_enabled);
   
   // public abstract void bootstrap();
   static void bootstrap();