changeset 19535:97b35083d49d

Reduce casting in AbstractBytecodeParser. Consolidate asserts in HIRFrameStateBuilder.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sun, 22 Feb 2015 15:19:54 +0100
parents 50b19dc35c66
children 2c3ea61e8b65
files graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java
diffstat 3 files changed, 601 insertions(+), 146 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Sun Feb 22 14:41:35 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Sun Feb 22 15:19:54 2015 +0100
@@ -42,7 +42,7 @@
 import com.oracle.graal.options.*;
 import com.oracle.graal.phases.*;
 
-public abstract class AbstractBytecodeParser<T extends KindProvider, F extends AbstractFrameStateBuilder<T, F>> {
+public abstract class AbstractBytecodeParser {
 
     static class Options {
         // @formatter:off
@@ -63,7 +63,7 @@
      */
     public static final int TRACELEVEL_STATE = 2;
 
-    protected F frameState;
+    protected HIRFrameStateBuilder frameState;
     protected BciBlock currentBlock;
 
     protected final BytecodeStream stream;
@@ -97,7 +97,7 @@
         assert metaAccess != null;
     }
 
-    public void setCurrentFrameState(F frameState) {
+    public void setCurrentFrameState(HIRFrameStateBuilder frameState) {
         this.frameState = frameState;
     }
 
@@ -114,7 +114,7 @@
     }
 
     public void storeLocal(Kind kind, int index) {
-        T value;
+        ValueNode value;
         if (kind == Kind.Object) {
             value = frameState.xpop();
             // astore and astore_<n> may be used to store a returnAddress (jsr)
@@ -134,13 +134,13 @@
      * @param type the unresolved type of the type check
      * @param object the object value whose type is being checked against {@code type}
      */
-    protected abstract void handleUnresolvedCheckCast(JavaType type, T object);
+    protected abstract void handleUnresolvedCheckCast(JavaType type, ValueNode object);
 
     /**
      * @param type the unresolved type of the type check
      * @param object the object value whose type is being checked against {@code type}
      */
-    protected abstract void handleUnresolvedInstanceOf(JavaType type, T object);
+    protected abstract void handleUnresolvedInstanceOf(JavaType type, ValueNode object);
 
     /**
      * @param type the type being instantiated
@@ -151,26 +151,26 @@
      * @param type the type of the array being instantiated
      * @param length the length of the array
      */
-    protected abstract void handleUnresolvedNewObjectArray(JavaType type, T length);
+    protected abstract void handleUnresolvedNewObjectArray(JavaType type, ValueNode length);
 
     /**
      * @param type the type being instantiated
      * @param dims the dimensions for the multi-array
      */
-    protected abstract void handleUnresolvedNewMultiArray(JavaType type, List<T> dims);
+    protected abstract void handleUnresolvedNewMultiArray(JavaType type, List<ValueNode> dims);
 
     /**
      * @param field the unresolved field
      * @param receiver the object containing the field or {@code null} if {@code field} is static
      */
-    protected abstract void handleUnresolvedLoadField(JavaField field, T receiver);
+    protected abstract void handleUnresolvedLoadField(JavaField field, ValueNode receiver);
 
     /**
      * @param field the unresolved field
      * @param value the value being stored to the field
      * @param receiver the object containing the field or {@code null} if {@code field} is static
      */
-    protected abstract void handleUnresolvedStoreField(JavaField field, T value, T receiver);
+    protected abstract void handleUnresolvedStoreField(JavaField field, ValueNode value, ValueNode receiver);
 
     /**
      * @param type
@@ -179,7 +179,7 @@
 
     // protected abstract void handleUnresolvedInvoke(JavaMethod javaMethod, InvokeKind invokeKind);
 
-    // protected abstract DispatchBeginNode handleException(T exceptionObject, int bci);
+    // protected abstract DispatchBeginNode handleException(ValueNode exceptionObject, int bci);
 
     private void genLoadConstant(int cpi, int opcode) {
         Object con = lookupConstant(cpi, opcode);
@@ -200,24 +200,24 @@
         }
     }
 
-    protected abstract T genLoadIndexed(T index, T array, Kind kind);
+    protected abstract ValueNode genLoadIndexed(ValueNode index, ValueNode array, Kind kind);
 
     private void genLoadIndexed(Kind kind) {
         emitExplicitExceptions(frameState.peek(1), frameState.peek(0));
 
-        T index = frameState.ipop();
-        T array = frameState.apop();
+        ValueNode index = frameState.ipop();
+        ValueNode array = frameState.apop();
         frameState.push(kind.getStackKind(), append(genLoadIndexed(array, index, kind)));
     }
 
-    protected abstract T genStoreIndexed(T array, T index, Kind kind, T value);
+    protected abstract ValueNode genStoreIndexed(ValueNode array, ValueNode index, Kind kind, ValueNode value);
 
     private void genStoreIndexed(Kind kind) {
         emitExplicitExceptions(frameState.peek(2), frameState.peek(1));
 
-        T value = frameState.pop(kind.getStackKind());
-        T index = frameState.ipop();
-        T array = frameState.apop();
+        ValueNode value = frameState.pop(kind.getStackKind());
+        ValueNode index = frameState.ipop();
+        ValueNode array = frameState.apop();
         append(genStoreIndexed(array, index, kind, value));
     }
 
@@ -233,23 +233,23 @@
                 break;
             }
             case DUP: {
-                T w = frameState.xpop();
+                ValueNode w = frameState.xpop();
                 frameState.xpush(w);
                 frameState.xpush(w);
                 break;
             }
             case DUP_X1: {
-                T w1 = frameState.xpop();
-                T w2 = frameState.xpop();
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
                 frameState.xpush(w1);
                 frameState.xpush(w2);
                 frameState.xpush(w1);
                 break;
             }
             case DUP_X2: {
-                T w1 = frameState.xpop();
-                T w2 = frameState.xpop();
-                T w3 = frameState.xpop();
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
+                ValueNode w3 = frameState.xpop();
                 frameState.xpush(w1);
                 frameState.xpush(w3);
                 frameState.xpush(w2);
@@ -257,8 +257,8 @@
                 break;
             }
             case DUP2: {
-                T w1 = frameState.xpop();
-                T w2 = frameState.xpop();
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
                 frameState.xpush(w2);
                 frameState.xpush(w1);
                 frameState.xpush(w2);
@@ -266,9 +266,9 @@
                 break;
             }
             case DUP2_X1: {
-                T w1 = frameState.xpop();
-                T w2 = frameState.xpop();
-                T w3 = frameState.xpop();
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
+                ValueNode w3 = frameState.xpop();
                 frameState.xpush(w2);
                 frameState.xpush(w1);
                 frameState.xpush(w3);
@@ -277,10 +277,10 @@
                 break;
             }
             case DUP2_X2: {
-                T w1 = frameState.xpop();
-                T w2 = frameState.xpop();
-                T w3 = frameState.xpop();
-                T w4 = frameState.xpop();
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
+                ValueNode w3 = frameState.xpop();
+                ValueNode w4 = frameState.xpop();
                 frameState.xpush(w2);
                 frameState.xpush(w1);
                 frameState.xpush(w4);
@@ -290,8 +290,8 @@
                 break;
             }
             case SWAP: {
-                T w1 = frameState.xpop();
-                T w2 = frameState.xpop();
+                ValueNode w1 = frameState.xpop();
+                ValueNode w2 = frameState.xpop();
                 frameState.xpush(w1);
                 frameState.xpush(w2);
                 break;
@@ -301,27 +301,27 @@
         }
     }
 
-    protected abstract T genIntegerAdd(Kind kind, T x, T y);
+    protected abstract ValueNode genIntegerAdd(Kind kind, ValueNode x, ValueNode y);
 
-    protected abstract T genIntegerSub(Kind kind, T x, T y);
+    protected abstract ValueNode genIntegerSub(Kind kind, ValueNode x, ValueNode y);
 
-    protected abstract T genIntegerMul(Kind kind, T x, T y);
+    protected abstract ValueNode genIntegerMul(Kind kind, ValueNode x, ValueNode y);
 
-    protected abstract T genFloatAdd(Kind kind, T x, T y, boolean isStrictFP);
+    protected abstract ValueNode genFloatAdd(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP);
 
-    protected abstract T genFloatSub(Kind kind, T x, T y, boolean isStrictFP);
+    protected abstract ValueNode genFloatSub(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP);
 
-    protected abstract T genFloatMul(Kind kind, T x, T y, boolean isStrictFP);
+    protected abstract ValueNode genFloatMul(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP);
 
-    protected abstract T genFloatDiv(Kind kind, T x, T y, boolean isStrictFP);
+    protected abstract ValueNode genFloatDiv(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP);
 
-    protected abstract T genFloatRem(Kind kind, T x, T y, boolean isStrictFP);
+    protected abstract ValueNode genFloatRem(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP);
 
     private void genArithmeticOp(Kind result, int opcode) {
-        T y = frameState.pop(result);
-        T x = frameState.pop(result);
+        ValueNode y = frameState.pop(result);
+        ValueNode x = frameState.pop(result);
         boolean isStrictFP = method.isStrict();
-        T v;
+        ValueNode v;
         switch (opcode) {
             case IADD:
             case LADD:
@@ -361,14 +361,14 @@
         frameState.push(result, append(v));
     }
 
-    protected abstract T genIntegerDiv(Kind kind, T x, T y);
+    protected abstract ValueNode genIntegerDiv(Kind kind, ValueNode x, ValueNode y);
 
-    protected abstract T genIntegerRem(Kind kind, T x, T y);
+    protected abstract ValueNode genIntegerRem(Kind kind, ValueNode x, ValueNode y);
 
     private void genIntegerDivOp(Kind result, int opcode) {
-        T y = frameState.pop(result);
-        T x = frameState.pop(result);
-        T v;
+        ValueNode y = frameState.pop(result);
+        ValueNode x = frameState.pop(result);
+        ValueNode v;
         switch (opcode) {
             case IDIV:
             case LDIV:
@@ -384,22 +384,22 @@
         frameState.push(result, append(v));
     }
 
-    protected abstract T genNegateOp(T x);
+    protected abstract ValueNode genNegateOp(ValueNode x);
 
     private void genNegateOp(Kind kind) {
         frameState.push(kind, append(genNegateOp(frameState.pop(kind))));
     }
 
-    protected abstract T genLeftShift(Kind kind, T x, T y);
+    protected abstract ValueNode genLeftShift(Kind kind, ValueNode x, ValueNode y);
 
-    protected abstract T genRightShift(Kind kind, T x, T y);
+    protected abstract ValueNode genRightShift(Kind kind, ValueNode x, ValueNode y);
 
-    protected abstract T genUnsignedRightShift(Kind kind, T x, T y);
+    protected abstract ValueNode genUnsignedRightShift(Kind kind, ValueNode x, ValueNode y);
 
     private void genShiftOp(Kind kind, int opcode) {
-        T s = frameState.ipop();
-        T x = frameState.pop(kind);
-        T v;
+        ValueNode s = frameState.ipop();
+        ValueNode x = frameState.pop(kind);
+        ValueNode v;
         switch (opcode) {
             case ISHL:
             case LSHL:
@@ -419,16 +419,16 @@
         frameState.push(kind, append(v));
     }
 
-    protected abstract T genAnd(Kind kind, T x, T y);
+    protected abstract ValueNode genAnd(Kind kind, ValueNode x, ValueNode y);
 
-    protected abstract T genOr(Kind kind, T x, T y);
+    protected abstract ValueNode genOr(Kind kind, ValueNode x, ValueNode y);
 
-    protected abstract T genXor(Kind kind, T x, T y);
+    protected abstract ValueNode genXor(Kind kind, ValueNode x, ValueNode y);
 
     private void genLogicOp(Kind kind, int opcode) {
-        T y = frameState.pop(kind);
-        T x = frameState.pop(kind);
-        T v;
+        ValueNode y = frameState.pop(kind);
+        ValueNode x = frameState.pop(kind);
+        ValueNode v;
         switch (opcode) {
             case IAND:
             case LAND:
@@ -448,29 +448,29 @@
         frameState.push(kind, append(v));
     }
 
-    protected abstract T genNormalizeCompare(T x, T y, boolean isUnorderedLess);
+    protected abstract ValueNode genNormalizeCompare(ValueNode x, ValueNode y, boolean isUnorderedLess);
 
     private void genCompareOp(Kind kind, boolean isUnorderedLess) {
-        T y = frameState.pop(kind);
-        T x = frameState.pop(kind);
+        ValueNode y = frameState.pop(kind);
+        ValueNode x = frameState.pop(kind);
         frameState.ipush(append(genNormalizeCompare(x, y, isUnorderedLess)));
     }
 
-    protected abstract T genFloatConvert(FloatConvert op, T input);
+    protected abstract ValueNode genFloatConvert(FloatConvert op, ValueNode input);
 
     private void genFloatConvert(FloatConvert op, Kind from, Kind to) {
-        T input = frameState.pop(from.getStackKind());
+        ValueNode input = frameState.pop(from.getStackKind());
         frameState.push(to.getStackKind(), append(genFloatConvert(op, input)));
     }
 
-    protected abstract T genNarrow(T input, int bitCount);
+    protected abstract ValueNode genNarrow(ValueNode input, int bitCount);
 
-    protected abstract T genSignExtend(T input, int bitCount);
+    protected abstract ValueNode genSignExtend(ValueNode input, int bitCount);
 
-    protected abstract T genZeroExtend(T input, int bitCount);
+    protected abstract ValueNode genZeroExtend(ValueNode input, int bitCount);
 
     private void genSignExtend(Kind from, Kind to) {
-        T input = frameState.pop(from.getStackKind());
+        ValueNode input = frameState.pop(from.getStackKind());
         if (from != from.getStackKind()) {
             input = append(genNarrow(input, from.getBitCount()));
         }
@@ -478,7 +478,7 @@
     }
 
     private void genZeroExtend(Kind from, Kind to) {
-        T input = frameState.pop(from.getStackKind());
+        ValueNode input = frameState.pop(from.getStackKind());
         if (from != from.getStackKind()) {
             input = append(genNarrow(input, from.getBitCount()));
         }
@@ -486,45 +486,45 @@
     }
 
     private void genNarrow(Kind from, Kind to) {
-        T input = frameState.pop(from.getStackKind());
+        ValueNode input = frameState.pop(from.getStackKind());
         frameState.push(to.getStackKind(), append(genNarrow(input, to.getBitCount())));
     }
 
     private void genIncrement() {
         int index = getStream().readLocalIndex();
         int delta = getStream().readIncrement();
-        T x = frameState.loadLocal(index);
-        T y = appendConstant(JavaConstant.forInt(delta));
+        ValueNode x = frameState.loadLocal(index);
+        ValueNode y = appendConstant(JavaConstant.forInt(delta));
         frameState.storeLocal(index, append(genIntegerAdd(Kind.Int, x, y)));
     }
 
     protected abstract void genGoto();
 
-    protected abstract T genObjectEquals(T x, T y);
+    protected abstract ValueNode genObjectEquals(ValueNode x, ValueNode y);
 
-    protected abstract T genIntegerEquals(T x, T y);
+    protected abstract ValueNode genIntegerEquals(ValueNode x, ValueNode y);
 
-    protected abstract T genIntegerLessThan(T x, T y);
+    protected abstract ValueNode genIntegerLessThan(ValueNode x, ValueNode y);
 
-    protected abstract T genUnique(T x);
+    protected abstract ValueNode genUnique(ValueNode x);
 
-    protected abstract void genIf(T x, Condition cond, T y);
+    protected abstract void genIf(ValueNode x, Condition cond, ValueNode y);
 
     private void genIfZero(Condition cond) {
-        T y = appendConstant(JavaConstant.INT_0);
-        T x = frameState.ipop();
+        ValueNode y = appendConstant(JavaConstant.INT_0);
+        ValueNode x = frameState.ipop();
         genIf(x, cond, y);
     }
 
     private void genIfNull(Condition cond) {
-        T y = appendConstant(JavaConstant.NULL_POINTER);
-        T x = frameState.apop();
+        ValueNode y = appendConstant(JavaConstant.NULL_POINTER);
+        ValueNode x = frameState.apop();
         genIf(x, cond, y);
     }
 
     private void genIfSame(Kind kind, Condition cond) {
-        T y = frameState.pop(kind);
-        T x = frameState.pop(kind);
+        ValueNode y = frameState.pop(kind);
+        ValueNode x = frameState.pop(kind);
         // assert !x.isDeleted() && !y.isDeleted();
         genIf(x, cond, y);
     }
@@ -579,41 +579,40 @@
         }
     }
 
-    protected abstract T createCheckCast(ResolvedJavaType type, T object, JavaTypeProfile profileForTypeCheck, boolean forStoreCheck);
+    protected abstract ValueNode createCheckCast(ResolvedJavaType type, ValueNode object, JavaTypeProfile profileForTypeCheck, boolean forStoreCheck);
 
     private void genCheckCast() {
         int cpi = getStream().readCPI();
         JavaType type = lookupType(cpi, CHECKCAST);
-        T object = frameState.apop();
+        ValueNode object = frameState.apop();
         if (type instanceof ResolvedJavaType) {
             JavaTypeProfile profileForTypeCheck = getProfileForTypeCheck((ResolvedJavaType) type);
-            T checkCastNode = append(createCheckCast((ResolvedJavaType) type, object, profileForTypeCheck, false));
+            ValueNode checkCastNode = append(createCheckCast((ResolvedJavaType) type, object, profileForTypeCheck, false));
             frameState.apush(checkCastNode);
         } else {
             handleUnresolvedCheckCast(type, object);
         }
     }
 
-    protected abstract T createInstanceOf(ResolvedJavaType type, T object, JavaTypeProfile profileForTypeCheck);
+    protected abstract ValueNode createInstanceOf(ResolvedJavaType type, ValueNode object, JavaTypeProfile profileForTypeCheck);
 
-    protected abstract T genConditional(T x);
+    protected abstract ValueNode genConditional(ValueNode x);
 
     private void genInstanceOf() {
         int cpi = getStream().readCPI();
         JavaType type = lookupType(cpi, INSTANCEOF);
-        T object = frameState.apop();
+        ValueNode object = frameState.apop();
         if (type instanceof ResolvedJavaType) {
             ResolvedJavaType resolvedType = (ResolvedJavaType) type;
-            T instanceOfNode = createInstanceOf((ResolvedJavaType) type, object, getProfileForTypeCheck(resolvedType));
+            ValueNode instanceOfNode = createInstanceOf((ResolvedJavaType) type, object, getProfileForTypeCheck(resolvedType));
             frameState.ipush(append(genConditional(genUnique(instanceOfNode))));
         } else {
             handleUnresolvedInstanceOf(type, object);
         }
     }
 
-    protected abstract T createNewInstance(ResolvedJavaType type, boolean fillContents);
+    protected abstract ValueNode createNewInstance(ResolvedJavaType type, boolean fillContents);
 
-    @SuppressWarnings("unchecked")
     void genNewInstance(int cpi) {
         JavaType type = lookupType(cpi, NEW);
         if (type instanceof ResolvedJavaType && ((ResolvedJavaType) type).isInitialized()) {
@@ -621,7 +620,7 @@
             if (skippedExceptionTypes != null) {
                 for (ResolvedJavaType exceptionType : skippedExceptionTypes) {
                     if (exceptionType.isAssignableFrom((ResolvedJavaType) type)) {
-                        append((T) new DeoptimizeNode(DeoptimizationAction.None, TransferToInterpreter));
+                        append(new DeoptimizeNode(DeoptimizationAction.None, TransferToInterpreter));
                         return;
                     }
                 }
@@ -672,7 +671,7 @@
 
     private void genNewObjectArray(int cpi) {
         JavaType type = lookupType(cpi, ANEWARRAY);
-        T length = frameState.ipop();
+        ValueNode length = frameState.ipop();
         if (type instanceof ResolvedJavaType) {
             frameState.apush(append(createNewArray((ResolvedJavaType) type, length, true)));
         } else {
@@ -681,12 +680,12 @@
 
     }
 
-    protected abstract T createNewArray(ResolvedJavaType elementType, T length, boolean fillContents);
+    protected abstract ValueNode createNewArray(ResolvedJavaType elementType, ValueNode length, boolean fillContents);
 
     private void genNewMultiArray(int cpi) {
         JavaType type = lookupType(cpi, MULTIANEWARRAY);
         int rank = getStream().readUByte(bci() + 3);
-        List<T> dims = new ArrayList<>(Collections.nCopies(rank, null));
+        List<ValueNode> dims = new ArrayList<>(Collections.nCopies(rank, null));
         for (int i = rank - 1; i >= 0; i--) {
             dims.set(i, frameState.ipop());
         }
@@ -697,18 +696,18 @@
         }
     }
 
-    protected abstract T createNewMultiArray(ResolvedJavaType type, List<T> dims);
+    protected abstract ValueNode createNewMultiArray(ResolvedJavaType type, List<ValueNode> dims);
 
-    protected abstract T genLoadField(T receiver, ResolvedJavaField field);
+    protected abstract ValueNode genLoadField(ValueNode receiver, ResolvedJavaField field);
 
     private void genGetField(JavaField field) {
         emitExplicitExceptions(frameState.peek(0), null);
 
         Kind kind = field.getKind();
-        T receiver = frameState.apop();
+        ValueNode receiver = frameState.apop();
         if ((field instanceof ResolvedJavaField) && ((ResolvedJavaField) field).getDeclaringClass().isInitialized()) {
             LoadFieldPlugin loadFieldPlugin = this.graphBuilderConfig.getLoadFieldPlugin();
-            if (loadFieldPlugin == null || !loadFieldPlugin.apply((GraphBuilderContext) this, (ValueNode) receiver, (ResolvedJavaField) field)) {
+            if (loadFieldPlugin == null || !loadFieldPlugin.apply((GraphBuilderContext) this, receiver, (ResolvedJavaField) field)) {
                 appendOptimizedLoadField(kind, genLoadField(receiver, (ResolvedJavaField) field));
             }
         } else {
@@ -716,15 +715,15 @@
         }
     }
 
-    protected abstract void emitNullCheck(T receiver);
+    protected abstract void emitNullCheck(ValueNode receiver);
 
-    protected abstract void emitBoundsCheck(T index, T length);
+    protected abstract void emitBoundsCheck(ValueNode index, ValueNode length);
 
     private static final DebugMetric EXPLICIT_EXCEPTIONS = Debug.metric("ExplicitExceptions");
 
-    protected abstract T genArrayLength(T x);
+    protected abstract ValueNode genArrayLength(ValueNode x);
 
-    protected void emitExplicitExceptions(T receiver, T outOfBoundsIndex) {
+    protected void emitExplicitExceptions(ValueNode receiver, ValueNode outOfBoundsIndex) {
         assert receiver != null;
         if (graphBuilderConfig.omitAllExceptionEdges() || profilingInfo == null ||
                         (optimisticOpts.useExceptionProbabilityForOperations() && profilingInfo.getExceptionSeen(bci()) == TriState.FALSE && !GraalOptions.StressExplicitExceptionCode.getValue())) {
@@ -733,19 +732,19 @@
 
         emitNullCheck(receiver);
         if (outOfBoundsIndex != null) {
-            T length = append(genArrayLength(receiver));
+            ValueNode length = append(genArrayLength(receiver));
             emitBoundsCheck(outOfBoundsIndex, length);
         }
         EXPLICIT_EXCEPTIONS.increment();
     }
 
-    protected abstract T genStoreField(T receiver, ResolvedJavaField field, T value);
+    protected abstract ValueNode genStoreField(ValueNode receiver, ResolvedJavaField field, ValueNode value);
 
     private void genPutField(JavaField field) {
         emitExplicitExceptions(frameState.peek(1), null);
 
-        T value = frameState.pop(field.getKind().getStackKind());
-        T receiver = frameState.apop();
+        ValueNode value = frameState.pop(field.getKind().getStackKind());
+        ValueNode receiver = frameState.apop();
         if (field instanceof ResolvedJavaField && ((ResolvedJavaField) field).getDeclaringClass().isInitialized()) {
             appendOptimizedStoreField(genStoreField(receiver, (ResolvedJavaField) field, value));
         } else {
@@ -766,7 +765,7 @@
     }
 
     private void genPutStatic(JavaField field) {
-        T value = frameState.pop(field.getKind().getStackKind());
+        ValueNode value = frameState.pop(field.getKind().getStackKind());
         if (field instanceof ResolvedJavaField && ((ResolvedJavaType) field.getDeclaringClass()).isInitialized()) {
             appendOptimizedStoreField(genStoreField(null, (ResolvedJavaField) field, value));
         } else {
@@ -774,13 +773,13 @@
         }
     }
 
-    protected void appendOptimizedStoreField(T store) {
+    protected void appendOptimizedStoreField(ValueNode store) {
         append(store);
     }
 
-    protected void appendOptimizedLoadField(Kind kind, T load) {
+    protected void appendOptimizedLoadField(Kind kind, ValueNode load) {
         // append the load to the instruction
-        T optimized = append(load);
+        ValueNode optimized = append(load);
         frameState.push(kind.getStackKind(), optimized);
     }
 
@@ -794,11 +793,11 @@
 
     protected abstract void genInvokeSpecial(JavaMethod target);
 
-    protected abstract void genReturn(T x);
+    protected abstract void genReturn(ValueNode x);
 
-    protected abstract T genMonitorEnter(T x);
+    protected abstract ValueNode genMonitorEnter(ValueNode x);
 
-    protected abstract T genMonitorExit(T x, T returnValue);
+    protected abstract ValueNode genMonitorExit(ValueNode x, ValueNode returnValue);
 
     protected abstract void genJsr(int dest);
 
@@ -843,7 +842,7 @@
 
     private void genSwitch(BytecodeSwitch bs) {
         int bci = bci();
-        T value = frameState.ipop();
+        ValueNode value = frameState.ipop();
 
         int nofCases = bs.numberOfCases();
         double[] keyProbabilities = switchProbability(nofCases + 1, bci);
@@ -861,7 +860,7 @@
         int[] keySuccessors = new int[nofCases + 1];
         int deoptSuccessorIndex = -1;
         int nextSuccessorIndex = 0;
-        boolean constantValue = ((ValueNode) value).isConstant();
+        boolean constantValue = value.isConstant();
         for (int i = 0; i < nofCases + 1; i++) {
             if (i < nofCases) {
                 keys[i] = bs.keyAt(i);
@@ -888,7 +887,7 @@
 
     }
 
-    protected abstract void genIntegerSwitch(T value, ArrayList<BciBlock> actualSuccessors, int[] keys, double[] keyProbabilities, int[] keySuccessors);
+    protected abstract void genIntegerSwitch(ValueNode value, ArrayList<BciBlock> actualSuccessors, int[] keys, double[] keyProbabilities, int[] keySuccessors);
 
     private static class SuccessorInfo {
 
@@ -901,9 +900,9 @@
         }
     }
 
-    protected abstract T appendConstant(JavaConstant constant);
+    protected abstract ValueNode appendConstant(JavaConstant constant);
 
-    protected abstract T append(T v);
+    protected abstract ValueNode append(ValueNode v);
 
     protected boolean isNeverExecutedCode(double probability) {
         return probability == 0 && optimisticOpts.removeNeverExecutedCode();
@@ -1182,7 +1181,7 @@
         return method;
     }
 
-    public F getFrameState() {
+    public HIRFrameStateBuilder getFrameState() {
         return frameState;
     }
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Sun Feb 22 14:41:35 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Sun Feb 22 15:19:54 2015 +0100
@@ -172,7 +172,7 @@
             private int peelIteration;
         }
 
-        public class BytecodeParser extends AbstractBytecodeParser<ValueNode, HIRFrameStateBuilder> implements GraphBuilderContext {
+        public class BytecodeParser extends AbstractBytecodeParser implements GraphBuilderContext {
 
             private BciBlockMapping blockMap;
             private LocalLiveness liveness;
@@ -1228,7 +1228,7 @@
                             }
                             lastLoopExit = loopExit;
                             Debug.log("Target %s Exits %s, scanning framestates...", targetBlock, loop);
-                            newState.insertLoopProxies(loopExit, (HIRFrameStateBuilder) getEntryState(loop, this.getCurrentDimension()));
+                            newState.insertLoopProxies(loopExit, getEntryState(loop, this.getCurrentDimension()));
                             loopExit.setStateAfter(newState.create(bci));
                         }
 
@@ -1239,7 +1239,7 @@
                 return new Target(target, state);
             }
 
-            private AbstractFrameStateBuilder<?, ?> getEntryState(BciBlock block, int dimension) {
+            private HIRFrameStateBuilder getEntryState(BciBlock block, int dimension) {
                 int id = block.id;
                 if (dimension == 0) {
                     return entryStateArray[id];
@@ -1248,9 +1248,9 @@
                 }
             }
 
-            private AbstractFrameStateBuilder<?, ?> getEntryStateMultiDimension(int dimension, int id) {
+            private HIRFrameStateBuilder getEntryStateMultiDimension(int dimension, int id) {
                 if (entryStateMatrix != null && dimension - 1 < entryStateMatrix.length) {
-                    AbstractFrameStateBuilder<?, ?>[] entryStateArrayEntry = entryStateMatrix[dimension - 1];
+                    HIRFrameStateBuilder[] entryStateArrayEntry = entryStateMatrix[dimension - 1];
                     if (entryStateArrayEntry == null) {
                         return null;
                     }
@@ -1376,7 +1376,7 @@
                 }
 
                 // We already saw this block before, so we have to merge states.
-                if (!((HIRFrameStateBuilder) getEntryState(block, operatingDimension)).isCompatibleWith(state)) {
+                if (!getEntryState(block, operatingDimension).isCompatibleWith(state)) {
                     throw bailout("stacks do not match; bytecodes would not verify");
                 }
 
@@ -1389,7 +1389,7 @@
                     LoopBeginNode loopBegin = (LoopBeginNode) getFirstInstruction(block, operatingDimension);
                     Target target = checkLoopExit(currentGraph.add(new LoopEndNode(loopBegin)), block, state);
                     FixedNode result = target.fixed;
-                    ((HIRFrameStateBuilder) getEntryState(block, operatingDimension)).merge(loopBegin, target.state);
+                    getEntryState(block, operatingDimension).merge(loopBegin, target.state);
 
                     Debug.log("createTarget %s: merging backward branch to loop header %s, result: %s", block, loopBegin, result);
                     return result;
@@ -1430,7 +1430,7 @@
                 EndNode newEnd = currentGraph.add(new EndNode());
                 Target target = checkLoopExit(newEnd, block, state);
                 FixedNode result = target.fixed;
-                ((HIRFrameStateBuilder) getEntryState(block, operatingDimension)).merge(mergeNode, target.state);
+                getEntryState(block, operatingDimension).merge(mergeNode, target.state);
                 mergeNode.addForwardEnd(newEnd);
 
                 Debug.log("createTarget %s: merging state, result: %s", block, result);
@@ -1508,7 +1508,7 @@
                 try (Indent indent = Debug.logAndIndent("Parsing block %s  firstInstruction: %s  loopHeader: %b", block, getFirstInstruction(block, this.getCurrentDimension()), block.isLoopHeader)) {
 
                     lastInstr = getFirstInstruction(block, this.getCurrentDimension());
-                    frameState = (HIRFrameStateBuilder) getEntryState(block, this.getCurrentDimension());
+                    frameState = getEntryState(block, this.getCurrentDimension());
                     parser.setCurrentFrameState(frameState);
                     currentBlock = block;
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java	Sun Feb 22 14:41:35 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java	Sun Feb 22 15:19:54 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.java.BciBlockMapping.*;
 import com.oracle.graal.java.GraphBuilderPlugin.ParameterPlugin;
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
@@ -38,11 +39,27 @@
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.util.*;
 
-public class HIRFrameStateBuilder extends AbstractFrameStateBuilder<ValueNode, HIRFrameStateBuilder> {
+public final class HIRFrameStateBuilder {
 
     private static final ValueNode[] EMPTY_ARRAY = new ValueNode[0];
     private static final MonitorIdNode[] EMPTY_MONITOR_ARRAY = new MonitorIdNode[0];
 
+    protected final ResolvedJavaMethod method;
+    protected int stackSize;
+    protected final ValueNode[] locals;
+    protected final ValueNode[] stack;
+    protected ValueNode[] lockedObjects;
+
+    /**
+     * Specifies if asserting type checks are enabled.
+     */
+    protected final boolean checkTypes;
+
+    /**
+     * @see BytecodeFrame#rethrowException
+     */
+    protected boolean rethrowException;
+
     private MonitorIdNode[] monitorIds;
     private final StructuredGraph graph;
     private final Supplier<FrameState> outerFrameStateSupplier;
@@ -54,7 +71,11 @@
      * @param graph the target graph of Graal nodes created by the builder
      */
     public HIRFrameStateBuilder(ResolvedJavaMethod method, StructuredGraph graph, boolean checkTypes, Supplier<FrameState> outerFrameStateSupplier) {
-        super(method, checkTypes);
+        this.method = method;
+        this.locals = allocateArray(method.getMaxLocals());
+        this.stack = allocateArray(Math.max(1, method.getMaxStackSize()));
+        this.lockedObjects = allocateArray(0);
+        this.checkTypes = checkTypes;
 
         assert graph != null;
 
@@ -63,7 +84,7 @@
         this.outerFrameStateSupplier = outerFrameStateSupplier;
     }
 
-    public final void initializeFromArgumentsArray(ValueNode[] arguments) {
+    public void initializeFromArgumentsArray(ValueNode[] arguments) {
 
         int javaIndex = 0;
         int index = 0;
@@ -82,7 +103,7 @@
         }
     }
 
-    public final void initializeForMethodStart(boolean eagerResolve, ParameterPlugin parameterPlugin) {
+    public void initializeForMethodStart(boolean eagerResolve, ParameterPlugin parameterPlugin) {
 
         int javaIndex = 0;
         int index = 0;
@@ -128,7 +149,17 @@
     }
 
     private HIRFrameStateBuilder(HIRFrameStateBuilder other) {
-        super(other);
+        this.method = other.method;
+        this.stackSize = other.stackSize;
+        this.locals = other.locals.clone();
+        this.stack = other.stack.clone();
+        this.lockedObjects = other.lockedObjects.length == 0 ? other.lockedObjects : other.lockedObjects.clone();
+        this.rethrowException = other.rethrowException;
+        this.checkTypes = other.checkTypes;
+
+        assert locals.length == method.getMaxLocals();
+        assert stack.length == Math.max(1, method.getMaxStackSize());
+
         assert other.graph != null;
         graph = other.graph;
         monitorIds = other.monitorIds.length == 0 ? other.monitorIds : other.monitorIds.clone();
@@ -139,8 +170,7 @@
         assert lockedObjects.length == monitorIds.length;
     }
 
-    @Override
-    protected ValueNode[] allocateArray(int length) {
+    private static ValueNode[] allocateArray(int length) {
         return length == 0 ? EMPTY_ARRAY : new ValueNode[length];
     }
 
@@ -175,12 +205,10 @@
         return graph.add(new FrameState(outerFrameState, method, bci, locals, stack, stackSize, lockedObjects, Arrays.asList(monitorIds), rethrowException, false));
     }
 
-    @Override
     public HIRFrameStateBuilder copy() {
         return new HIRFrameStateBuilder(this);
     }
 
-    @Override
     public boolean isCompatibleWith(HIRFrameStateBuilder other) {
         assert method.equals(other.method) && graph == other.graph && localsSize() == other.localsSize() : "Can only compare frame states of the same method";
         assert lockedObjects.length == monitorIds.length && other.lockedObjects.length == other.monitorIds.length : "mismatch between lockedObjects and monitorIds";
@@ -380,7 +408,6 @@
     /**
      * @return the current lock depth
      */
-    @Override
     public int lockDepth() {
         assert lockedObjects.length == monitorIds.length;
         return lockedObjects.length;
@@ -405,4 +432,433 @@
         }
         return false;
     }
+
+    public void clearNonLiveLocals(BciBlock block, LocalLiveness liveness, boolean liveIn) {
+        /*
+         * (lstadler) if somebody is tempted to remove/disable this clearing code: it's possible to
+         * remove it for normal compilations, but not for OSR compilations - otherwise dead object
+         * slots at the OSR entry aren't cleared. it is also not enough to rely on PiNodes with
+         * Kind.Illegal, because the conflicting branch might not have been parsed.
+         */
+        if (liveness == null) {
+            return;
+        }
+        if (liveIn) {
+            for (int i = 0; i < locals.length; i++) {
+                if (!liveness.localIsLiveIn(block, i)) {
+                    locals[i] = null;
+                }
+            }
+        } else {
+            for (int i = 0; i < locals.length; i++) {
+                if (!liveness.localIsLiveOut(block, i)) {
+                    locals[i] = null;
+                }
+            }
+        }
+    }
+
+    /**
+     * @see BytecodeFrame#rethrowException
+     */
+    public boolean rethrowException() {
+        return rethrowException;
+    }
+
+    /**
+     * @see BytecodeFrame#rethrowException
+     */
+    public void setRethrowException(boolean b) {
+        rethrowException = b;
+    }
+
+    /**
+     * Returns the size of the local variables.
+     *
+     * @return the size of the local variables
+     */
+    public int localsSize() {
+        return locals.length;
+    }
+
+    /**
+     * Gets the current size (height) of the stack.
+     */
+    public int stackSize() {
+        return stackSize;
+    }
+
+    /**
+     * Gets the value in the local variables at the specified index, without any sanity checking.
+     *
+     * @param i the index into the locals
+     * @return the instruction that produced the value for the specified local
+     */
+    public ValueNode localAt(int i) {
+        return locals[i];
+    }
+
+    /**
+     * Get the value on the stack at the specified stack index.
+     *
+     * @param i the index into the stack, with {@code 0} being the bottom of the stack
+     * @return the instruction at the specified position in the stack
+     */
+    public ValueNode stackAt(int i) {
+        return stack[i];
+    }
+
+    /**
+     * Gets the value in the lock at the specified index, without any sanity checking.
+     *
+     * @param i the index into the lock
+     * @return the instruction that produced the value for the specified lock
+     */
+    public ValueNode lockAt(int i) {
+        return lockedObjects[i];
+    }
+
+    public void storeLock(int i, ValueNode lock) {
+        lockedObjects[i] = lock;
+    }
+
+    /**
+     * Loads the local variable at the specified index, checking that the returned value is non-null
+     * and that two-stack values are properly handled.
+     *
+     * @param i the index of the local variable to load
+     * @return the instruction that produced the specified local
+     */
+    public ValueNode loadLocal(int i) {
+        ValueNode x = locals[i];
+        assert assertLoadLocal(i, x);
+        return x;
+    }
+
+    private boolean assertLoadLocal(int i, ValueNode x) {
+        assert x != null : i;
+        assert !checkTypes || (x.getKind().getSlotCount() == 1 || locals[i + 1] == null);
+        assert !checkTypes || (i == 0 || locals[i - 1] == null || locals[i - 1].getKind().getSlotCount() == 1);
+        return true;
+    }
+
+    /**
+     * Stores a given local variable at the specified index. If the value occupies two slots, then
+     * the next local variable index is also overwritten.
+     *
+     * @param i the index at which to store
+     * @param x the instruction which produces the value for the local
+     */
+    public void storeLocal(int i, ValueNode x) {
+        assert assertStoreLocal(x);
+        locals[i] = x;
+        if (x != null && x.getKind().needsTwoSlots()) {
+            // if this is a double word, then kill i+1
+            locals[i + 1] = null;
+        }
+        if (x != null && i > 0) {
+            ValueNode p = locals[i - 1];
+            if (p != null && p.getKind().needsTwoSlots()) {
+                // if there was a double word at i - 1, then kill it
+                locals[i - 1] = null;
+            }
+        }
+    }
+
+    private boolean assertStoreLocal(ValueNode x) {
+        assert x == null || !checkTypes || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal) : "unexpected value: " + x;
+        return true;
+    }
+
+    public void storeStack(int i, ValueNode x) {
+        assert assertStoreStack(i, x);
+        stack[i] = x;
+    }
+
+    private boolean assertStoreStack(int i, ValueNode x) {
+        assert x == null || (stack[i] == null || x.getKind() == stack[i].getKind()) : "Method does not handle changes from one-slot to two-slot values or non-alive values";
+        return true;
+    }
+
+    /**
+     * Pushes an instruction onto the stack with the expected type.
+     *
+     * @param kind the type expected for this instruction
+     * @param x the instruction to push onto the stack
+     */
+    public void push(Kind kind, ValueNode x) {
+        assert assertPush(kind, x);
+        xpush(x);
+        if (kind.needsTwoSlots()) {
+            xpush(null);
+        }
+    }
+
+    private boolean assertPush(Kind kind, ValueNode x) {
+        assert !checkTypes || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal);
+        assert x != null && (!checkTypes || x.getKind() == kind);
+        return true;
+    }
+
+    /**
+     * Pushes a value onto the stack without checking the type.
+     *
+     * @param x the instruction to push onto the stack
+     */
+    public void xpush(ValueNode x) {
+        assert assertXpush(x);
+        stack[stackSize++] = x;
+    }
+
+    private boolean assertXpush(ValueNode x) {
+        assert !checkTypes || (x == null || (x.getKind() != Kind.Void && x.getKind() != Kind.Illegal));
+        return true;
+    }
+
+    /**
+     * Pushes a value onto the stack and checks that it is an int.
+     *
+     * @param x the instruction to push onto the stack
+     */
+    public void ipush(ValueNode x) {
+        assert assertInt(x);
+        xpush(x);
+    }
+
+    /**
+     * Pushes a value onto the stack and checks that it is a float.
+     *
+     * @param x the instruction to push onto the stack
+     */
+    public void fpush(ValueNode x) {
+        assert assertFloat(x);
+        xpush(x);
+    }
+
+    /**
+     * Pushes a value onto the stack and checks that it is an object.
+     *
+     * @param x the instruction to push onto the stack
+     */
+    public void apush(ValueNode x) {
+        assert assertObject(x);
+        xpush(x);
+    }
+
+    /**
+     * Pushes a value onto the stack and checks that it is a long.
+     *
+     * @param x the instruction to push onto the stack
+     */
+    public void lpush(ValueNode x) {
+        assert assertLong(x);
+        xpush(x);
+        xpush(null);
+    }
+
+    /**
+     * Pushes a value onto the stack and checks that it is a double.
+     *
+     * @param x the instruction to push onto the stack
+     */
+    public void dpush(ValueNode x) {
+        assert assertDouble(x);
+        xpush(x);
+        xpush(null);
+    }
+
+    public void pushReturn(Kind kind, ValueNode x) {
+        if (kind != Kind.Void) {
+            push(kind.getStackKind(), x);
+        }
+    }
+
+    /**
+     * Pops an instruction off the stack with the expected type.
+     *
+     * @param kind the expected type
+     * @return the instruction on the top of the stack
+     */
+    public ValueNode pop(Kind kind) {
+        if (kind.needsTwoSlots()) {
+            xpop();
+        }
+        assert assertPop(kind);
+        return xpop();
+    }
+
+    private boolean assertPop(Kind kind) {
+        assert kind != Kind.Void;
+        ValueNode x = xpeek();
+        assert x != null && (!checkTypes || x.getKind() == kind);
+        return true;
+    }
+
+    /**
+     * Pops a value off of the stack without checking the type.
+     *
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode xpop() {
+        return stack[--stackSize];
+    }
+
+    private ValueNode xpeek() {
+        return stack[stackSize - 1];
+    }
+
+    /**
+     * Pops a value off of the stack and checks that it is an int.
+     *
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode ipop() {
+        assert assertIntPeek();
+        return xpop();
+    }
+
+    /**
+     * Pops a value off of the stack and checks that it is a float.
+     *
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode fpop() {
+        assert assertFloatPeek();
+        return xpop();
+    }
+
+    /**
+     * Pops a value off of the stack and checks that it is an object.
+     *
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode apop() {
+        assert assertObjectPeek();
+        return xpop();
+    }
+
+    /**
+     * Pops a value off of the stack and checks that it is a long.
+     *
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode lpop() {
+        assert assertHighPeek();
+        xpop();
+        assert assertLongPeek();
+        return xpop();
+    }
+
+    /**
+     * Pops a value off of the stack and checks that it is a double.
+     *
+     * @return x the instruction popped off the stack
+     */
+    public ValueNode dpop() {
+        assert assertHighPeek();
+        xpop();
+        assert assertDoublePeek();
+        return xpop();
+    }
+
+    /**
+     * Pop the specified number of slots off of this stack and return them as an array of
+     * instructions.
+     *
+     * @return an array containing the arguments off of the stack
+     */
+    public ValueNode[] popArguments(int argSize) {
+        ValueNode[] result = allocateArray(argSize);
+        int newStackSize = stackSize;
+        for (int i = argSize - 1; i >= 0; i--) {
+            newStackSize--;
+            if (stack[newStackSize] == null) {
+                /* Two-slot value. */
+                newStackSize--;
+                assert stack[newStackSize].getKind().needsTwoSlots();
+            } else {
+                assert !checkTypes || (stack[newStackSize].getKind().getSlotCount() == 1);
+            }
+            result[i] = stack[newStackSize];
+        }
+        stackSize = newStackSize;
+        return result;
+    }
+
+    /**
+     * Peeks an element from the operand stack.
+     *
+     * @param argumentNumber The number of the argument, relative from the top of the stack (0 =
+     *            top). Long and double arguments only count as one argument, i.e., null-slots are
+     *            ignored.
+     * @return The peeked argument.
+     */
+    public ValueNode peek(int argumentNumber) {
+        int idx = stackSize() - 1;
+        for (int i = 0; i < argumentNumber; i++) {
+            if (stackAt(idx) == null) {
+                idx--;
+                assert stackAt(idx).getKind().needsTwoSlots();
+            }
+            idx--;
+        }
+        return stackAt(idx);
+    }
+
+    /**
+     * Clears all values on this stack.
+     */
+    public void clearStack() {
+        stackSize = 0;
+    }
+
+    private boolean assertLongPeek() {
+        return assertLong(xpeek());
+    }
+
+    private static boolean assertLong(ValueNode x) {
+        assert x != null && (x.getKind() == Kind.Long);
+        return true;
+    }
+
+    private boolean assertIntPeek() {
+        return assertInt(xpeek());
+    }
+
+    private static boolean assertInt(ValueNode x) {
+        assert x != null && (x.getKind() == Kind.Int);
+        return true;
+    }
+
+    private boolean assertFloatPeek() {
+        return assertFloat(xpeek());
+    }
+
+    private static boolean assertFloat(ValueNode x) {
+        assert x != null && (x.getKind() == Kind.Float);
+        return true;
+    }
+
+    private boolean assertObjectPeek() {
+        return assertObject(xpeek());
+    }
+
+    private boolean assertObject(ValueNode x) {
+        assert x != null && (!checkTypes || (x.getKind() == Kind.Object));
+        return true;
+    }
+
+    private boolean assertDoublePeek() {
+        return assertDouble(xpeek());
+    }
+
+    private static boolean assertDouble(ValueNode x) {
+        assert x != null && (x.getKind() == Kind.Double);
+        return true;
+    }
+
+    private boolean assertHighPeek() {
+        assert xpeek() == null;
+        return true;
+    }
 }