changeset 7111:e0fcf7802786

Merge.
author Christian Haeubl <haeubl@ssw.jku.at>
date Fri, 30 Nov 2012 08:30:22 +0100
parents 9bd688f91d3f (current diff) 4983da9d3fc7 (diff)
children 60bef2672469 38076efb9062
files
diffstat 80 files changed, 805 insertions(+), 847 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java	Fri Nov 30 08:30:22 2012 +0100
@@ -86,7 +86,7 @@
                         double totalHintProbability = 0.0d;
                         for (ProfiledType ptype : ptypes) {
                             ResolvedJavaType hint = ptype.getType();
-                            if (type != null && hint.isAssignableTo(type)) {
+                            if (type != null && type.isAssignableFrom(hint)) {
                                 hintTypes[hintCount++] = hint;
                                 totalHintProbability += ptype.getProbability();
                             }
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/NameAndSignature.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/NameAndSignature.java	Fri Nov 30 08:30:22 2012 +0100
@@ -26,8 +26,12 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
 
 class NameAndSignature {
+
+    public static final MetaAccessProvider runtime = Graal.getRequiredCapability(MetaAccessProvider.class);
+
     final String name;
     final Class returnType;
     final Class[] parameterTypes;
@@ -67,14 +71,14 @@
     public boolean signatureEquals(ResolvedJavaMethod m) {
         Signature s = m.getSignature();
         ResolvedJavaType declaringClass = m.getDeclaringClass();
-        if (!s.getReturnType(declaringClass).resolve(declaringClass).isClass(returnType)) {
+        if (!s.getReturnType(declaringClass).resolve(declaringClass).equals(runtime.lookupJavaType(returnType))) {
             return false;
         }
         if (s.getParameterCount(false) != parameterTypes.length) {
             return false;
         }
         for (int i = 0; i < parameterTypes.length; i++) {
-            if (!s.getParameterType(i, declaringClass).resolve(declaringClass).isClass(parameterTypes[i])) {
+            if (!s.getParameterType(i, declaringClass).resolve(declaringClass).equals(runtime.lookupJavaType(parameterTypes[i]))) {
                 return false;
             }
         }
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java	Fri Nov 30 08:30:22 2012 +0100
@@ -68,7 +68,7 @@
         for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
             Class expected = e.getKey().getDeclaringClass();
             ResolvedJavaType actual = e.getValue().getDeclaringClass();
-            assertTrue(actual.isClass(expected));
+            assertTrue(actual.equals(runtime.lookupJavaType(expected)));
         }
     }
 
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java	Fri Nov 30 08:30:22 2012 +0100
@@ -184,7 +184,6 @@
         for (Class c : classes) {
             ResolvedJavaType type = runtime.lookupJavaType(c);
             assertNotNull(type);
-            assertTrue(type.isClass(c));
             assertEquals(c.getModifiers(), type.getModifiers());
             if (!type.isArray()) {
                 assertEquals(type.getName(), toInternalName(c.getName()));
@@ -202,7 +201,7 @@
                 int expected = reflect.getModifiers() & Modifier.methodModifiers();
                 int actual = method.getModifiers();
                 assertEquals(String.format("%s: 0x%x != 0x%x", reflect, expected, actual), expected, actual);
-                assertTrue(method.getDeclaringClass().isClass(reflect.getDeclaringClass()));
+                assertTrue(method.getDeclaringClass().equals(runtime.lookupJavaType(reflect.getDeclaringClass())));
             }
         }
     }
@@ -216,7 +215,7 @@
                 int expected = reflect.getModifiers() & Modifier.fieldModifiers();
                 int actual = field.getModifiers();
                 assertEquals(String.format("%s: 0x%x != 0x%x", reflect, expected, actual), expected, actual);
-                assertTrue(field.getDeclaringClass().isClass(reflect.getDeclaringClass()));
+                assertTrue(field.getDeclaringClass().equals(runtime.lookupJavaType(reflect.getDeclaringClass())));
             }
         }
     }
@@ -224,11 +223,11 @@
     @Test
     public void lookupJavaTypeConstantTest() {
         for (Constant c : constants) {
-            if (c.getKind().isObject() && !c.isNull()) {
+            if (c.getKind() == Kind.Object && !c.isNull()) {
                 Object o = c.asObject();
                 ResolvedJavaType type = runtime.lookupJavaType(c);
                 assertNotNull(type);
-                assertTrue(type.isClass(o.getClass()));
+                assertTrue(type.equals(runtime.lookupJavaType(o.getClass())));
             } else {
                 assertEquals(runtime.lookupJavaType(c), null);
             }
@@ -241,7 +240,7 @@
             for (Constant c2 : constants) {
                 // test symmetry
                 assertEquals(runtime.constantEquals(c1, c2), runtime.constantEquals(c2, c1));
-                if (!c1.getKind().isObject() && !c2.getKind().isObject()) {
+                if (c1.getKind() != Kind.Object && c2.getKind() != Kind.Object) {
                     assertEquals(c1.equals(c2), runtime.constantEquals(c2, c1));
                 }
             }
@@ -251,7 +250,7 @@
     @Test
     public void lookupArrayLengthTest() {
         for (Constant c : constants) {
-            if (!c.getKind().isObject() || c.isNull() || !c.asObject().getClass().isArray()) {
+            if (c.getKind() != Kind.Object || c.isNull() || !c.asObject().getClass().isArray()) {
                 try {
                     int length = runtime.lookupArrayLength(c);
                     fail("Expected " + IllegalArgumentException.class.getName() + " for " + c + ", not " + length);
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java	Fri Nov 30 08:30:22 2012 +0100
@@ -111,10 +111,10 @@
                 ResolvedJavaType t1 = runtime.lookupJavaType(c1);
                 ResolvedJavaType t2 = runtime.lookupJavaType(c2);
                 boolean expected = c1.isAssignableFrom(c2);
-                boolean actual = t2.isAssignableTo(t1);
+                boolean actual = t1.isAssignableFrom(t2);
                 assertEquals(expected, actual);
                 if (expected && t1 != t2) {
-                    assertFalse(t1.isAssignableTo(t2));
+                    assertFalse(t2.isAssignableFrom(t1));
                 }
             }
         }
@@ -123,7 +123,7 @@
     @Test
     public void isInstanceTest() {
         for (Constant c : constants) {
-            if (c.getKind().isObject() && !c.isNull()) {
+            if (c.getKind() == Kind.Object && !c.isNull()) {
                 Object o = c.asObject();
                 Class< ? extends Object> cls = o.getClass();
                 while (cls != null) {
@@ -160,7 +160,7 @@
                 assertTrue("exact(" + c.getName() + ") != null", exactType == null);
             } else {
                 assertNotNull(exactType);
-                assertTrue(exactType.isClass(expected));
+                assertTrue(exactType.equals(runtime.lookupJavaType(expected)));
             }
         }
     }
@@ -175,7 +175,7 @@
                 assertTrue(actual == null);
             } else {
                 assertNotNull(actual);
-                assertTrue(actual.isClass(expected));
+                assertTrue(actual.equals(runtime.lookupJavaType(expected)));
             }
         }
     }
@@ -188,7 +188,7 @@
             ResolvedJavaType[] actual = type.getInterfaces();
             assertEquals(expected.length, actual.length);
             for (int i = 0; i < expected.length; i++) {
-                assertTrue(actual[i].isClass(expected[i]));
+                assertTrue(actual[i].equals(runtime.lookupJavaType(expected[i])));
             }
         }
     }
@@ -242,7 +242,7 @@
                     assertTrue(actual == null);
                 } else {
                     assertNotNull(actual);
-                    assertTrue(actual.isClass(expected));
+                    assertTrue(actual.equals(runtime.lookupJavaType(expected)));
                 }
             }
         }
@@ -264,7 +264,7 @@
             if (expected == null) {
                 assertNull(subtype);
             } else {
-                assertTrue(subtype.isClass(expected));
+                assertTrue(subtype.equals(runtime.lookupJavaType(expected)));
             }
         }
 
@@ -318,7 +318,7 @@
             if (expected == null) {
                 assertNull(actual);
             } else {
-                assertTrue(actual.isClass(expected));
+                assertTrue(actual.equals(runtime.lookupJavaType(expected)));
             }
         }
     }
@@ -330,7 +330,7 @@
                 ResolvedJavaType type = runtime.lookupJavaType(c);
                 Class expected = getArrayClass(c);
                 ResolvedJavaType actual = type.getArrayClass();
-                assertTrue(actual.isClass(expected));
+                assertTrue(actual.equals(runtime.lookupJavaType(expected)));
             }
         }
     }
@@ -459,9 +459,9 @@
     }
 
     public static boolean fieldsEqual(Field f, ResolvedJavaField rjf) {
-        return rjf.getDeclaringClass().isClass(f.getDeclaringClass()) &&
+        return rjf.getDeclaringClass().equals(runtime.lookupJavaType(f.getDeclaringClass())) &&
                rjf.getName().equals(f.getName()) &&
-               rjf.getType().resolve(rjf.getDeclaringClass()).isClass(f.getType());
+               rjf.getType().resolve(rjf.getDeclaringClass()).equals(runtime.lookupJavaType(f.getType()));
     }
 
     public static ResolvedJavaField lookupField(ResolvedJavaField[] fields, Field key) {
@@ -485,10 +485,10 @@
     }
 
     private static boolean isHiddenFromReflection(ResolvedJavaField f) {
-        if (f.getDeclaringClass().isClass(Throwable.class) && f.getName().equals("backtrace")) {
+        if (f.getDeclaringClass().equals(runtime.lookupJavaType(Throwable.class)) && f.getName().equals("backtrace")) {
             return true;
         }
-        if (f.getDeclaringClass().isClass(ConstantPool.class) && f.getName().equals("constantPoolOop")) {
+        if (f.getDeclaringClass().equals(runtime.lookupJavaType(ConstantPool.class)) && f.getName().equals("constantPoolOop")) {
             return true;
         }
         return false;
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Fri Nov 30 08:30:22 2012 +0100
@@ -34,27 +34,27 @@
     private static final Constant[] INT_CONSTANT_CACHE = new Constant[100];
     static {
         for (int i = 0; i < INT_CONSTANT_CACHE.length; ++i) {
-            INT_CONSTANT_CACHE[i] = new Constant(Kind.Int, i);
+            INT_CONSTANT_CACHE[i] = new Constant(Kind.Int, null, i);
         }
     }
 
-    public static final Constant NULL_OBJECT = new Constant(null);
-    public static final Constant INT_MINUS_1 = new Constant(Kind.Int, -1);
+    public static final Constant NULL_OBJECT = new Constant(Kind.Object, null, 0);
+    public static final Constant INT_MINUS_1 = new Constant(Kind.Int, null, -1);
     public static final Constant INT_0 = forInt(0);
     public static final Constant INT_1 = forInt(1);
     public static final Constant INT_2 = forInt(2);
     public static final Constant INT_3 = forInt(3);
     public static final Constant INT_4 = forInt(4);
     public static final Constant INT_5 = forInt(5);
-    public static final Constant LONG_0 = new Constant(Kind.Long, 0L);
-    public static final Constant LONG_1 = new Constant(Kind.Long, 1L);
-    public static final Constant FLOAT_0 = new Constant(Kind.Float, Float.floatToRawIntBits(0.0F));
-    public static final Constant FLOAT_1 = new Constant(Kind.Float, Float.floatToRawIntBits(1.0F));
-    public static final Constant FLOAT_2 = new Constant(Kind.Float, Float.floatToRawIntBits(2.0F));
-    public static final Constant DOUBLE_0 = new Constant(Kind.Double, Double.doubleToRawLongBits(0.0D));
-    public static final Constant DOUBLE_1 = new Constant(Kind.Double, Double.doubleToRawLongBits(1.0D));
-    public static final Constant TRUE = new Constant(Kind.Boolean, 1L);
-    public static final Constant FALSE = new Constant(Kind.Boolean, 0L);
+    public static final Constant LONG_0 = new Constant(Kind.Long, null, 0L);
+    public static final Constant LONG_1 = new Constant(Kind.Long, null, 1L);
+    public static final Constant FLOAT_0 = new Constant(Kind.Float, null, Float.floatToRawIntBits(0.0F));
+    public static final Constant FLOAT_1 = new Constant(Kind.Float, null, Float.floatToRawIntBits(1.0F));
+    public static final Constant FLOAT_2 = new Constant(Kind.Float, null, Float.floatToRawIntBits(2.0F));
+    public static final Constant DOUBLE_0 = new Constant(Kind.Double, null, Double.doubleToRawLongBits(0.0D));
+    public static final Constant DOUBLE_1 = new Constant(Kind.Double, null, Double.doubleToRawLongBits(1.0D));
+    public static final Constant TRUE = new Constant(Kind.Boolean, null, 1L);
+    public static final Constant FALSE = new Constant(Kind.Boolean, null, 0L);
 
     static {
         assert FLOAT_0 != forFloat(-0.0F) : "Constant for 0.0f must be different from -0.0f";
@@ -75,43 +75,9 @@
      */
     private final long primitive;
 
-    /**
-     * Creates a constant represented by the specified object reference.
-     * @param object the value of this constant
-     */
-    private Constant(Object object) {
-        super(Kind.Object);
-        this.object = object;
-        this.primitive = 0L;
-    }
-
-    /**
-     * Creates a constant represented by the specified primitive.
-     *
-     * @param kind the type of this constant
-     * @param primitive the value of this constant
-     */
-    public Constant(Kind kind, long primitive) {
+    private Constant(Kind kind, Object object, long primitive) {
         super(kind);
-        assert !kind.isObject();
-        this.object = null;
-        this.primitive = primitive;
-    }
-
-    /**
-     * Creates an annotated primitive constant. An annotation enables a {@linkplain MetaAccessProvider provider} to
-     * associate some extra semantic or debugging information with a primitive. An annotated primitive constant
-     * is never {@linkplain #equals(Object) equal} to a non-annotated constant.
-     *
-     * @param kind the type of this constant
-     * @param primitive the value of this constant
-     * @param annotation an arbitrary non-null object
-     */
-    public Constant(Kind kind, long primitive, Object annotation) {
-        super(kind);
-        assert !kind.isObject();
-        assert annotation != null;
-        this.object = annotation;
+        this.object = object;
         this.primitive = primitive;
     }
 
@@ -121,7 +87,7 @@
      * @return {@code true} if this constant is a primitive, or an object constant that is not null
      */
     public boolean isNonNull() {
-        return !getKind().isObject() || object != null;
+        return getKind() != Kind.Object || object != null;
     }
 
     /**
@@ -130,7 +96,7 @@
      * @return {@code true} if this constant is the null constant
      */
     public boolean isNull() {
-        return getKind().isObject() && object == null;
+        return getKind() == Kind.Object && object == null;
     }
 
     /**
@@ -145,7 +111,7 @@
     @Override
     public String toString() {
         String annotationSuffix = "";
-        if (!getKind().isObject() && getPrimitiveAnnotation() != null) {
+        if (getKind() != Kind.Object && getPrimitiveAnnotation() != null) {
             annotationSuffix = "{" + getPrimitiveAnnotation() + "}";
         }
         return getKind().getJavaName() + "[" + getKind().format(asBoxedValue()) + (getKind() != Kind.Object ? "|0x" + Long.toHexString(primitive) : "") + "]" + annotationSuffix;
@@ -187,115 +153,72 @@
         if (!ignoreKind && getKind() != other.getKind()) {
             return false;
         }
-        if (getKind().isObject()) {
+        if (getKind() == Kind.Object) {
             return object == other.object;
         }
         return primitive == other.primitive && getPrimitiveAnnotation() == other.getPrimitiveAnnotation();
     }
 
     /**
-     * Converts this constant to a primitive int.
+     * Returns the primitive int value this constant represents. The constant must have a {@link Kind#getStackKind()} of
+     * {@link Kind#Int}, or kind {@link Kind#Jsr}.
      *
-     * @return the int value of this constant
+     * @return the constant value
      */
     public int asInt() {
-        if (getKind().getStackKind().isStackInt() || getKind().isJsr()) {
-            return (int) primitive;
-        }
-        throw new Error("Constant is not int: " + this);
+        assert getKind().getStackKind() == Kind.Int || getKind() == Kind.Jsr;
+        return (int) primitive;
     }
 
     /**
-     * Converts this constant to a primitive boolean.
+     * Returns the primitive boolean value this constant represents. The constant must have kind {@link Kind#Boolean}.
      *
-     * @return the boolean value of this constant
+     * @return the constant value
      */
     public boolean asBoolean() {
-        if (getKind() == Kind.Boolean) {
-            return primitive != 0L;
-        }
-        throw new Error("Constant is not boolean: " + this);
-    }
-
-    /**
-     * Converts this constant to a primitive long.
-     *
-     * @return the long value of this constant
-     */
-    public long asLong() {
-        switch (getKind().getStackKind()) {
-            case Jsr:
-            case Int:
-            case Long:
-                return primitive;
-            case Float:
-                return (long) asFloat();
-            case Double:
-                return (long) asDouble();
-            default:
-                throw new Error("Constant is not long: " + this);
-        }
+        assert getKind() == Kind.Boolean;
+        return primitive != 0L;
     }
 
     /**
-     * Converts this constant to a primitive float.
+     * Returns the primitive long value this constant represents. The constant must have kind {@link Kind#Long}, a
+     * {@link Kind#getStackKind()} of {@link Kind#Int}, or kind {@link Kind#Jsr}.
      *
-     * @return the float value of this constant
+     * @return the constant value
      */
-    public float asFloat() {
-        if (getKind().isFloat()) {
-            return Float.intBitsToFloat((int) primitive);
-        }
-        throw new Error("Constant is not float: " + this);
-    }
-
-    /**
-     * Converts this constant to a primitive double.
-     *
-     * @return the double value of this constant
-     */
-    public double asDouble() {
-        if (getKind().isFloat()) {
-            return Float.intBitsToFloat((int) primitive);
-        }
-        if (getKind().isDouble()) {
-            return Double.longBitsToDouble(primitive);
-        }
-        throw new Error("Constant is not double: " + this);
+    public long asLong() {
+        assert getKind() == Kind.Long || getKind().getStackKind() == Kind.Int || getKind() == Kind.Jsr;
+        return primitive;
     }
 
     /**
-     * Converts this constant to the object reference it represents.
+     * Returns the primitive float value this constant represents. The constant must have kind {@link Kind#Float}.
      *
-     * @return the object which this constant represents
+     * @return the constant value
      */
-    public Object asObject() {
-        if (getKind().isObject()) {
-            return object;
-        }
-        throw new Error("Constant is not object: " + this);
+    public float asFloat() {
+        assert getKind() == Kind.Float;
+        return Float.intBitsToFloat((int) primitive);
     }
 
     /**
-     * Converts this constant to the jsr reference it represents.
+     * Returns the primitive double value this constant represents. The constant must have kind {@link Kind#Double}.
      *
-     * @return the object which this constant represents
+     * @return the constant value
      */
-    public int asJsr() {
-        if (getKind().isJsr()) {
-            return (int) primitive;
-        }
-        throw new Error("Constant is not jsr: " + this);
+    public double asDouble() {
+        assert getKind() == Kind.Double;
+        return Double.longBitsToDouble(primitive);
     }
 
     /**
-     * Unchecked access to a primitive value.
+     * Returns the object reference this constant represents. The constant must have kind {@link Kind#Object}.
+     *
+     * @return the constant value
      */
-    public long asPrimitive() {
-        if (getKind().isObject()) {
-            throw new Error("Constant is not primitive: " + this);
-        }
-        return primitive;
+    public Object asObject() {
+        assert getKind() == Kind.Object;
+        return object;
     }
 
     /**
@@ -304,7 +227,7 @@
      * @return null if this constant is not primitive or has no annotation
      */
     public Object getPrimitiveAnnotation() {
-        return getKind().isObject() ? null : object;
+        return getKind() == Kind.Object ? null : object;
     }
 
     /**
@@ -314,7 +237,7 @@
      */
     @Override
     public int hashCode() {
-        if (getKind().isObject()) {
+        if (getKind() == Kind.Object) {
             return System.identityHashCode(object);
         }
         return (int) primitive;
@@ -345,7 +268,7 @@
         if (Double.compare(d, 1.0D) == 0) {
             return DOUBLE_1;
         }
-        return new Constant(Kind.Double, Double.doubleToRawLongBits(d));
+        return new Constant(Kind.Double, null, Double.doubleToRawLongBits(d));
     }
 
     /**
@@ -364,7 +287,7 @@
         if (Float.compare(f, 2.0F) == 0) {
             return FLOAT_2;
         }
-        return new Constant(Kind.Float, Float.floatToRawIntBits(f));
+        return new Constant(Kind.Float, null, Float.floatToRawIntBits(f));
     }
 
     /**
@@ -374,7 +297,7 @@
      * @return a boxed copy of {@code value}
      */
     public static Constant forLong(long i) {
-        return i == 0 ? LONG_0 : i == 1 ? LONG_1 : new Constant(Kind.Long, i);
+        return i == 0 ? LONG_0 : i == 1 ? LONG_1 : new Constant(Kind.Long, null, i);
     }
 
     /**
@@ -390,7 +313,7 @@
         if (i >= 0 && i < INT_CONSTANT_CACHE.length) {
             return INT_CONSTANT_CACHE[i];
         }
-        return new Constant(Kind.Int, i);
+        return new Constant(Kind.Int, null, i);
     }
 
     /**
@@ -400,7 +323,7 @@
      * @return a boxed copy of {@code value}
      */
     public static Constant forByte(byte i) {
-        return new Constant(Kind.Byte, i);
+        return new Constant(Kind.Byte, null, i);
     }
 
     /**
@@ -420,7 +343,7 @@
      * @return a boxed copy of {@code value}
      */
     public static Constant forChar(char i) {
-        return new Constant(Kind.Char, i);
+        return new Constant(Kind.Char, null, i);
     }
 
     /**
@@ -430,7 +353,7 @@
      * @return a boxed copy of {@code value}
      */
     public static Constant forShort(short i) {
-        return new Constant(Kind.Short, i);
+        return new Constant(Kind.Short, null, i);
     }
 
     /**
@@ -440,7 +363,7 @@
      * @return a boxed copy of {@code value}
      */
     public static Constant forJsr(int i) {
-        return new Constant(Kind.Jsr, i);
+        return new Constant(Kind.Jsr, null, i);
     }
 
     /**
@@ -453,7 +376,27 @@
         if (o == null) {
             return NULL_OBJECT;
         }
-        return new Constant(o);
+        return new Constant(Kind.Object, o, 0L);
+    }
+
+    /**
+     * Creates an annotated int or long constant. An annotation enables a client to associate some extra semantic or
+     * debugging information with a primitive. An annotated primitive constant is never {@linkplain #equals(Object)
+     * equal} to a non-annotated constant.
+     *
+     * @param kind the type of this constant
+     * @param i the value of this constant
+     * @param annotation an arbitrary non-null object
+     */
+    public static Constant forIntegerKind(Kind kind, long i, Object annotation) {
+        switch (kind) {
+            case Int:
+                return new Constant(kind, annotation, (int) i);
+            case Long:
+                return new Constant(kind, annotation, i);
+            default:
+                throw new IllegalArgumentException("not an integer kind: " + kind);
+        }
     }
 
     /**
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Fri Nov 30 08:30:22 2012 +0100
@@ -24,8 +24,6 @@
 
 import java.lang.reflect.*;
 
-import sun.misc.*;
-
 /**
  * Denotes the basic kinds of types in CRI, including the all the Java primitive types, for example, {@link Kind#Int}
  * for {@code int} and {@link Kind#Object} for all object types. A kind has a single character short name, a Java name,
@@ -33,51 +31,54 @@
  */
 public enum Kind {
     /** The primitive boolean kind, represented as an int on the stack. */
-    Boolean('z', "boolean", true, true),
+    Boolean('z', "boolean", true, java.lang.Boolean.TYPE, java.lang.Boolean.class),
 
     /** The primitive byte kind, represented as an int on the stack. */
-    Byte('b', "byte", true, true),
+    Byte('b', "byte", true, java.lang.Byte.TYPE, java.lang.Byte.class),
 
     /** The primitive short kind, represented as an int on the stack. */
-    Short('s', "short", true, true),
+    Short('s', "short", true, java.lang.Short.TYPE, java.lang.Short.class),
 
     /** The primitive char kind, represented as an int on the stack. */
-    Char('c', "char", true, true),
+    Char('c', "char", true, java.lang.Character.TYPE, java.lang.Character.class),
 
     /** The primitive int kind, represented as an int on the stack. */
-    Int('i', "int", true, true),
+    Int('i', "int", true, java.lang.Integer.TYPE, java.lang.Integer.class),
 
     /** The primitive float kind. */
-    Float('f', "float", true, false),
+    Float('f', "float", false, java.lang.Float.TYPE, java.lang.Float.class),
 
     /** The primitive long kind. */
-    Long('j', "long", true, false),
+    Long('j', "long", false, java.lang.Long.TYPE, java.lang.Long.class),
 
     /** The primitive double kind. */
-    Double('d', "double", true, false),
+    Double('d', "double", false, java.lang.Double.TYPE, java.lang.Double.class),
 
     /** The Object kind, also used for arrays. */
-    Object('a', "Object", false, false),
+    Object('a', "Object", false, null, null),
 
     /** The void float kind. */
-    Void('v', "void", false, false),
+    Void('v', "void", false, java.lang.Void.TYPE, java.lang.Void.class),
 
     /** Denote a bytecode address in a {@code JSR} bytecode. */
-    Jsr('r', "jsr", false, false),
+    Jsr('r', "jsr", false, null, null),
 
     /** The non-type. */
-    Illegal('-', "illegal", false, false);
+    Illegal('-', "illegal", false, null, null);
 
     private final char typeChar;
     private final String javaName;
     private final boolean isStackInt;
-    private final boolean isPrimitive;
+    private final Class primitiveJavaClass;
+    private final Class boxedJavaClass;
 
-    private Kind(char typeChar, String javaName, boolean isPrimitive, boolean isStackInt) {
+    private Kind(char typeChar, String javaName, boolean isStackInt, Class primitiveJavaClass, Class boxedJavasClass) {
         this.typeChar = typeChar;
         this.javaName = javaName;
-        this.isPrimitive = isPrimitive;
         this.isStackInt = isStackInt;
+        this.primitiveJavaClass = primitiveJavaClass;
+        this.boxedJavaClass = boxedJavasClass;
+        assert primitiveJavaClass == null || javaName.equals(primitiveJavaClass.getName());
     }
 
     /**
@@ -96,22 +97,13 @@
     }
 
     /**
-     * Checks whether this type is valid as an {@code int} on the Java operand stack.
-     *
-     * @return {@code true} if this type is represented by an {@code int} on the operand stack
-     */
-    public boolean isStackInt() {
-        return this.isStackInt;
-    }
-
-    /**
      * Checks whether this type is a Java primitive type.
      *
      * @return {@code true} if this is {@link #Boolean}, {@link #Byte}, {@link #Char}, {@link #Short}, {@link #Int},
-     *         {@link #Long}, {@link #Float} or {@link #Double}.
+     *         {@link #Long}, {@link #Float}, {@link #Double}, or {@link #Void}.
      */
     public boolean isPrimitive() {
-        return this.isPrimitive;
+        return primitiveJavaClass != null;
     }
 
     /**
@@ -120,7 +112,7 @@
      * @return the kind used on the operand stack
      */
     public Kind getStackKind() {
-        if (isStackInt()) {
+        if (isStackInt) {
             return Int;
         }
         return this;
@@ -178,23 +170,23 @@
      * @return the kind
      */
     public static Kind fromJavaClass(Class< ? > klass) {
-        if (klass == java.lang.Boolean.TYPE) {
+        if (klass == Boolean.primitiveJavaClass) {
             return Boolean;
-        } else if (klass == java.lang.Byte.TYPE) {
+        } else if (klass == Byte.primitiveJavaClass) {
             return Byte;
-        } else if (klass == java.lang.Short.TYPE) {
+        } else if (klass == Short.primitiveJavaClass) {
             return Short;
-        } else if (klass == java.lang.Character.TYPE) {
+        } else if (klass == Char.primitiveJavaClass) {
             return Char;
-        } else if (klass == java.lang.Integer.TYPE) {
+        } else if (klass == Int.primitiveJavaClass) {
             return Int;
-        } else if (klass == java.lang.Long.TYPE) {
+        } else if (klass == Long.primitiveJavaClass) {
             return Long;
-        } else if (klass == java.lang.Float.TYPE) {
+        } else if (klass == Float.primitiveJavaClass) {
             return Float;
-        } else if (klass == java.lang.Double.TYPE) {
+        } else if (klass == Double.primitiveJavaClass) {
             return Double;
-        } else if (klass == java.lang.Void.TYPE) {
+        } else if (klass == Void.primitiveJavaClass) {
             return Void;
         } else {
             return Object;
@@ -207,28 +199,7 @@
      * @return the Java class
      */
     public Class< ? > toJavaClass() {
-        switch (this) {
-            case Void:
-                return java.lang.Void.TYPE;
-            case Long:
-                return java.lang.Long.TYPE;
-            case Int:
-                return java.lang.Integer.TYPE;
-            case Byte:
-                return java.lang.Byte.TYPE;
-            case Char:
-                return java.lang.Character.TYPE;
-            case Double:
-                return java.lang.Double.TYPE;
-            case Float:
-                return java.lang.Float.TYPE;
-            case Short:
-                return java.lang.Short.TYPE;
-            case Boolean:
-                return java.lang.Boolean.TYPE;
-            default:
-                return null;
-        }
+        return primitiveJavaClass;
     }
 
     /**
@@ -237,91 +208,7 @@
      * @return the Java class
      */
     public Class< ? > toBoxedJavaClass() {
-        switch (this) {
-            case Void:
-                return java.lang.Void.class;
-            case Long:
-                return java.lang.Long.class;
-            case Int:
-                return java.lang.Integer.class;
-            case Byte:
-                return java.lang.Byte.class;
-            case Char:
-                return java.lang.Character.class;
-            case Double:
-                return java.lang.Double.class;
-            case Float:
-                return java.lang.Float.class;
-            case Short:
-                return java.lang.Short.class;
-            case Boolean:
-                return java.lang.Boolean.class;
-            default:
-                return null;
-        }
-    }
-
-    /**
-     * Checks whether this value type is void.
-     *
-     * @return {@code true} if this type is void
-     */
-    public final boolean isVoid() {
-        return this == Kind.Void;
-    }
-
-    /**
-     * Checks whether this value type is long.
-     *
-     * @return {@code true} if this type is long
-     */
-    public final boolean isLong() {
-        return this == Kind.Long;
-    }
-
-    /**
-     * Checks whether this value type is float.
-     *
-     * @return {@code true} if this type is float
-     */
-    public final boolean isFloat() {
-        return this == Kind.Float;
-    }
-
-    /**
-     * Checks whether this value type is double.
-     *
-     * @return {@code true} if this type is double
-     */
-    public final boolean isDouble() {
-        return this == Kind.Double;
-    }
-
-    /**
-     * Checks whether this value type is float or double.
-     *
-     * @return {@code true} if this type is float or double
-     */
-    public final boolean isFloatOrDouble() {
-        return this == Kind.Double || this == Kind.Float;
-    }
-
-    /**
-     * Checks whether this value type is an object type.
-     *
-     * @return {@code true} if this type is an object
-     */
-    public final boolean isObject() {
-        return this == Kind.Object;
-    }
-
-    /**
-     * Checks whether this value type is an address type.
-     *
-     * @return {@code true} if this type is an address
-     */
-    public boolean isJsr() {
-        return this == Kind.Jsr;
+        return boxedJavaClass;
     }
 
     /**
@@ -346,7 +233,7 @@
      * @return a formatted string for {@code value} based on this kind
      */
     public String format(Object value) {
-        if (isObject()) {
+        if (this == Kind.Object) {
             if (value == null) {
                 return "null";
             } else {
@@ -401,112 +288,6 @@
     }
 
     /**
-     * The offset from the origin of an array to the first element.
-     *
-     * @return the offset in bytes
-     */
-    public final int getArrayBaseOffset() {
-        switch (this) {
-            case Boolean:
-                return Unsafe.ARRAY_BOOLEAN_BASE_OFFSET;
-            case Byte:
-                return Unsafe.ARRAY_BYTE_BASE_OFFSET;
-            case Char:
-                return Unsafe.ARRAY_CHAR_BASE_OFFSET;
-            case Short:
-                return Unsafe.ARRAY_SHORT_BASE_OFFSET;
-            case Int:
-                return Unsafe.ARRAY_INT_BASE_OFFSET;
-            case Long:
-                return Unsafe.ARRAY_LONG_BASE_OFFSET;
-            case Float:
-                return Unsafe.ARRAY_FLOAT_BASE_OFFSET;
-            case Double:
-                return Unsafe.ARRAY_DOUBLE_BASE_OFFSET;
-            case Object:
-                return Unsafe.ARRAY_OBJECT_BASE_OFFSET;
-            default:
-                assert false : "unexpected kind: " + this;
-                return -1;
-        }
-    }
-
-    /**
-     * The scale used for the index when accessing elements of an array of this kind.
-     *
-     * @return the scale in order to convert the index into a byte offset
-     */
-    public final int getArrayIndexScale() {
-        switch (this) {
-            case Boolean:
-                return Unsafe.ARRAY_BOOLEAN_INDEX_SCALE;
-            case Byte:
-                return Unsafe.ARRAY_BYTE_INDEX_SCALE;
-            case Char:
-                return Unsafe.ARRAY_CHAR_INDEX_SCALE;
-            case Short:
-                return Unsafe.ARRAY_SHORT_INDEX_SCALE;
-            case Int:
-                return Unsafe.ARRAY_INT_INDEX_SCALE;
-            case Long:
-                return Unsafe.ARRAY_LONG_INDEX_SCALE;
-            case Float:
-                return Unsafe.ARRAY_FLOAT_INDEX_SCALE;
-            case Double:
-                return Unsafe.ARRAY_DOUBLE_INDEX_SCALE;
-            case Object:
-                return Unsafe.ARRAY_OBJECT_INDEX_SCALE;
-            default:
-                assert false : "unexpected kind: " + this;
-                return -1;
-        }
-    }
-
-    private static Unsafe unsafeCache;
-
-    private static Unsafe unsafe() {
-        if (unsafeCache == null) {
-            unsafeCache = Unsafe.getUnsafe();
-        }
-        return unsafeCache;
-    }
-
-
-    /**
-     * Utility function for reading a value of this kind using an object and a displacement.
-     *
-     * @param object the object from which the value is read
-     * @param displacement the displacement within the object in bytes
-     * @return the read value encapsulated in a {@link Constant} object
-     */
-    public Constant readUnsafeConstant(Object object, long displacement) {
-        assert object != null : displacement;
-        switch (this) {
-            case Boolean:
-                return Constant.forBoolean(unsafe().getBoolean(object, displacement));
-            case Byte:
-                return Constant.forByte(unsafe().getByte(object, displacement));
-            case Char:
-                return Constant.forChar(unsafe().getChar(object, displacement));
-            case Short:
-                return Constant.forShort(unsafe().getShort(object, displacement));
-            case Int:
-                return Constant.forInt(unsafe().getInt(object, displacement));
-            case Long:
-                return Constant.forLong(unsafe().getLong(object, displacement));
-            case Float:
-                return Constant.forFloat(unsafe().getFloat(object, displacement));
-            case Double:
-                return Constant.forDouble(unsafe().getDouble(object, displacement));
-            case Object:
-                return Constant.forObject(unsafe().getObject(object, displacement));
-            default:
-                assert false : "unexpected kind: " + this;
-                return null;
-        }
-    }
-
-    /**
      * The minimum value that can be represented as a value of this kind.
      *
      * @return the minimum value
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Fri Nov 30 08:30:22 2012 +0100
@@ -37,6 +37,15 @@
 public class MetaUtil {
 
     /**
+     * Returns true if the specified typed is exactly the type {@link java.lang.Object}.
+     */
+    public static boolean isJavaLangObject(ResolvedJavaType type) {
+        boolean result = type.getSuperclass() == null && !type.isInterface() && type.getKind() == Kind.Object;
+        assert result == type.getName().equals("Ljava/lang/Object;") : type.getName();
+        return result;
+    }
+
+    /**
      * Gets the {@link Class} mirror for a given resolved type.
      *
      * @param type the type for which the Java mirror is requested
@@ -153,7 +162,7 @@
      */
     public static String toJavaName(JavaType type, boolean qualified) {
         Kind kind = type.getKind();
-        if (kind.isObject()) {
+        if (kind == Kind.Object) {
             return internalNameToJava(type.getName(), qualified);
         }
         return type.getKind().getJavaName();
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Fri Nov 30 08:30:22 2012 +0100
@@ -38,16 +38,6 @@
      */
     public enum Representation {
         /**
-         * The runtime representation of the data structure containing the static primitive fields of this type.
-         */
-        StaticPrimitiveFields,
-
-        /**
-         * The runtime representation of the data structure containing the static object fields of this type.
-         */
-        StaticObjectFields,
-
-        /**
          * The runtime representation of the Java class object of this type.
          */
         JavaClass,
@@ -130,13 +120,11 @@
     void initialize();
 
     /**
-     * Checks whether this type is a subtype of another type.
-     *
-     * @param other the type to test
-     * @return {@code true} if this type a subtype of the specified type
-     * @see Class#isAssignableFrom(Class)
+     * Determines if this type is either the same as, or is a superclass or superinterface of, the type represented by
+     * the specified parameter. This method is identical to {@link Class#isAssignableFrom(Class)} in terms of the value
+     * return for this type.
      */
-    boolean isAssignableTo(ResolvedJavaType other);
+    boolean isAssignableFrom(ResolvedJavaType other);
 
     /**
      * Checks whether the specified object is an instance of this type.
@@ -243,11 +231,6 @@
     <T extends Annotation> T getAnnotation(Class<T> annotationClass);
 
     /**
-     * Determines if this type is the same as that represented by a given {@link Class}.
-     */
-    boolean isClass(Class c);
-
-    /**
      * Returns the instance field of this class (or one of its super classes) at the given
      * offset, or {@code null} if there is no such field.
      *
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Fri Nov 30 08:30:22 2012 +0100
@@ -586,7 +586,7 @@
 
     @Override
     public void emitBitScanReverse(Variable result, Value value) {
-        if (value.getKind().isStackInt()) {
+        if (value.getKind().getStackKind() == Kind.Int) {
             append(new AMD64BitScanOp(AMD64BitScanOp.IntrinsicOpcode.IBSR, result, value));
         } else {
             append(new AMD64BitScanOp(AMD64BitScanOp.IntrinsicOpcode.LBSR, result, value));
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Fri Nov 30 08:30:22 2012 +0100
@@ -128,7 +128,7 @@
                 new InliningPhase(null, runtime(), hints, assumptions, null, phasePlan, OptimisticOptimizations.ALL).apply(graph);
                 new CanonicalizerPhase(null, runtime(), assumptions).apply(graph);
                 Debug.dump(graph, "Graph");
-                new BoxingEliminationPhase().apply(graph);
+                new BoxingEliminationPhase(runtime()).apply(graph);
                 Debug.dump(graph, "Graph");
                 new ExpandBoxingNodesPhase(pool).apply(graph);
                 new CanonicalizerPhase(null, runtime(), assumptions).apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfBoxingEliminationTest.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfBoxingEliminationTest.java	Fri Nov 30 08:30:22 2012 +0100
@@ -93,7 +93,7 @@
                 new PhiStampPhase().apply(graph);
                 new CanonicalizerPhase(null, runtime(), assumptions).apply(graph);
                 Debug.dump(graph, "Graph");
-                new BoxingEliminationPhase().apply(graph);
+                new BoxingEliminationPhase(runtime()).apply(graph);
                 Debug.dump(graph, "Graph");
                 new ExpandBoxingNodesPhase(pool).apply(graph);
                 new CanonicalizerPhase(null, runtime(), assumptions).apply(graph);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Fri Nov 30 08:30:22 2012 +0100
@@ -164,7 +164,7 @@
         if (GraalOptions.OptFloatingReads) {
             int mark = graph.getMark();
             new FloatingReadPhase().apply(graph);
-            new CanonicalizerPhase(target, runtime, assumptions, mark, null).apply(graph);
+            new CanonicalizerPhase(target, runtime, assumptions, mark).apply(graph);
             if (GraalOptions.OptReadElimination) {
                 new ReadEliminationPhase().apply(graph);
             }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Fri Nov 30 08:30:22 2012 +0100
@@ -507,7 +507,7 @@
     @Override
     public void visitReturn(ReturnNode x) {
         Value operand = Value.ILLEGAL;
-        if (!x.kind().isVoid()) {
+        if (x.kind() != Kind.Void) {
             operand = resultOperandFor(x.kind());
             emitMove(operand(x.result()), operand);
         }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Fri Nov 30 08:30:22 2012 +0100
@@ -159,7 +159,7 @@
             }
         }
 
-        Value returnLocation = returnKind.isVoid() ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(returnKind);
+        Value returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(returnKind);
         return new CallingConvention(currentStackOffset, returnLocation, locations);
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Fri Nov 30 08:30:22 2012 +0100
@@ -76,7 +76,7 @@
      * Reads a word value from a given address.
      */
     public static long unsafeReadWord(long address) {
-        if (wordKind.isLong()) {
+        if (wordKind == Kind.Long) {
             return unsafe.getLong(address);
         }
         return unsafe.getInt(address);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -75,8 +75,8 @@
         for (int i = 0; i < sig.length; i++) {
             Object arg = args[i];
             if (arg == null) {
-                assert sig[i].isObject() : MetaUtil.format("%H.%n(%p): expected arg ", method) + i + " to be Object, not " + sig[i];
-            } else if (!sig[i].isObject()) {
+                assert sig[i] == Kind.Object : MetaUtil.format("%H.%n(%p): expected arg ", method) + i + " to be Object, not " + sig[i];
+            } else if (sig[i] != Kind.Object) {
                 assert sig[i].toBoxedJavaClass() == arg.getClass() : MetaUtil.format("%H.%n(%p): expected arg ", method) + i + " to be " + sig[i] + ", not " + arg.getClass();
             }
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Fri Nov 30 08:30:22 2012 +0100
@@ -27,8 +27,8 @@
 import java.lang.reflect.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.meta.ResolvedJavaType.*;
 import com.oracle.graal.hotspot.*;
+import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.phases.*;
 
 /**
@@ -100,13 +100,12 @@
         if (receiver == null) {
             assert Modifier.isStatic(flags);
             if (holder.isInitialized()) {
-                Constant encoding = holder.getEncoding(getKind() == Kind.Object ? Representation.StaticObjectFields : Representation.StaticPrimitiveFields);
-                return this.getKind().readUnsafeConstant(encoding.asObject(), offset);
+                return ReadNode.readUnsafeConstant(getKind(), holder.mirror(), offset);
             }
             return null;
         } else {
             assert !Modifier.isStatic(flags);
-            return this.getKind().readUnsafeConstant(receiver.asObject(), offset);
+            return ReadNode.readUnsafeConstant(getKind(), receiver.asObject(), offset);
         }
     }
 
@@ -115,7 +114,7 @@
     }
 
     @Override
-    public ResolvedJavaType getDeclaringClass() {
+    public HotSpotResolvedObjectType getDeclaringClass() {
         return holder;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Fri Nov 30 08:30:22 2012 +0100
@@ -83,7 +83,7 @@
      * @return the {@link ResolvedJavaType} corresponding to {@code klassConstant}
      */
     public static ResolvedJavaType fromMetaspaceKlass(Constant metaspaceKlass) {
-        assert metaspaceKlass.getKind().isLong();
+        assert metaspaceKlass.getKind() == Kind.Long;
         return fromMetaspaceKlass(metaspaceKlass.asLong());
     }
 
@@ -222,10 +222,10 @@
             HotSpotResolvedObjectType t1 = this;
             HotSpotResolvedObjectType t2 = (HotSpotResolvedObjectType) otherType;
             while (true) {
-              if (t2.isAssignableTo(t1)) {
+              if (t1.isAssignableFrom(t2)) {
                   return t1;
               }
-              if (t1.isAssignableTo(t2)) {
+              if (t2.isAssignableFrom(t1)) {
                   return t2;
               }
               t1 = t1.getSupertype();
@@ -249,9 +249,6 @@
                 return Constant.forObject(javaMirror);
             case ObjectHub:
                 return klass();
-            case StaticPrimitiveFields:
-            case StaticObjectFields:
-                return Constant.forObject(javaMirror);
             default:
                 assert false : "Should not reach here.";
                 return null;
@@ -297,7 +294,7 @@
 
     @Override
     public boolean isInstance(Constant obj) {
-        if (obj.getKind().isObject() && !obj.isNull()) {
+        if (obj.getKind() == Kind.Object && !obj.isNull()) {
             return javaMirror.isInstance(obj.asObject());
         }
         return false;
@@ -314,10 +311,10 @@
     }
 
     @Override
-    public boolean isAssignableTo(ResolvedJavaType other) {
+    public boolean isAssignableFrom(ResolvedJavaType other) {
         if (other instanceof HotSpotResolvedObjectType) {
             HotSpotResolvedObjectType otherType = (HotSpotResolvedObjectType) other;
-            return otherType.javaMirror.isAssignableFrom(javaMirror);
+            return javaMirror.isAssignableFrom(otherType.javaMirror);
         }
         return false;
     }
@@ -438,11 +435,6 @@
     }
 
     @Override
-    public boolean isClass(Class c) {
-        return c == javaMirror;
-    }
-
-    @Override
     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
         return javaMirror.getAnnotation(annotationClass);
     }
@@ -456,7 +448,7 @@
      * Gets the address of the C++ Klass object for this type.
      */
     public Constant klass() {
-        return new Constant(HotSpotGraalRuntime.getInstance().getTarget().wordKind, metaspaceKlass, this);
+        return Constant.forIntegerKind(HotSpotGraalRuntime.getInstance().getTarget().wordKind, metaspaceKlass, this);
     }
 
     public boolean isPrimaryType() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Fri Nov 30 08:30:22 2012 +0100
@@ -42,7 +42,7 @@
         super(String.valueOf(Character.toUpperCase(kind.getTypeChar())));
         this.kind = kind;
         this.javaMirror = kind.toJavaClass();
-        this.javaArrayMirror = kind.isVoid() ? null : Array.newInstance(javaMirror, 0).getClass();
+        this.javaArrayMirror = kind == Kind.Void ? null : Array.newInstance(javaMirror, 0).getClass();
     }
 
     @Override
@@ -127,7 +127,7 @@
     }
 
     @Override
-    public boolean isAssignableTo(ResolvedJavaType other) {
+    public boolean isAssignableFrom(ResolvedJavaType other) {
         return other == this;
     }
 
@@ -167,11 +167,6 @@
     }
 
     @Override
-    public boolean isClass(Class c) {
-        return c == javaMirror;
-    }
-
-    @Override
     public ResolvedJavaType resolve(ResolvedJavaType accessingClass) {
         return this;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Nov 30 08:30:22 2012 +0100
@@ -38,6 +38,8 @@
 import java.lang.reflect.*;
 import java.util.*;
 
+import sun.misc.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CodeUtil.RefMapFormatter;
 import com.oracle.graal.api.code.CompilationResult.Call;
@@ -81,15 +83,75 @@
 
     private final Map<Descriptor, RuntimeCall> runtimeCalls = new HashMap<>();
 
+    /**
+     * The offset from the origin of an array to the first element.
+     *
+     * @return the offset in bytes
+     */
+    public static int getArrayBaseOffset(Kind kind) {
+        switch (kind) {
+            case Boolean:
+                return Unsafe.ARRAY_BOOLEAN_BASE_OFFSET;
+            case Byte:
+                return Unsafe.ARRAY_BYTE_BASE_OFFSET;
+            case Char:
+                return Unsafe.ARRAY_CHAR_BASE_OFFSET;
+            case Short:
+                return Unsafe.ARRAY_SHORT_BASE_OFFSET;
+            case Int:
+                return Unsafe.ARRAY_INT_BASE_OFFSET;
+            case Long:
+                return Unsafe.ARRAY_LONG_BASE_OFFSET;
+            case Float:
+                return Unsafe.ARRAY_FLOAT_BASE_OFFSET;
+            case Double:
+                return Unsafe.ARRAY_DOUBLE_BASE_OFFSET;
+            case Object:
+                return Unsafe.ARRAY_OBJECT_BASE_OFFSET;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    /**
+     * The scale used for the index when accessing elements of an array of this kind.
+     *
+     * @return the scale in order to convert the index into a byte offset
+     */
+    public static int getArrayIndexScale(Kind kind) {
+        switch (kind) {
+            case Boolean:
+                return Unsafe.ARRAY_BOOLEAN_INDEX_SCALE;
+            case Byte:
+                return Unsafe.ARRAY_BYTE_INDEX_SCALE;
+            case Char:
+                return Unsafe.ARRAY_CHAR_INDEX_SCALE;
+            case Short:
+                return Unsafe.ARRAY_SHORT_INDEX_SCALE;
+            case Int:
+                return Unsafe.ARRAY_INT_INDEX_SCALE;
+            case Long:
+                return Unsafe.ARRAY_LONG_INDEX_SCALE;
+            case Float:
+                return Unsafe.ARRAY_FLOAT_INDEX_SCALE;
+            case Double:
+                return Unsafe.ARRAY_DOUBLE_INDEX_SCALE;
+            case Object:
+                return Unsafe.ARRAY_OBJECT_INDEX_SCALE;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
     protected Value ret(Kind kind) {
-        if (kind.isVoid()) {
+        if (kind == Kind.Void) {
             return ILLEGAL;
         }
         return globalStubRegConfig.getReturnRegister(kind).asValue(kind);
     }
 
     protected Value arg(int index, Kind kind) {
-        if (kind.isFloat() || kind.isDouble()) {
+        if (kind == Kind.Float || kind == Kind.Double) {
             return globalStubRegConfig.getCallingConventionRegisters(CallingConvention.Type.RuntimeCall, RegisterFlag.FPU)[index].asValue(kind);
         }
         return globalStubRegConfig.getCallingConventionRegisters(CallingConvention.Type.RuntimeCall, RegisterFlag.CPU)[index].asValue(kind);
@@ -330,7 +392,7 @@
 
     @Override
     public ResolvedJavaType lookupJavaType(Constant constant) {
-        if (!constant.getKind().isObject() || constant.isNull()) {
+        if (constant.getKind() != Kind.Object || constant.isNull()) {
             return null;
         }
         Object o = constant.asObject();
@@ -367,7 +429,7 @@
 
     @Override
     public int lookupArrayLength(Constant array) {
-        if (!array.getKind().isObject() || array.isNull() || !array.asObject().getClass().isArray()) {
+        if (array.getKind() != Kind.Object || array.isNull() || !array.asObject().getClass().isArray()) {
             throw new IllegalArgumentException(array + " is not an array");
         }
         return Array.getLength(array.asObject());
@@ -423,13 +485,14 @@
                 callTarget.replaceAndDelete(loweredCallTarget);
             }
         } else if (n instanceof LoadFieldNode) {
-            LoadFieldNode field = (LoadFieldNode) n;
-            int displacement = ((HotSpotResolvedJavaField) field.field()).offset();
-            assert field.kind() != Kind.Illegal;
-            ReadNode memoryRead = graph.add(new ReadNode(field.object(), LocationNode.create(field.field(), field.field().getKind(), displacement, graph), field.stamp()));
-            memoryRead.dependencies().add(tool.createNullCheckGuard(field.object(), field.leafGraphId()));
-            graph.replaceFixedWithFixed(field, memoryRead);
-            if (field.isVolatile()) {
+            LoadFieldNode loadField = (LoadFieldNode) n;
+            HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) loadField.field();
+            ValueNode object = loadField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : loadField.object();
+            assert loadField.kind() != Kind.Illegal;
+            ReadNode memoryRead = graph.add(new ReadNode(object, LocationNode.create(field, field.getKind(), field.offset(), graph), loadField.stamp()));
+            memoryRead.dependencies().add(tool.createNullCheckGuard(object, loadField.leafGraphId()));
+            graph.replaceFixedWithFixed(loadField, memoryRead);
+            if (loadField.isVolatile()) {
                 MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_READ));
                 graph.addBeforeFixed(memoryRead, preMembar);
                 MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_READ));
@@ -438,8 +501,9 @@
         } else if (n instanceof StoreFieldNode) {
             StoreFieldNode storeField = (StoreFieldNode) n;
             HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field();
-            WriteNode memoryWrite = graph.add(new WriteNode(storeField.object(), storeField.value(), LocationNode.create(field, field.getKind(), field.offset(), graph)));
-            memoryWrite.dependencies().add(tool.createNullCheckGuard(storeField.object(), storeField.leafGraphId()));
+            ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : storeField.object();
+            WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), LocationNode.create(field, field.getKind(), field.offset(), graph)));
+            memoryWrite.dependencies().add(tool.createNullCheckGuard(object, storeField.leafGraphId()));
             memoryWrite.setStateAfter(storeField.stateAfter());
             graph.replaceFixedWithFixed(storeField, memoryWrite);
             FixedWithNextNode last = memoryWrite;
@@ -460,7 +524,7 @@
             ValueNode expected = cas.expected();
             if (expected.kind() == Kind.Object && !cas.newValue().objectStamp().alwaysNull()) {
                 ResolvedJavaType type = cas.object().objectStamp().type();
-                if (type != null && !type.isArray() && !type.isClass(Object.class)) {
+                if (type != null && !type.isArray() && !MetaUtil.isJavaLangObject(type)) {
                     // Use a field write barrier since it's not an array store
                     FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(cas.object()));
                     graph.addAfterFixed(cas, writeBarrier);
@@ -491,7 +555,7 @@
                 ResolvedJavaType arrayType = array.objectStamp().type();
                 if (arrayType != null && array.objectStamp().isExactType()) {
                     ResolvedJavaType elementType = arrayType.getComponentType();
-                    if (!elementType.isClass(Object.class)) {
+                    if (!MetaUtil.isJavaLangObject(elementType)) {
                         CheckCastNode checkcast = graph.add(new CheckCastNode(elementType, value, null));
                         graph.addBeforeFixed(storeIndexed, checkcast);
                         value = checkcast;
@@ -533,7 +597,7 @@
             if (write.value().kind() == Kind.Object && !write.value().objectStamp().alwaysNull()) {
                 ResolvedJavaType type = object.objectStamp().type();
                 WriteBarrier writeBarrier;
-                if (type != null && !type.isArray() && !type.isClass(Object.class)) {
+                if (type != null && !type.isArray() && !MetaUtil.isJavaLangObject(type)) {
                     // Use a field write barrier since it's not an array store
                     writeBarrier = graph.add(new FieldWriteBarrier(object));
                 } else {
@@ -581,7 +645,7 @@
     }
 
     private static IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) {
-        return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, elementKind.getArrayBaseOffset(), index, graph, true);
+        return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, getArrayBaseOffset(elementKind), index, graph, true);
     }
 
     private SafeReadNode safeReadArrayLength(ValueNode array, long leafGraphId) {
@@ -602,7 +666,7 @@
         ResolvedJavaType holder = method.getDeclaringClass();
         String fullName = method.getName() + ((HotSpotSignature) method.getSignature()).asString();
         Kind wordKind = graalRuntime.getTarget().wordKind;
-        if (holder.isClass(Object.class)) {
+        if (MetaUtil.isJavaLangObject(holder)) {
             if (fullName.equals("getClass()Ljava/lang/Class;")) {
                 ValueNode obj = (ValueNode) parameters.get(0);
                 ObjectStamp stamp = (ObjectStamp) obj.stamp();
@@ -624,7 +688,7 @@
                 hub.setNext(ret);
                 return graph;
             }
-        } else if (holder.isClass(Class.class)) {
+        } else if (holder.equals(lookupJavaType(Class.class))) {
             if (fullName.equals("getModifiers()I")) {
                 StructuredGraph graph = new StructuredGraph();
                 LocalNode receiver = graph.unique(new LocalNode(0, StampFactory.objectNonNull()));
@@ -639,7 +703,7 @@
                 klass.setNext(ret);
                 return graph;
             }
-        } else if (holder.isClass(Thread.class)) {
+        } else if (holder.equals(lookupJavaType(Thread.class))) {
             if (fullName.equals("currentThread()Ljava/lang/Thread;")) {
                 StructuredGraph graph = new StructuredGraph();
                 ReturnNode ret = graph.add(new ReturnNode(graph.unique(new CurrentThread(config.threadObjectOffset, this))));
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -56,10 +56,11 @@
     public void generate(LIRGenerator gen) {
         gen.lock();
         StackSlot lockData = gen.peekLock();
-        Value result = eliminated ? new Constant(gen.target().wordKind, 0L) : gen.emitLea(lockData);
-        FrameState stateAfter = stateAfter();
-        assert stateAfter != null;
-        gen.setResult(this, result);
+        assert stateAfter() != null;
+        if (!eliminated) {
+            Value result = gen.emitLea(lockData);
+            gen.setResult(this, result);
+        }
     }
 
     @NodeIntrinsic
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java	Fri Nov 30 08:30:22 2012 +0100
@@ -27,6 +27,7 @@
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.snippets.Snippet.Fold;
@@ -154,12 +155,12 @@
 
     @Fold
     static int arrayBaseOffset(Kind elementKind) {
-        return elementKind.getArrayBaseOffset();
+        return HotSpotRuntime.getArrayBaseOffset(elementKind);
     }
 
     @Fold
     static int arrayIndexScale(Kind elementKind) {
-        return elementKind.getArrayIndexScale();
+        return HotSpotRuntime.getArrayIndexScale(elementKind);
     }
 
     @Fold
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java	Fri Nov 30 08:30:22 2012 +0100
@@ -108,7 +108,7 @@
                             snippetMethod = objectArrayCopy;
                         }
                     } else if (componentKind == Kind.Object
-                                    && srcType.getComponentType().isAssignableTo(destType.getComponentType())) {
+                                    && destType.getComponentType().isAssignableFrom(srcType.getComponentType())) {
                         snippetMethod = objectArrayCopy;
                     }
                 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Fri Nov 30 08:30:22 2012 +0100
@@ -273,7 +273,7 @@
 
             ValueNode memory;
             if (!useTLAB) {
-                memory = ConstantNode.forConstant(new Constant(target.wordKind, 0L), runtime, graph);
+                memory = ConstantNode.defaultForKind(target.wordKind, graph);
             } else {
                 ConstantNode sizeNode = ConstantNode.forInt(size, graph);
                 TLABAllocateNode tlabAllocateNode = graph.add(new TLABAllocateNode(sizeNode));
@@ -296,11 +296,11 @@
             ResolvedJavaType arrayType = elementType.getArrayClass();
             Kind elementKind = elementType.getKind();
             final int alignment = target.wordSize;
-            final int headerSize = elementKind.getArrayBaseOffset();
+            final int headerSize = HotSpotRuntime.getArrayBaseOffset(elementKind);
             final Integer length = lengthNode.isConstant() ? Integer.valueOf(lengthNode.asConstant().asInt()) : null;
             int log2ElementSize = CodeUtil.log2(target.sizeInBytes(elementKind));
             if (!useTLAB) {
-                ConstantNode zero = ConstantNode.forConstant(new Constant(target.wordKind, 0L), runtime, graph);
+                ConstantNode zero = ConstantNode.defaultForKind(target.wordKind, graph);
                 // value for 'size' doesn't matter as it isn't used since a stub call will be made anyway
                 // for both allocation and initialization - it just needs to be non-null
                 ConstantNode size = ConstantNode.forInt(-1, graph);
@@ -363,8 +363,8 @@
             assert elementType != null;
             ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph);
             Kind elementKind = elementType.getKind();
-            final int headerSize = elementKind.getArrayBaseOffset();
-            Key key = new Key(elementKind.isObject() ? initializeObjectArray : initializePrimitiveArray).add("headerSize", headerSize).add("fillContents", initializeNode.fillContents()).add("locked", initializeNode.locked());
+            final int headerSize = HotSpotRuntime.getArrayBaseOffset(elementKind);
+            Key key = new Key(elementKind == Kind.Object ? initializeObjectArray : initializePrimitiveArray).add("headerSize", headerSize).add("fillContents", initializeNode.fillContents()).add("locked", initializeNode.locked());
             ValueNode memory = initializeNode.memory();
             Arguments arguments = arguments("memory", memory).add("hub", hub).add("prototypeMarkWord", type.prototypeMarkWord()).add("size", initializeNode.size()).add("length", initializeNode.length());
             SnippetTemplate template = cache.get(key, assumptions);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Fri Nov 30 08:30:22 2012 +0100
@@ -762,7 +762,7 @@
         while (stream.currentBCI() <= block.endBci) {
             switch (stream.currentBC()) {
                 case RETURN:
-                    if (method.isConstructor() && method.getDeclaringClass().isClass(Object.class)) {
+                    if (method.isConstructor() && MetaUtil.isJavaLangObject(method.getDeclaringClass())) {
                         // return from Object.init implicitly registers a finalizer
                         // for the receiver if needed, so keep it alive.
                         loadOne(block, 0);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Nov 30 08:30:22 2012 +0100
@@ -536,7 +536,7 @@
         ValueNode b = mirror ? x : y;
 
         CompareNode condition;
-        assert !a.kind().isFloatOrDouble();
+        assert a.kind() != Kind.Double && a.kind() != Kind.Float;
         if (cond == Condition.EQ || cond == Condition.NE) {
             if (a.kind() == Kind.Object) {
                 condition = new ObjectEqualsNode(a, b);
@@ -832,37 +832,28 @@
     }
 
     private void genGetStatic(JavaField field) {
-        JavaType holder = field.getDeclaringClass();
-        boolean isInitialized = (field instanceof ResolvedJavaField) && ((ResolvedJavaType) holder).isInitialized();
-        Constant constantValue = null;
-        if (isInitialized) {
-            constantValue = ((ResolvedJavaField) field).readConstantValue(null);
-        }
-        if (constantValue != null) {
-            frameState.push(constantValue.getKind().getStackKind(), appendConstant(constantValue));
+        Kind kind = field.getKind();
+        if (field instanceof ResolvedJavaField && ((ResolvedJavaType) field.getDeclaringClass()).isInitialized()) {
+            Constant constantValue = ((ResolvedJavaField) field).readConstantValue(null);
+            if (constantValue != null) {
+                frameState.push(constantValue.getKind().getStackKind(), appendConstant(constantValue));
+            } else {
+                LoadFieldNode load = currentGraph.add(new LoadFieldNode(null, (ResolvedJavaField) field, graphId));
+                appendOptimizedLoadField(kind, load);
+            }
         } else {
-            ValueNode container = genTypeOrDeopt(field.getKind() == Kind.Object ? Representation.StaticObjectFields : Representation.StaticPrimitiveFields, holder, isInitialized);
-            Kind kind = field.getKind();
-            if (container != null) {
-                LoadFieldNode load = currentGraph.add(new LoadFieldNode(container, (ResolvedJavaField) field, graphId));
-                appendOptimizedLoadField(kind, load);
-            } else {
-                // deopt will be generated by genTypeOrDeopt, not needed here
-                frameState.push(kind.getStackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
-            }
+            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
+            frameState.push(kind.getStackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
         }
     }
 
     private void genPutStatic(JavaField field) {
-        JavaType holder = field.getDeclaringClass();
-        boolean isInitialized = (field instanceof ResolvedJavaField) && ((ResolvedJavaType) holder).isInitialized();
-        ValueNode container = genTypeOrDeopt(field.getKind() == Kind.Object ? Representation.StaticObjectFields : Representation.StaticPrimitiveFields, holder, isInitialized);
         ValueNode value = frameState.pop(field.getKind().getStackKind());
-        if (container != null) {
-            StoreFieldNode store = currentGraph.add(new StoreFieldNode(container, (ResolvedJavaField) field, value, graphId));
+        if (field instanceof ResolvedJavaField && ((ResolvedJavaType) field.getDeclaringClass()).isInitialized()) {
+            StoreFieldNode store = currentGraph.add(new StoreFieldNode(null, (ResolvedJavaField) field, value, graphId));
             appendOptimizedStoreField(store);
         } else {
-            // deopt will be generated by genTypeOrDeopt, not needed here
+            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
         }
     }
 
@@ -1396,7 +1387,7 @@
     }
 
     private void createReturn() {
-        if (method.isConstructor() && method.getDeclaringClass().isClass(Object.class)) {
+        if (method.isConstructor() && MetaUtil.isJavaLangObject(method.getDeclaringClass())) {
             callRegisterFinalizer();
         }
         Kind returnKind = method.getSignature().getReturnKind().getStackKind();
@@ -1442,7 +1433,7 @@
         if (initialized && graphBuilderConfig.getSkippedExceptionTypes() != null) {
             ResolvedJavaType resolvedCatchType = (ResolvedJavaType) catchType;
             for (ResolvedJavaType skippedType : graphBuilderConfig.getSkippedExceptionTypes()) {
-                initialized &= !resolvedCatchType.isAssignableTo(skippedType);
+                initialized &= !skippedType.isAssignableFrom(resolvedCatchType);
                 if (!initialized) {
                     break;
                 }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java	Fri Nov 30 08:30:22 2012 +0100
@@ -44,10 +44,6 @@
             return null;
         }
         @Override
-        public boolean isImmutable(Constant objectConstant) {
-            return false;
-        }
-        @Override
         public Assumptions assumptions() {
             return null;
         }
@@ -85,7 +81,7 @@
         while (!loopBegin.isDeleted()) {
             int mark = graph.getMark();
             peel(loop);
-            new CanonicalizerPhase(null, runtime, assumptions, mark, null).apply(graph);
+            new CanonicalizerPhase(null, runtime, assumptions, mark).apply(graph);
             if (iterations++ > UNROLL_LIMIT || graph.getNodeCount() > GraalOptions.MaximumDesiredSize * 3) {
                 throw new BailoutException("FullUnroll : Graph seems to grow out of proportion");
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -224,7 +224,7 @@
     @Override
     public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
         Map<Object, Object> properties = super.getDebugProperties(map);
-        properties.put("rawvalue", value.getKind().isObject() ? value.getKind().format(value.asBoxedValue()) : value.asBoxedValue());
+        properties.put("rawvalue", value.getKind() == Kind.Object ? value.getKind().format(value.asBoxedValue()) : value.asBoxedValue());
         return properties;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Fri Nov 30 08:30:22 2012 +0100
@@ -232,7 +232,7 @@
                 copy.remove(copy.size() - 1);
             }
             ValueNode lastSlot = copy.get(copy.size() - 1);
-            assert lastSlot.kind().getStackKind() == popKind.getStackKind() || (lastSlot instanceof BoxedVirtualObjectNode && popKind.isObject());
+            assert lastSlot.kind().getStackKind() == popKind.getStackKind() || (lastSlot instanceof BoxedVirtualObjectNode && popKind == Kind.Object);
             copy.remove(copy.size() - 1);
         }
         Collections.addAll(copy, pushedValues);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -141,7 +141,7 @@
 
     @Override
     public void intrinsify(Node node) {
-        assert !(node instanceof ValueNode) || ((ValueNode) node).kind().isVoid() == kind().isVoid();
+        assert !(node instanceof ValueNode) || (((ValueNode) node).kind() == Kind.Void) == (kind() == Kind.Void);
         CallTargetNode call = callTarget;
         FrameState stateAfter = stateAfter();
         if (node instanceof StateSplit) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -177,7 +177,7 @@
 
     @Override
     public void intrinsify(Node node) {
-        assert !(node instanceof ValueNode) || ((ValueNode) node).kind().isVoid() == kind().isVoid();
+        assert !(node instanceof ValueNode) || (((ValueNode) node).kind() == Kind.Void) == (kind() == Kind.Void);
         CallTargetNode call = callTarget;
         FrameState state = stateAfter();
         killExceptionEdge();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -131,22 +131,22 @@
     public static CompareNode createCompareNode(Condition condition, ValueNode x, ValueNode y) {
         assert x.kind() == y.kind();
         assert condition.isCanonical() : "condition is not canonical: " + condition;
+        assert x.kind() != Kind.Double && x.kind() != Kind.Float;
 
-        assert !x.kind().isFloatOrDouble();
         CompareNode comparison;
         if (condition == Condition.EQ) {
-            if (x.kind().isObject()) {
+            if (x.kind() == Kind.Object) {
                 comparison = new ObjectEqualsNode(x, y);
             } else {
-                assert x.kind().getStackKind().isStackInt() || x.kind().isLong();
+                assert x.kind().getStackKind() == Kind.Int || x.kind() == Kind.Long;
                 comparison = new IntegerEqualsNode(x, y);
             }
         } else if (condition == Condition.LT) {
-            assert x.kind().getStackKind().isStackInt() || x.kind().isLong();
+            assert x.kind().getStackKind() == Kind.Int || x.kind() == Kind.Long;
             comparison = new IntegerLessThanNode(x, y);
         } else {
             assert condition == Condition.BT;
-            assert x.kind().getStackKind().isStackInt() || x.kind().isLong();
+            assert x.kind().getStackKind() == Kind.Int || x.kind() == Kind.Long;
             comparison = new IntegerBelowThanNode(x, y);
         }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/Condition.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/Condition.java	Fri Nov 30 08:30:22 2012 +0100
@@ -247,7 +247,7 @@
      * {@link Boolean#FALSE} if the comparison is known to be false
      */
     public boolean foldCondition(Constant lt, Constant rt, CodeCacheProvider runtime) {
-        assert !lt.getKind().isFloatOrDouble() && !rt.getKind().isFloatOrDouble();
+        assert lt.getKind() != Kind.Double && lt.getKind() != Kind.Float && rt.getKind() != Kind.Double && rt.getKind() != Kind.Float;
         return foldCondition(lt, rt, runtime, false);
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 
@@ -36,8 +37,8 @@
      */
     public FloatEqualsNode(ValueNode x, ValueNode y) {
         super(x, y);
-        assert x.kind().isFloatOrDouble();
-        assert y.kind().isFloatOrDouble();
+        assert x.kind() == Kind.Double || x.kind() == Kind.Float;
+        assert y.kind() == Kind.Double || y.kind() == Kind.Float;
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -40,8 +41,8 @@
      */
     public FloatLessThanNode(ValueNode x, ValueNode y, boolean unorderedIsTrue) {
         super(x, y);
-        assert x.kind().isFloatOrDouble();
-        assert y.kind().isFloatOrDouble();
+        assert x.kind() == Kind.Double || x.kind() == Kind.Float;
+        assert y.kind() == Kind.Double || y.kind() == Kind.Float;
         this.unorderedIsTrue = unorderedIsTrue;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -79,13 +79,13 @@
 
     public static boolean isIntegerAddition(ValueNode result, ValueNode a, ValueNode b) {
         Kind kind = result.kind();
-        if (kind != a.kind() || kind != b.kind() || !(kind.isStackInt() || kind.isLong())) {
+        if (kind != a.kind() || kind != b.kind() || !(kind.getStackKind() == Kind.Int || kind == Kind.Long)) {
             return false;
         }
         if (result.isConstant() && a.isConstant() && b.isConstant()) {
-            if (kind.isStackInt()) {
+            if (kind.getStackKind() == Kind.Int) {
                 return result.asConstant().asInt() == a.asConstant().asInt() + b.asConstant().asInt();
-            } else if (kind.isLong()) {
+            } else if (kind == Kind.Long) {
                 return result.asConstant().asLong() == a.asConstant().asLong() + b.asConstant().asLong();
             }
         } else if (result instanceof IntegerAddNode) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -39,8 +39,8 @@
      */
     public IntegerBelowThanNode(ValueNode x, ValueNode y) {
         super(x, y);
-        assert !x.kind().isFloatOrDouble() && x.kind() != Kind.Object;
-        assert !y.kind().isFloatOrDouble() && y.kind() != Kind.Object;
+        assert x.kind() != Kind.Double && x.kind() != Kind.Float && x.kind() != Kind.Object;
+        assert y.kind() != Kind.Double && y.kind() != Kind.Float && y.kind() != Kind.Object;
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -70,10 +70,10 @@
                 // no rounding if dividend is positive or if its low bits are always 0
                 if (stampX.canBeNegative() || (stampX.mask() & (abs - 1)) != 0) {
                     int bits;
-                    if (kind().isStackInt()) {
+                    if (kind().getStackKind() == Kind.Int) {
                         bits = 32;
                     } else {
-                        assert kind().isLong();
+                        assert kind() == Kind.Long;
                         bits = 64;
                     }
                     RightShiftNode sign = graph().unique(new RightShiftNode(kind(), x(), ConstantNode.forInt(bits - 1, graph())));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -38,8 +38,8 @@
      */
     public IntegerEqualsNode(ValueNode x, ValueNode y) {
         super(x, y);
-        assert !x.kind().isFloatOrDouble() && x.kind() != Kind.Object;
-        assert !y.kind().isFloatOrDouble() && y.kind() != Kind.Object;
+        assert x.kind() != Kind.Double && x.kind() != Kind.Float && x.kind() != Kind.Object;
+        assert y.kind() != Kind.Double && y.kind() != Kind.Float && y.kind() != Kind.Object;
     }
 
     @Override
@@ -58,7 +58,7 @@
             ValueNode a = mirrored ? normalizeNode.y() : normalizeNode.x();
             ValueNode b = mirrored ? normalizeNode.x() : normalizeNode.y();
 
-            if (normalizeNode.x().kind().isFloatOrDouble()) {
+            if (normalizeNode.x().kind() == Kind.Double || normalizeNode.x().kind() == Kind.Float) {
                 return graph().unique(new FloatEqualsNode(a, b));
             } else {
                 return graph().unique(new IntegerEqualsNode(a, b));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -39,8 +39,8 @@
      */
     public IntegerLessThanNode(ValueNode x, ValueNode y) {
         super(x, y);
-        assert !x.kind().isFloatOrDouble() && x.kind() != Kind.Object;
-        assert !y.kind().isFloatOrDouble() && y.kind() != Kind.Object;
+        assert x.kind() != Kind.Double && x.kind() != Kind.Float && x.kind() != Kind.Object;
+        assert y.kind() != Kind.Double && y.kind() != Kind.Float && y.kind() != Kind.Object;
     }
 
     @Override
@@ -60,7 +60,7 @@
             ValueNode a = mirrored ? normalizeNode.y() : normalizeNode.x();
             ValueNode b = mirrored ? normalizeNode.x() : normalizeNode.y();
 
-            if (normalizeNode.x().kind().isFloatOrDouble()) {
+            if (normalizeNode.x().kind() == Kind.Double || normalizeNode.x().kind() == Kind.Float) {
                 return graph().unique(new FloatLessThanNode(a, b, mirrored ^ normalizeNode.isUnorderedLess));
             } else {
                 return graph().unique(new IntegerLessThanNode(a, b));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -57,7 +57,7 @@
     @Override
     public boolean verify() {
         assertTrue(object() != null, "is null input must not be null");
-        assertTrue(object().kind().isObject(), "is null input must be an object");
+        assertTrue(object().kind() == Kind.Object, "is null input must be an object");
         return super.verify();
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -50,7 +50,7 @@
 
         BooleanNode equalComp;
         BooleanNode lessComp;
-        if (x().kind().isFloatOrDouble()) {
+        if (x().kind() == Kind.Double || x().kind() == Kind.Float) {
             equalComp = graph.unique(new FloatEqualsNode(x(), y()));
             lessComp = graph.unique(new FloatLessThanNode(x(), y(), isUnorderedLess));
         } else {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java	Fri Nov 30 08:30:22 2012 +0100
@@ -22,32 +22,11 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import java.lang.reflect.*;
 import java.util.*;
-import java.util.Map.Entry;
 
 import com.oracle.graal.api.meta.*;
 
 public class BoxingMethodPool {
-    private static final Map<Kind, BoxingMethod> boxings = new HashMap<>();
-    private static class BoxingMethod {
-        final Class<?> type;
-        final String unboxMethod;
-        public BoxingMethod(Class< ? > type, String unboxMethod) {
-            this.type = type;
-            this.unboxMethod = unboxMethod;
-        }
-    }
-    static {
-        boxings.put(Kind.Boolean, new BoxingMethod(Boolean.class, "booleanValue"));
-        boxings.put(Kind.Byte, new BoxingMethod(Byte.class, "byteValue"));
-        boxings.put(Kind.Char, new BoxingMethod(Character.class, "charValue"));
-        boxings.put(Kind.Short, new BoxingMethod(Short.class, "shortValue"));
-        boxings.put(Kind.Int, new BoxingMethod(Integer.class, "intValue"));
-        boxings.put(Kind.Long, new BoxingMethod(Long.class, "longValue"));
-        boxings.put(Kind.Float, new BoxingMethod(Float.class, "floatValue"));
-        boxings.put(Kind.Double, new BoxingMethod(Double.class, "doubleValue"));
-    }
 
     private final Set<JavaMethod> specialMethods = new HashSet<>();
     private final MetaAccessProvider runtime;
@@ -57,25 +36,22 @@
 
     public BoxingMethodPool(MetaAccessProvider runtime) {
         this.runtime = runtime;
-        initialize();
-    }
 
-    private void initialize() {
         try {
-            for (Entry<Kind, BoxingMethod> entry : boxings.entrySet()) {
-                Kind kind = entry.getKey();
-                BoxingMethod boxing = entry.getValue();
-                initialize(kind, boxing.type, boxing.unboxMethod);
-            }
-        } catch (SecurityException e) {
-            throw new RuntimeException(e);
-        } catch (NoSuchMethodException e) {
+            initialize(Kind.Boolean, Boolean.class, "booleanValue");
+            initialize(Kind.Byte, Byte.class, "byteValue");
+            initialize(Kind.Char, Character.class, "charValue");
+            initialize(Kind.Short, Short.class, "shortValue");
+            initialize(Kind.Int, Integer.class, "intValue");
+            initialize(Kind.Long, Long.class, "longValue");
+            initialize(Kind.Float, Float.class, "floatValue");
+            initialize(Kind.Double, Double.class, "doubleValue");
+        } catch (SecurityException | NoSuchMethodException e) {
             throw new RuntimeException(e);
         }
     }
 
     private void initialize(Kind kind, Class<?> type, String unboxMethod) throws SecurityException, NoSuchMethodException {
-
         // Get boxing method from runtime.
         ResolvedJavaMethod boxingMethod = runtime.lookupJavaMethod(type.getDeclaredMethod("valueOf", kind.toJavaClass()));
         specialMethods.add(boxingMethod);
@@ -116,38 +92,4 @@
     public ResolvedJavaField getBoxField(Kind kind) {
         return boxFields[kind.ordinal()];
     }
-
-    public static boolean isSpecialMethodStatic(ResolvedJavaMethod method) {
-        return isUnboxingMethodStatic(method) || isBoxingMethodStatic(method);
-    }
-
-    public static boolean isBoxingMethodStatic(ResolvedJavaMethod method) {
-        Signature signature = method.getSignature();
-        if (!Modifier.isStatic(method.getModifiers())
-                        || signature.getReturnKind() == Kind.Object
-                        || signature.getParameterCount(false) != 1) {
-            return false;
-        }
-        Kind kind = signature.getParameterKind(0);
-        BoxingMethod boxing = boxings.get(kind);
-        if (boxing == null) {
-            return false;
-        }
-        return method.getDeclaringClass().isClass(boxing.type) && method.getName().equals("valueOf");
-    }
-
-    public static boolean isUnboxingMethodStatic(ResolvedJavaMethod method) {
-        Signature signature = method.getSignature();
-        if (signature.getReturnKind() == Kind.Object
-                        || signature.getParameterCount(false) != 0
-                        || Modifier.isStatic(method.getModifiers())) {
-            return false;
-        }
-        Kind kind = signature.getReturnKind();
-        BoxingMethod boxing = boxings.get(kind);
-        if (boxing == null) {
-            return false;
-        }
-        return method.getDeclaringClass().isClass(boxing.type) && method.getName().equals(boxing.unboxMethod);
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.extended;
 
+import static com.oracle.graal.graph.FieldIntrospection.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -47,6 +48,39 @@
         return canonicalizeRead(this, tool);
     }
 
+    /**
+     * Utility function for reading a value of this kind using an object and a displacement.
+     *
+     * @param object the object from which the value is read
+     * @param displacement the displacement within the object in bytes
+     * @return the read value encapsulated in a {@link Constant} object
+     */
+    public static Constant readUnsafeConstant(Kind kind, Object object, long displacement) {
+        assert object != null;
+        switch (kind) {
+            case Boolean:
+                return Constant.forBoolean(unsafe.getBoolean(object, displacement));
+            case Byte:
+                return Constant.forByte(unsafe.getByte(object, displacement));
+            case Char:
+                return Constant.forChar(unsafe.getChar(object, displacement));
+            case Short:
+                return Constant.forShort(unsafe.getShort(object, displacement));
+            case Int:
+                return Constant.forInt(unsafe.getInt(object, displacement));
+            case Long:
+                return Constant.forLong(unsafe.getLong(object, displacement));
+            case Float:
+                return Constant.forFloat(unsafe.getFloat(object, displacement));
+            case Double:
+                return Constant.forDouble(unsafe.getDouble(object, displacement));
+            case Object:
+                return Constant.forObject(unsafe.getObject(object, displacement));
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
     public static ValueNode canonicalizeRead(Access read, CanonicalizerTool tool) {
         MetaAccessProvider runtime = tool.runtime();
         if (runtime != null && read.object() != null && read.object().isConstant() && read.object().kind() == Kind.Object) {
@@ -55,10 +89,8 @@
                 if (value != null) {
                     long displacement = read.location().displacement();
                     Kind kind = read.location().getValueKind();
-                    Constant constant = kind.readUnsafeConstant(value, displacement);
-                    if (constant != null) {
-                        return ConstantNode.forConstant(constant, runtime, read.node().graph());
-                    }
+                    Constant constant = readUnsafeConstant(kind, value, displacement);
+                    return ConstantNode.forConstant(constant, runtime, read.node().graph());
                 }
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -46,7 +46,7 @@
     }
 
     public UnsafeCastNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
-        this(object, toType.getKind().isObject() ? StampFactory.object(toType, exactType, nonNull || object.stamp().nonNull()) : StampFactory.forKind(toType.getKind()));
+        this(object, toType.getKind() == Kind.Object ? StampFactory.object(toType, exactType, nonNull || object.stamp().nonNull()) : StampFactory.forKind(toType.getKind()));
     }
 
     @Override
@@ -68,7 +68,7 @@
             if (my.nonNull() && !other.nonNull()) {
                 return this;
             }
-            if (my.type() != other.type() && my.type().isAssignableTo(other.type())) {
+            if (my.type() != other.type() && other.type().isAssignableFrom(my.type())) {
                 return this;
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -100,7 +100,7 @@
 
     @Override
     public boolean verify() {
-        assertTrue(object != null, "Access object can not be null");
+        assertTrue((object == null) == isStatic(), "static field must not have object, instance field must have object");
         return super.verify();
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -72,7 +72,7 @@
 
         if (type != null) {
             ResolvedJavaType objectType = object().objectStamp().type();
-            if (objectType != null && objectType.isAssignableTo(type)) {
+            if (objectType != null && type.isAssignableFrom(objectType)) {
                 // we don't have to check for null types here because they will also pass the checkcast.
                 return object();
             }
@@ -102,7 +102,7 @@
     @Override
     public void virtualize(VirtualizerTool tool) {
         VirtualObjectNode virtual = tool.getVirtualState(object());
-        if (virtual != null && virtual.type().isAssignableTo(type())) {
+        if (virtual != null && type().isAssignableFrom(virtual.type())) {
             tool.replaceWithVirtual(virtual);
         }
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -70,7 +70,7 @@
         ResolvedJavaType stampType = stamp.type();
 
         if (stamp.isExactType()) {
-            boolean subType = stampType.isAssignableTo(type());
+            boolean subType = type().isAssignableFrom(stampType);
 
             if (subType) {
                 if (stamp.nonNull()) {
@@ -87,7 +87,7 @@
                 return ConstantNode.forBoolean(false, graph());
             }
         } else if (stampType != null) {
-            boolean subType = stampType.isAssignableTo(type());
+            boolean subType = type().isAssignableFrom(stampType);
 
             if (subType) {
                 if (stamp.nonNull()) {
@@ -135,7 +135,7 @@
     public void virtualize(VirtualizerTool tool) {
         VirtualObjectNode virtual = tool.getVirtualState(object());
         if (virtual != null) {
-            tool.replaceWithValue(ConstantNode.forBoolean(virtual.type().isAssignableTo(type()), graph()));
+            tool.replaceWithValue(ConstantNode.forBoolean(type().isAssignableFrom(virtual.type()), graph()));
         }
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.nodes.java;
 
-import java.lang.reflect.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -34,7 +32,7 @@
 /**
  * The {@code LoadIndexedNode} represents a read from an element of an array.
  */
-public final class LoadIndexedNode extends AccessIndexedNode implements Canonicalizable, Node.IterableNodeType, Virtualizable {
+public final class LoadIndexedNode extends AccessIndexedNode implements Node.IterableNodeType, Virtualizable {
 
     /**
      * Creates a new LoadIndexedNode.
@@ -55,24 +53,6 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        MetaAccessProvider runtime = tool.runtime();
-        if (runtime != null && index().isConstant() && array().isConstant() && !array().isNullConstant()) {
-            Constant arrayConst = array().asConstant();
-            if (tool.isImmutable(arrayConst)) {
-                int index = index().asConstant().asInt();
-                Object array = arrayConst.asObject();
-                int length = Array.getLength(array);
-                if (index >= 0 && index < length) {
-                    return ConstantNode.forConstant(elementKind().readUnsafeConstant(array,
-                                    elementKind().getArrayBaseOffset() + index * elementKind().getArrayIndexScale()), runtime, graph());
-                }
-            }
-        }
-        return this;
-    }
-
-    @Override
     public void virtualize(VirtualizerTool tool) {
         VirtualObjectNode virtualArray = tool.getVirtualState(array());
         if (virtualArray != null) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -98,7 +98,7 @@
             if (stamp.type() != null) {
                 int validKeys = 0;
                 for (int i = 0; i < keyCount(); i++) {
-                    if (keys[i].isAssignableTo(stamp.type())) {
+                    if (stamp.type().isAssignableFrom(keys[i])) {
                         validKeys++;
                     }
                 }
@@ -113,7 +113,7 @@
                     double totalProbability = 0;
                     int current = 0;
                     for (int i = 0; i < keyCount() + 1; i++) {
-                        if (i == keyCount() || keys[i].isAssignableTo(stamp.type())) {
+                        if (i == keyCount() || stamp.type().isAssignableFrom(keys[i])) {
                             int index = newSuccessors.indexOf(keySuccessor(i));
                             if (index == -1) {
                                 index = newSuccessors.size();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/CanonicalizerTool.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/CanonicalizerTool.java	Fri Nov 30 08:30:22 2012 +0100
@@ -30,10 +30,4 @@
     TargetDescription target();
     Assumptions assumptions();
     MetaAccessProvider runtime();
-
-    /**
-     * Determines if a given constant is an object/array whose current
-     * fields/elements will never change.
-     */
-    boolean isImmutable(Constant objectConstant);
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java	Fri Nov 30 08:30:22 2012 +0100
@@ -78,7 +78,7 @@
             return false;
         } else if (other.nonNull || nonNull) {
             // One of the two values cannot be null.
-            return !other.type.isInterface() && !type.isInterface() && !other.type.isAssignableTo(type) && !type.isAssignableTo(other.type);
+            return !other.type.isInterface() && !type.isInterface() && !type.isAssignableFrom(other.type) && !other.type.isAssignableFrom(type);
         }
         return false;
     }
@@ -139,7 +139,7 @@
             joinType = type;
         } else {
             // both types are != null
-            if (other.type.isAssignableTo(type)) {
+            if (type.isAssignableFrom(other.type)) {
                 joinType = other.type;
             } else {
                 joinType = type;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Fri Nov 30 08:30:22 2012 +0100
@@ -137,7 +137,9 @@
         } else {
             if (value.getKind() == Kind.Int || value.getKind() == Kind.Long) {
                 return forInteger(value.getKind(), value.asLong(), value.asLong(), value.asLong() & IntegerStamp.defaultMask(value.getKind()));
-            } else if (value.getKind() == Kind.Float || value.getKind() == Kind.Double) {
+            } else if (value.getKind() == Kind.Float) {
+                return forFloat(value.getKind(), value.asFloat(), value.asFloat(), !Float.isNaN(value.asFloat()));
+            } else if (value.getKind() == Kind.Double) {
                 return forFloat(value.getKind(), value.asDouble(), value.asDouble(), !Double.isNaN(value.asDouble()));
             }
             return forKind(value.getKind().getStackKind());
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/BoxingEliminationPhase.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/BoxingEliminationPhase.java	Fri Nov 30 08:30:22 2012 +0100
@@ -37,8 +37,13 @@
 
 public class BoxingEliminationPhase extends Phase {
 
+    private final MetaAccessProvider metaAccess;
     private int virtualIds = Integer.MIN_VALUE;
 
+    public BoxingEliminationPhase(MetaAccessProvider metaAccess) {
+        this.metaAccess = metaAccess;
+    }
+
     @Override
     protected void run(StructuredGraph graph) {
         if (graph.getNodes(UnboxNode.class).isNotEmpty()) {
@@ -71,7 +76,7 @@
             ObjectStamp stamp = phiNode.objectStamp();
             if (stamp.nonNull() && stamp.isExactType()) {
                 ResolvedJavaType type = stamp.type();
-                if (type != null && type.isClass(kind.toBoxedJavaClass())) {
+                if (type != null && type.equals(metaAccess.lookupJavaType(kind.toBoxedJavaClass()))) {
                     StructuredGraph graph = (StructuredGraph) phiNode.graph();
                     result = graph.add(new PhiNode(kind, phiNode.merge()));
                     phiReplacements.put(phiNode, result);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Fri Nov 30 08:30:22 2012 +0100
@@ -50,7 +50,6 @@
     private final TargetDescription target;
     private final Assumptions assumptions;
     private final MetaAccessProvider runtime;
-    private final IsImmutablePredicate immutabilityPredicate;
     private final Iterable<Node> initWorkingSet;
 
     private NodeWorkList workList;
@@ -58,7 +57,7 @@
     private List<Node> snapshotTemp;
 
     public CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions) {
-        this(target, runtime, assumptions, null, 0, null);
+        this(target, runtime, assumptions, null, 0);
     }
 
     /**
@@ -66,26 +65,24 @@
      * @param runtime
      * @param assumptions
      * @param workingSet the initial working set of nodes on which the canonicalizer works, should be an auto-grow node bitmap
-     * @param immutabilityPredicate
      */
-    public CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, Iterable<Node> workingSet, IsImmutablePredicate immutabilityPredicate) {
-        this(target, runtime, assumptions, workingSet, 0, immutabilityPredicate);
+    public CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, Iterable<Node> workingSet) {
+        this(target, runtime, assumptions, workingSet, 0);
     }
 
     /**
      * @param newNodesMark only the {@linkplain Graph#getNewNodes(int) new nodes} specified by
      *            this mark are processed otherwise all nodes in the graph are processed
      */
-    public CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, int newNodesMark, IsImmutablePredicate immutabilityPredicate) {
-        this(target, runtime, assumptions, null, newNodesMark, immutabilityPredicate);
+    public CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, int newNodesMark) {
+        this(target, runtime, assumptions, null, newNodesMark);
     }
 
-    private CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, Iterable<Node> workingSet, int newNodesMark, IsImmutablePredicate immutabilityPredicate) {
+    private CanonicalizerPhase(TargetDescription target, MetaAccessProvider runtime, Assumptions assumptions, Iterable<Node> workingSet, int newNodesMark) {
         this.newNodesMark = newNodesMark;
         this.target = target;
         this.assumptions = assumptions;
         this.runtime = runtime;
-        this.immutabilityPredicate = immutabilityPredicate;
         this.initWorkingSet = workingSet;
         this.snapshotTemp = new ArrayList<>();
     }
@@ -101,18 +98,10 @@
             workList = graph.createNodeWorkList(false, MAX_ITERATION_PER_NODE);
             workList.addAll(initWorkingSet);
         }
-        tool = new Tool(workList, runtime, target, assumptions, immutabilityPredicate);
+        tool = new Tool(workList, runtime, target, assumptions);
         processWorkSet(graph);
     }
 
-    public interface IsImmutablePredicate {
-        /**
-         * Determines if a given constant is an object/array whose current
-         * fields/elements will never change.
-         */
-        boolean apply(Constant constant);
-    }
-
     private void processWorkSet(StructuredGraph graph) {
         graph.trackInputChange(new InputChangedListener() {
             @Override
@@ -288,14 +277,12 @@
         private final MetaAccessProvider runtime;
         private final TargetDescription target;
         private final Assumptions assumptions;
-        private final IsImmutablePredicate immutabilityPredicate;
 
-        public Tool(NodeWorkList nodeWorkSet, MetaAccessProvider runtime, TargetDescription target, Assumptions assumptions, IsImmutablePredicate immutabilityPredicate) {
+        public Tool(NodeWorkList nodeWorkSet, MetaAccessProvider runtime, TargetDescription target, Assumptions assumptions) {
             this.nodeWorkSet = nodeWorkSet;
             this.runtime = runtime;
             this.target = target;
             this.assumptions = assumptions;
-            this.immutabilityPredicate = immutabilityPredicate;
         }
 
         @Override
@@ -329,10 +316,5 @@
         public void addToWorkList(Node node) {
             nodeWorkSet.addAgain(node);
         }
-
-        @Override
-        public boolean isImmutable(Constant objectConstant) {
-            return immutabilityPredicate != null && immutabilityPredicate.apply(objectConstant);
-        }
     }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Fri Nov 30 08:30:22 2012 +0100
@@ -240,9 +240,9 @@
             return a;
         } else if (a == b) {
             return a;
-        } else if (a.isAssignableTo(b)) {
+        } else if (b.isAssignableFrom(a)) {
             return a;
-        } else if (b.isAssignableTo(a)) {
+        } else if (a.isAssignableFrom(b)) {
             return b;
         } else {
             return a;
@@ -326,7 +326,7 @@
             } else if (node instanceof CheckCastNode) {
                 CheckCastNode checkCast = (CheckCastNode) node;
                 ResolvedJavaType type = state.getNodeType(checkCast.object());
-                if (type != null && type.isAssignableTo(checkCast.type())) {
+                if (type != null && checkCast.type().isAssignableFrom(type)) {
                     PiNode piNode;
                     boolean nonNull = state.knownNotNull.contains(checkCast.object());
                     piNode = graph.unique(new PiNode(checkCast.object(), lastBegin, nonNull ? StampFactory.declaredNonNull(type) : StampFactory.declared(type)));
@@ -351,7 +351,7 @@
                             replaceWith = ConstantNode.forBoolean(false, graph);
                         } else if (state.knownNotNull.contains(object)) {
                             ResolvedJavaType type = state.getNodeType(object);
-                            if (type != null && type.isAssignableTo(instanceOf.type())) {
+                            if (type != null && instanceOf.type().isAssignableFrom(type)) {
                                 replaceWith = ConstantNode.forBoolean(true, graph);
                             }
                         }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Fri Nov 30 08:30:22 2012 +0100
@@ -89,7 +89,7 @@
                         Debug.dump(graph, "after %s", candidate);
                         Iterable<Node> newNodes = graph.getNewNodes(mark);
                         if (GraalOptions.OptCanonicalizer) {
-                            new CanonicalizerPhase(target, runtime, assumptions, mark, null).apply(graph);
+                            new CanonicalizerPhase(target, runtime, assumptions, mark).apply(graph);
                         }
                         metricInliningPerformed.increment();
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Fri Nov 30 08:30:22 2012 +0100
@@ -560,7 +560,7 @@
             result.setProbability(probability);
 
             Kind kind = invoke.node().kind();
-            if (!kind.isVoid()) {
+            if (kind != Kind.Void) {
                 FrameState stateAfter = invoke.stateAfter();
                 stateAfter = stateAfter.duplicate(stateAfter.bci);
                 stateAfter.replaceFirstInput(invoke.node(), result.node());
@@ -658,7 +658,7 @@
         ObjectStamp receiverStamp = callTarget.receiver().objectStamp();
         ResolvedJavaType receiverType = receiverStamp.type();
         if (receiverStamp.isExactType()) {
-            assert receiverType.isAssignableTo(targetMethod.getDeclaringClass()) : receiverType + " subtype of " + targetMethod.getDeclaringClass() + " for " + targetMethod;
+            assert targetMethod.getDeclaringClass().isAssignableFrom(receiverType) : receiverType + " subtype of " + targetMethod.getDeclaringClass() + " for " + targetMethod;
             ResolvedJavaMethod resolved = receiverType.resolveMethod(targetMethod);
             if (!checkTargetConditions(invoke, resolved, optimisticOpts, runtime)) {
                 return null;
@@ -671,7 +671,7 @@
         if (receiverStamp.type() != null) {
             // the invoke target might be more specific than the holder (happens after inlining: locals lose their declared type...)
             // TODO (lstadler) fix this
-            if (receiverType != null && receiverType.isAssignableTo(holder)) {
+            if (receiverType != null && holder.isAssignableFrom(receiverType)) {
                 holder = receiverType;
             }
         }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java	Fri Nov 30 08:30:22 2012 +0100
@@ -55,7 +55,7 @@
             if (canonicalizationRoots.isEmpty()) {
                 break;
             }
-            new CanonicalizerPhase(target, runtime, assumptions, canonicalizationRoots, null).apply(graph);
+            new CanonicalizerPhase(target, runtime, assumptions, canonicalizationRoots).apply(graph);
             canonicalizationRoots.clear();
         }
     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Fri Nov 30 08:30:22 2012 +0100
@@ -129,7 +129,7 @@
 
             processBlock(schedule.getCFG().getStartBlock(), graph.createNodeBitMap(), null, schedule, processed);
             Debug.dump(graph, "Lowering iteration %d", i++);
-            new CanonicalizerPhase(null, runtime, assumptions, mark, null).apply(graph);
+            new CanonicalizerPhase(null, runtime, assumptions, mark).apply(graph);
 
             if (!containsLowerable(graph.getNewNodes(mark))) {
                 // No new lowerable nodes - done!
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java	Fri Nov 30 08:30:22 2012 +0100
@@ -32,6 +32,8 @@
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.snippets.Snippet.DefaultSnippetInliningPolicy;
 import com.oracle.graal.snippets.Snippet.SnippetInliningPolicy;
 
 /**
@@ -114,9 +116,10 @@
 
     @Test
     public void test_fromObject() {
-        inliningPolicy.set(new SnippetInliningPolicy() {
+        inliningPolicy.set(new DefaultSnippetInliningPolicy(new BoxingMethodPool(runtime())) {
+            @Override
             public boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller) {
-                return SnippetInliningPolicy.Default.shouldInline(method, caller) && !method.getName().equals("hashCode");
+                return super.shouldInline(method, caller) && !method.getName().equals("hashCode");
             }
         });
         test("fromToObject", "object1", "object2");
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java	Fri Nov 30 08:30:22 2012 +0100
@@ -48,7 +48,7 @@
 
     /**
      * Specifies the class defining the inlining policy for this snippet.
-     * A {@linkplain SnippetInliningPolicy#Default default} policy is used if none is supplied.
+     * A {@linkplain DefaultSnippetInliningPolicy default} policy is used if none is supplied.
      */
     Class<? extends SnippetInliningPolicy> inlining() default SnippetInliningPolicy.class;
 
@@ -60,42 +60,49 @@
          * Determines if {@code method} should be inlined into {@code caller}.
          */
         boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller);
+    }
 
-        /**
-         * The default inlining policy which inlines everything except for methods
-         * in any of the following categories.
-         * <ul>
-         * <li>{@linkplain Fold foldable} methods</li>
-         * <li>{@linkplain NodeIntrinsic node intrinsics}</li>
-         * <li>native methods</li>
-         * <li>constructors of {@link Throwable} classes</li>
-         * </ul>
-         */
-        SnippetInliningPolicy Default = new SnippetInliningPolicy() {
-            public boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller) {
-                if (Modifier.isNative(method.getModifiers())) {
+    /**
+     * The default inlining policy which inlines everything except for methods
+     * in any of the following categories.
+     * <ul>
+     * <li>{@linkplain Fold foldable} methods</li>
+     * <li>{@linkplain NodeIntrinsic node intrinsics}</li>
+     * <li>native methods</li>
+     * <li>constructors of {@link Throwable} classes</li>
+     * </ul>
+     */
+    public static class DefaultSnippetInliningPolicy implements SnippetInliningPolicy {
+        private final BoxingMethodPool pool;
+
+        public DefaultSnippetInliningPolicy(BoxingMethodPool pool) {
+            this.pool = pool;
+        }
+
+        @Override
+        public boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller) {
+            if (Modifier.isNative(method.getModifiers())) {
+                return false;
+            }
+            if (method.getAnnotation(Fold.class) != null) {
+                return false;
+            }
+            if (method.getAnnotation(NodeIntrinsic.class) != null) {
+                return false;
+            }
+            if (Throwable.class.isAssignableFrom(getMirrorOrFail(method.getDeclaringClass(), null))) {
+                if (method.getName().equals("<init>")) {
                     return false;
                 }
-                if (method.getAnnotation(Fold.class) != null) {
-                    return false;
-                }
-                if (method.getAnnotation(NodeIntrinsic.class) != null) {
-                    return false;
-                }
-                if (Throwable.class.isAssignableFrom(getMirrorOrFail(method.getDeclaringClass(), null))) {
-                    if (method.getName().equals("<init>")) {
-                        return false;
-                    }
-                }
-                if (method.getAnnotation(Operation.class) != null) {
-                    return false;
-                }
-                if (BoxingMethodPool.isSpecialMethodStatic(method)) {
-                    return false;
-                }
-                return true;
+            }
+            if (method.getAnnotation(Operation.class) != null) {
+                return false;
             }
-        };
+            if (pool.isSpecialMethod(method)) {
+                return false;
+            }
+            return true;
+        }
     }
 
     /**
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Fri Nov 30 08:30:22 2012 +0100
@@ -37,6 +37,7 @@
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
+import com.oracle.graal.snippets.Snippet.DefaultSnippetInliningPolicy;
 import com.oracle.graal.snippets.Snippet.SnippetInliningPolicy;
 
 /**
@@ -122,14 +123,14 @@
         }
     }
 
-    private static SnippetInliningPolicy inliningPolicy(ResolvedJavaMethod method) {
+    private SnippetInliningPolicy inliningPolicy(ResolvedJavaMethod method) {
         Class<? extends SnippetInliningPolicy> policyClass = SnippetInliningPolicy.class;
         Snippet snippet = method.getAnnotation(Snippet.class);
         if (snippet != null) {
             policyClass = snippet.inlining();
         }
         if (policyClass == SnippetInliningPolicy.class) {
-            return SnippetInliningPolicy.Default;
+            return new DefaultSnippetInliningPolicy(pool);
         }
         try {
             return policyClass.getConstructor().newInstance();
@@ -169,7 +170,7 @@
 
                 Debug.dump(graph, "%s: %s", method.getName(), GraphBuilderPhase.class.getSimpleName());
 
-                new SnippetVerificationPhase().apply(graph);
+                new SnippetVerificationPhase(runtime).apply(graph);
 
                 new SnippetIntrinsificationPhase(runtime, pool, true).apply(graph);
 
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java	Fri Nov 30 08:30:22 2012 +0100
@@ -319,7 +319,7 @@
         try {
             ValueNode intrinsicNode = (ValueNode) constructor.newInstance(arguments);
             if (setStampFromReturnType) {
-                if (returnType.getKind().isObject()) {
+                if (returnType.getKind() == Kind.Object) {
                     intrinsicNode.setStamp(StampFactory.declared(returnType));
                 } else {
                     intrinsicNode.setStamp(StampFactory.forKind(returnType.getKind()));
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Fri Nov 30 08:30:22 2012 +0100
@@ -267,7 +267,7 @@
             new SnippetIntrinsificationPhase(runtime, new BoxingMethodPool(runtime), false).apply(snippetCopy);
             new WordTypeRewriterPhase(target.wordKind).apply(snippetCopy);
 
-            new CanonicalizerPhase(null, runtime, assumptions, 0, null).apply(snippetCopy);
+            new CanonicalizerPhase(null, runtime, assumptions, 0).apply(snippetCopy);
         }
 
         // Gather the template parameters
@@ -321,7 +321,7 @@
                     LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin);
                     int mark = snippetCopy.getMark();
                     LoopTransformations.fullUnroll(loop, runtime, null);
-                    new CanonicalizerPhase(null, runtime, assumptions, mark, null).apply(snippetCopy);
+                    new CanonicalizerPhase(null, runtime, assumptions, mark).apply(snippetCopy);
                 }
                 FixedNode explodeLoopNext = explodeLoop.next();
                 explodeLoop.clearSuccessors();
@@ -390,7 +390,7 @@
     }
 
     private static boolean checkConstantArgument(final ResolvedJavaMethod method, Signature signature, int i, String name, Object arg, Kind kind) {
-        if (kind.isObject()) {
+        if (kind == Kind.Object) {
             ResolvedJavaType type = signature.getParameterType(i, method.getDeclaringClass()).resolve(method.getDeclaringClass());
             assert arg == null || type.isInstance(Constant.forObject(arg)) :
                 method + ": wrong value type for " + name + ": expected " + type.getName() + ", got " + arg.getClass().getName();
@@ -458,7 +458,7 @@
                     replacements.put((LocalNode) parameter, (ValueNode) argument);
                 } else {
                     Kind kind = ((LocalNode) parameter).kind();
-                    assert argument != null || kind.isObject() : this + " cannot accept null for non-object parameter named " + name;
+                    assert argument != null || kind == Kind.Object : this + " cannot accept null for non-object parameter named " + name;
                     Constant constant = Constant.forBoxed(kind, argument);
                     replacements.put((LocalNode) parameter, ConstantNode.forConstant(constant, runtime, replaceeGraph));
                 }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java	Fri Nov 30 08:30:22 2012 +0100
@@ -42,8 +42,16 @@
  */
 public class SnippetVerificationPhase extends Phase {
 
+    private final MetaAccessProvider metaAccess;
+
+    public SnippetVerificationPhase(MetaAccessProvider metaAccess) {
+        this.metaAccess = metaAccess;
+    }
+
     @Override
     protected void run(StructuredGraph graph) {
+        ResolvedJavaType wordType = metaAccess.lookupJavaType(Word.class);
+
         for (ValueNode node : graph.getNodes().filter(ValueNode.class)) {
             for (Node usage : node.usages()) {
                 if (usage instanceof AccessMonitorNode) {
@@ -83,7 +91,7 @@
                             ValueNode argument = arguments.get(argc);
                             if (argument == node) {
                                 ResolvedJavaType type = (ResolvedJavaType) signature.getParameterType(i, method.getDeclaringClass());
-                                verify((type.isClass(Word.class)) == isWord(argument), node, invoke.node(), "cannot pass word value to non-word parameter " + i + " or vice-versa");
+                                verify(type.equals(wordType) == isWord(argument), node, invoke.node(), "cannot pass word value to non-word parameter " + i + " or vice-versa");
                             }
                             argc++;
                         }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java	Fri Nov 30 08:30:22 2012 +0100
@@ -99,7 +99,7 @@
                 switch (opcode) {
                     case ZERO: {
                         assert arguments.size() == 0;
-                        replace(invoke, wordKind.isLong() ? ConstantNode.forLong(0L, graph) : ConstantNode.forInt(0, graph));
+                        replace(invoke, wordKind == Kind.Long ? ConstantNode.forLong(0L, graph) : ConstantNode.forInt(0, graph));
                         break;
                     }
 
@@ -261,12 +261,12 @@
     private ValueNode asWordKind(StructuredGraph graph, ValueNode value) {
         if (value.kind() != wordKind) {
             Op op;
-            if (wordKind.isLong()) {
-                assert value.kind().isStackInt();
+            if (wordKind == Kind.Long) {
+                assert value.kind().getStackKind() == Kind.Int;
                 op = Op.I2L;
             } else {
-                assert wordKind.isStackInt();
-                assert value.kind().isLong();
+                assert wordKind.getStackKind() == Kind.Int;
+                assert value.kind() == Kind.Long;
                 op = Op.L2I;
             }
             return graph.unique(new ConvertNode(op, value));
@@ -278,10 +278,10 @@
         Kind from = value.kind();
         if (from != to) {
             Op op;
-            if (from.isLong()) {
+            if (from == Kind.Long) {
                 op = Op.L2I;
             } else {
-                assert from.isStackInt();
+                assert from.getStackKind() == Kind.Int;
                 op = Op.I2L;
             }
             return graph.unique(new ConvertNode(op, value));
@@ -296,7 +296,7 @@
         if (node instanceof LoadIndexedNode) {
             return isWord(((LoadIndexedNode) node).array().objectStamp().type().getComponentType());
         }
-        if (node.kind().isObject()) {
+        if (node.kind() == Kind.Object) {
             return isWord(node.objectStamp().type());
         }
         return false;
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanForwardNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanForwardNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -44,9 +44,9 @@
     public ValueNode canonical(CanonicalizerTool tool) {
         if (value.isConstant()) {
             long v = value.asConstant().asLong();
-            if (value.kind().isStackInt()) {
+            if (value.kind().getStackKind() == Kind.Int) {
                 return ConstantNode.forInt(Integer.numberOfTrailingZeros((int) v), graph());
-            } else if (value.kind().isLong()) {
+            } else if (value.kind() == Kind.Long) {
                 return ConstantNode.forInt(Long.numberOfTrailingZeros(v), graph());
             }
         }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanReverseNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/BitScanReverseNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -44,9 +44,9 @@
     public ValueNode canonical(CanonicalizerTool tool) {
         if (value.isConstant()) {
             long v = value.asConstant().asLong();
-            if (value.kind().isStackInt()) {
+            if (value.kind().getStackKind() == Kind.Int) {
                 return ConstantNode.forInt(31 - Integer.numberOfLeadingZeros((int) v), graph());
-            } else if (value.kind().isLong()) {
+            } else if (value.kind() == Kind.Long) {
                 return ConstantNode.forInt(63 - Long.numberOfLeadingZeros(v), graph());
             }
         }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/ReverseBytesNode.java	Thu Nov 29 17:19:13 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/ReverseBytesNode.java	Fri Nov 30 08:30:22 2012 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.snippets.nodes;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.lir.*;
@@ -36,7 +37,7 @@
 
     public ReverseBytesNode(ValueNode value) {
         super(StampFactory.forKind(value.kind()));
-        assert kind().isStackInt() || kind().isLong();
+        assert kind().getStackKind() == Kind.Int || kind() == Kind.Long;
         this.value = value;
     }
 
@@ -44,9 +45,9 @@
     public ValueNode canonical(CanonicalizerTool tool) {
         if (value.isConstant()) {
             long v = value.asConstant().asLong();
-            if (kind().isStackInt()) {
+            if (kind().getStackKind() == Kind.Int) {
                 return ConstantNode.forInt(Integer.reverseBytes((int) v), graph());
-            } else if (kind().isLong()) {
+            } else if (kind() == Kind.Long) {
                 return ConstantNode.forLong(Long.reverseBytes(v), graph());
             }
         }
--- a/src/share/vm/code/dependencies.cpp	Thu Nov 29 17:19:13 2012 +0100
+++ b/src/share/vm/code/dependencies.cpp	Fri Nov 30 08:30:22 2012 +0100
@@ -50,6 +50,9 @@
   _oop_recorder = env->oop_recorder();
   _log = env->log();
   _dep_seen = new(arena) GrowableArray<int>(arena, 500, 0, 0);
+#ifdef GRAAL
+  _using_dep_values = false;
+#endif // GRAAL
   DEBUG_ONLY(_deps[end_marker] = NULL);
   for (int i = (int)FIRST_TYPE; i < (int)TYPE_LIMIT; i++) {
     _deps[i] = new(arena) GrowableArray<ciBaseObject*>(arena, 10, 0, 0);
@@ -119,6 +122,56 @@
   assert_common_2(call_site_target_value, call_site, method_handle);
 }
 
+#ifdef GRAAL
+
+Dependencies::Dependencies(Arena* arena, OopRecorder* oop_recorder) {
+  _oop_recorder = oop_recorder;
+  _log = NULL;
+  _dep_seen = new(arena) GrowableArray<int>(arena, 500, 0, 0);
+  _using_dep_values = true;
+  DEBUG_ONLY(_dep_values[end_marker] = NULL);
+  for (int i = (int)FIRST_TYPE; i < (int)TYPE_LIMIT; i++) {
+    _dep_values[i] = new(arena) GrowableArray<DepValue>(arena, 10, 0, DepValue());
+  }
+  _content_bytes = NULL;
+  _size_in_bytes = (size_t)-1;
+
+  assert(TYPE_LIMIT <= (1<<LG2_TYPE_LIMIT), "sanity");
+}
+
+void Dependencies::assert_evol_method(Method* m) {
+  assert_common_1(evol_method, DepValue(_oop_recorder, m));
+}
+
+void Dependencies::assert_leaf_type(Klass* ctxk) {
+  if (ctxk->oop_is_array()) {
+    // As a special case, support this assertion on an array type,
+    // which reduces to an assertion on its element type.
+    // Note that this cannot be done with assertions that
+    // relate to concreteness or abstractness.
+    BasicType elemt = ArrayKlass::cast(ctxk)->element_type();
+    if (is_java_primitive(elemt))  return;   // Ex:  int[][]
+    ctxk = ObjArrayKlass::cast(ctxk)->bottom_klass();
+    //if (ctxk->is_final())  return;            // Ex:  String[][]
+  }
+  check_ctxk(ctxk);
+  assert_common_1(leaf_type, DepValue(_oop_recorder, ctxk));
+}
+
+void Dependencies::assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck) {
+  check_ctxk_abstract(ctxk);
+  DepValue ctxk_dv(_oop_recorder, ctxk);
+  DepValue conck_dv(_oop_recorder, conck, &ctxk_dv);
+  assert_common_2(abstract_with_unique_concrete_subtype, ctxk_dv, conck_dv);
+}
+
+void Dependencies::assert_unique_concrete_method(Klass* ctxk, Method* uniqm) {
+  check_ctxk(ctxk);
+  assert_common_2(unique_concrete_method, DepValue(_oop_recorder, ctxk), DepValue(_oop_recorder, uniqm));
+}
+#endif // GRAAL
+
+
 // Helper function.  If we are adding a new dep. under ctxk2,
 // try to find an old dep. under a broader* ctxk1.  If there is
 //
@@ -230,6 +283,78 @@
   deps->append(x2);
 }
 
+#ifdef GRAAL
+bool Dependencies::maybe_merge_ctxk(GrowableArray<DepValue>* deps,
+                                    int ctxk_i, DepValue ctxk2_dv) {
+  Klass* ctxk1 = deps->at(ctxk_i).as_klass(_oop_recorder);
+  Klass* ctxk2 = ctxk2_dv.as_klass(_oop_recorder);
+  if (ctxk2->is_subtype_of(ctxk1)) {
+    return true;  // success, and no need to change
+  } else if (ctxk1->is_subtype_of(ctxk2)) {
+    // new context class fully subsumes previous one
+    deps->at_put(ctxk_i, ctxk2_dv);
+    return true;
+  } else {
+    return false;
+  }
+}
+
+void Dependencies::assert_common_1(DepType dept, DepValue x) {
+  assert(dep_args(dept) == 1, "sanity");
+  //log_dependency(dept, x);
+  GrowableArray<DepValue>* deps = _dep_values[dept];
+
+  // see if the same (or a similar) dep is already recorded
+  if (note_dep_seen(dept, x)) {
+    assert(deps->find(x) >= 0, "sanity");
+  } else {
+    deps->append(x);
+  }
+}
+
+void Dependencies::assert_common_2(DepType dept,
+                                   DepValue x0, DepValue x1) {
+  assert(dep_args(dept) == 2, "sanity");
+  //log_dependency(dept, x0, x1);
+  GrowableArray<DepValue>* deps = _dep_values[dept];
+
+  // see if the same (or a similar) dep is already recorded
+  bool has_ctxk = has_explicit_context_arg(dept);
+  if (has_ctxk) {
+    assert(dep_context_arg(dept) == 0, "sanity");
+    if (note_dep_seen(dept, x1)) {
+      // look in this bucket for redundant assertions
+      const int stride = 2;
+      for (int i = deps->length(); (i -= stride) >= 0; ) {
+        DepValue y1 = deps->at(i+1);
+        if (x1 == y1) {  // same subject; check the context
+          if (maybe_merge_ctxk(deps, i+0, x0)) {
+            return;
+          }
+        }
+      }
+    }
+  } else {
+    assert(dep_implicit_context_arg(dept) == 0, "sanity");
+    if (note_dep_seen(dept, x0) && note_dep_seen(dept, x1)) {
+      // look in this bucket for redundant assertions
+      const int stride = 2;
+      for (int i = deps->length(); (i -= stride) >= 0; ) {
+        DepValue y0 = deps->at(i+0);
+        DepValue y1 = deps->at(i+1);
+        if (x0 == y0 && x1 == y1) {
+          return;
+        }
+      }
+    }
+  }
+
+  // append the assertion in the correct bucket:
+  deps->append(x0);
+  deps->append(x1);
+}
+#endif // GRAAL
+
 /// Support for encoding dependencies into an nmethod:
 
 void Dependencies::copy_to(nmethod* nm) {
@@ -256,7 +381,40 @@
 static int sort_dep_arg_3(ciBaseObject** p1, ciBaseObject** p2)
 { return sort_dep(p1, p2, 3); }
 
+#ifdef GRAAL
+// metadata deps are sorted before object deps
+static int sort_dep_value(Dependencies::DepValue* p1, Dependencies::DepValue* p2, int narg) {
+  for (int i = 0; i < narg; i++) {
+    int diff = p1[i].sort_key() - p2[i].sort_key();
+    if (diff != 0)  return diff;
+  }
+  return 0;
+}
+static int sort_dep_value_arg_1(Dependencies::DepValue* p1, Dependencies::DepValue* p2)
+{ return sort_dep_value(p1, p2, 1); }
+static int sort_dep_value_arg_2(Dependencies::DepValue* p1, Dependencies::DepValue* p2)
+{ return sort_dep_value(p1, p2, 2); }
+static int sort_dep_value_arg_3(Dependencies::DepValue* p1, Dependencies::DepValue* p2)
+{ return sort_dep_value(p1, p2, 3); }
+#endif // GRAAL
+
 void Dependencies::sort_all_deps() {
+#ifdef GRAAL
+  if (_using_dep_values) {
+    for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
+      DepType dept = (DepType)deptv;
+      GrowableArray<DepValue>* deps = _dep_values[dept];
+      if (deps->length() <= 1)  continue;
+      switch (dep_args(dept)) {
+      case 1: deps->sort(sort_dep_value_arg_1, 1); break;
+      case 2: deps->sort(sort_dep_value_arg_2, 2); break;
+      case 3: deps->sort(sort_dep_value_arg_3, 3); break;
+      default: ShouldNotReachHere();
+      }
+    }
+    return;
+  }
+#endif // GRAAL
   for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
     DepType dept = (DepType)deptv;
     GrowableArray<ciBaseObject*>* deps = _deps[dept];
@@ -272,6 +430,16 @@
 
 size_t Dependencies::estimate_size_in_bytes() {
   size_t est_size = 100;
+#ifdef GRAAL
+  if (_using_dep_values) {
+    for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
+      DepType dept = (DepType)deptv;
+      GrowableArray<DepValue>* deps = _dep_values[dept];
+      est_size += deps->length() * 2;  // tags and argument(s)
+    }
+    return est_size;
+  }
+#endif // GRAAL
   for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
     DepType dept = (DepType)deptv;
     GrowableArray<ciBaseObject*>* deps = _deps[dept];
@@ -311,6 +479,37 @@
   // cast is safe, no deps can overflow INT_MAX
   CompressedWriteStream bytes((int)estimate_size_in_bytes());
 
+#ifdef GRAAL
+  if (_using_dep_values) {
+    for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
+      DepType dept = (DepType)deptv;
+      GrowableArray<DepValue>* deps = _dep_values[dept];
+      if (deps->length() == 0)  continue;
+      int stride = dep_args(dept);
+      int ctxkj  = dep_context_arg(dept);  // -1 if no context arg
+      assert(stride > 0, "sanity");
+      for (int i = 0; i < deps->length(); i += stride) {
+        jbyte code_byte = (jbyte)dept;
+        int skipj = -1;
+        if (ctxkj >= 0 && ctxkj+1 < stride) {
+          Klass*  ctxk = deps->at(i+ctxkj+0).as_klass(_oop_recorder);
+          DepValue x = deps->at(i+ctxkj+1);  // following argument
+          if (ctxk == ctxk_encoded_as_null(dept, x.as_metadata(_oop_recorder))) {
+            skipj = ctxkj;  // we win:  maybe one less oop to keep track of
+            code_byte |= default_context_type_bit;
+          }
+        }
+        bytes.write_byte(code_byte);
+        for (int j = 0; j < stride; j++) {
+          if (j == skipj)  continue;
+          DepValue v = deps->at(i+j);
+          int idx = v.index();
+          bytes.write_int(idx);
+        }
+      }
+    }
+  } else {
+#endif // GRAAL
   for (int deptv = (int)FIRST_TYPE; deptv < (int)TYPE_LIMIT; deptv++) {
     DepType dept = (DepType)deptv;
     GrowableArray<ciBaseObject*>* deps = _deps[dept];
@@ -344,6 +543,9 @@
       }
     }
   }
+#ifdef GRAAL
+  }
+#endif // GRAAL
 
   // write a sentinel byte to mark the end
   bytes.write_byte(end_marker);
@@ -360,7 +562,6 @@
   _size_in_bytes = bytes.position();
 }
 
-
 const char* Dependencies::_dep_name[TYPE_LIMIT] = {
   "end_marker",
   "evol_method",
--- a/src/share/vm/code/dependencies.hpp	Thu Nov 29 17:19:13 2012 +0100
+++ b/src/share/vm/code/dependencies.hpp	Fri Nov 30 08:30:22 2012 +0100
@@ -200,10 +200,59 @@
 
   static void check_valid_dependency_type(DepType dept);
 
+#ifdef GRAAL
+  // A Metadata* or object value recorded in an OopRecorder
+  class DepValue VALUE_OBJ_CLASS_SPEC {
+   private:
+    // Unique identifier of the value within the associated OopRecorder that
+    // encodes both the category of the value (0: invalid, positive: metadata, negative: object)
+    // and the index within a category specific array (metadata: index + 1, object: -(index + 1))
+    int _id;
+
+   public:
+    DepValue() : _id(0) {}
+    DepValue(OopRecorder* rec, Metadata* metadata, DepValue* candidate = NULL) {
+      assert(candidate == NULL || candidate->is_metadata(), "oops");
+      if (candidate != NULL && candidate->as_metadata(rec) == metadata) {
+        _id = candidate->_id;
+      } else {
+        _id = rec->find_index(metadata) + 1;
+      }
+    }
+    DepValue(OopRecorder* rec, jobject obj, DepValue* candidate = NULL) {
+      assert(candidate == NULL || candidate->is_object(), "oops");
+      if (candidate != NULL && candidate->as_object(rec) == obj) {
+        _id = candidate->_id;
+      } else {
+        _id = -(rec->find_index(obj) + 1);
+      }
+    }
+
+    // Used to sort values in ascending order of index() with metadata values preceding object values
+    int sort_key() const { return -_id; }
+
+    bool operator == (const DepValue& other) const   { return other._id == _id; }
+
+    bool is_valid() const             { return _id != 0; }
+    int  index() const                { assert(is_valid(), "oops"); return _id < 0 ? -(_id + 1) : _id - 1; }
+    bool is_metadata() const          { assert(is_valid(), "oops"); return _id > 0; }
+    bool is_object() const            { assert(is_valid(), "oops"); return _id < 0; }
+
+    Metadata*  as_metadata(OopRecorder* rec) const    { assert(is_metadata(), "oops"); return rec->metadata_at(index()); }
+    Klass*     as_klass(OopRecorder* rec) const       { assert(as_metadata(rec)->is_klass(), "oops"); return (Klass*) as_metadata(rec); }
+    Method*    as_method(OopRecorder* rec) const      { assert(as_metadata(rec)->is_method(), "oops"); return (Method*) as_metadata(rec); }
+    jobject    as_object(OopRecorder* rec) const      { assert(is_object(), "oops"); return rec->oop_at(index()); }
+  };
+#endif
+
  private:
   // State for writing a new set of dependencies:
   GrowableArray<int>*       _dep_seen;  // (seen[h->ident] & (1<<dept))
   GrowableArray<ciBaseObject*>*  _deps[TYPE_LIMIT];
+#ifdef GRAAL
+  bool _using_dep_values;
+  GrowableArray<DepValue>*  _dep_values[TYPE_LIMIT];
+#endif
 
   static const char* _dep_name[TYPE_LIMIT];
   static int         _dep_args[TYPE_LIMIT];
@@ -222,8 +271,25 @@
     return (seen & (1<<dept)) != 0;
   }
 
+#ifdef GRAAL
+  bool note_dep_seen(int dept, DepValue x) {
+    assert(dept < BitsPerInt, "oops");
+    // place metadata deps at even indexes, object deps at odd indexes
+    int x_id = x.is_metadata() ? x.index() * 2 : (x.index() * 2) + 1;
+    assert(_dep_seen != NULL, "deps must be writable");
+    int seen = _dep_seen->at_grow(x_id, 0);
+    _dep_seen->at_put(x_id, seen | (1<<dept));
+    // return true if we've already seen dept/x
+    return (seen & (1<<dept)) != 0;
+  }
+#endif
+
   bool maybe_merge_ctxk(GrowableArray<ciBaseObject*>* deps,
                         int ctxk_i, ciKlass* ctxk);
+#ifdef GRAAL
+  bool maybe_merge_ctxk(GrowableArray<DepValue>* deps,
+                        int ctxk_i, DepValue ctxk);
+#endif
 
   void sort_all_deps();
   size_t estimate_size_in_bytes();
@@ -245,6 +311,9 @@
   Dependencies(ciEnv* env) {
     initialize(env);
   }
+#ifdef GRAAL
+  Dependencies(Arena* arena, OopRecorder* oop_recorder);
+#endif // GRAAL
 
  private:
   // Check for a valid context type.
@@ -277,6 +346,25 @@
   void assert_has_no_finalizable_subclasses(ciKlass* ctxk);
   void assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle);
 
+#ifdef GRAAL
+ private:
+  static void check_ctxk(Klass* ctxk) {
+    assert(ctxk->oop_is_instance(), "java types only");
+  }
+  static void check_ctxk_abstract(Klass* ctxk) {
+    check_ctxk(ctxk);
+    assert(ctxk->is_abstract(), "must be abstract");
+  }
+  void assert_common_1(DepType dept, DepValue x);
+  void assert_common_2(DepType dept, DepValue x0, DepValue x1);
+
+ public:
+  void assert_evol_method(Method* m);
+  void assert_leaf_type(Klass* ctxk);
+  void assert_unique_concrete_method(Klass* ctxk, Method* uniqm);
+  void assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck);
+#endif // GRAAL
+
   // Define whether a given method or type is concrete.
   // These methods define the term "concrete" as used in this module.
   // For this module, an "abstract" class is one which is non-concrete.
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Thu Nov 29 17:19:13 2012 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Fri Nov 30 08:30:22 2012 +0100
@@ -264,10 +264,8 @@
 }
 
 void CodeInstaller::initialize_assumptions(oop target_method) {
-  _oop_recorder = new OopRecorder(_env->arena());
-  _env->set_oop_recorder(_oop_recorder);
-  _env->set_dependencies(_dependencies);
-  _dependencies = new Dependencies(_env);
+  _oop_recorder = new OopRecorder(&_arena);
+  _dependencies = new Dependencies(&_arena, _oop_recorder);
   Handle assumptions_handle = CompilationResult::assumptions(HotSpotCompilationResult::comp(target_method));
   if (!assumptions_handle.is_null()) {
     objArrayHandle assumptions(Thread::current(), (objArrayOop)Assumptions::list(assumptions_handle()));
@@ -292,7 +290,6 @@
 
 // constructor used to create a method
 CodeInstaller::CodeInstaller(Handle& comp_result, methodHandle method, GraalEnv::CodeInstallResult& result, nmethod*& nm, Handle installed_code) {
-  _env = CURRENT_ENV;
   GraalCompiler::initialize_buffer_blob();
   CodeBuffer buffer(JavaThread::current()->get_buffer_blob());
   jobject comp_result_obj = JNIHandles::make_local(comp_result());
@@ -317,10 +314,8 @@
 // constructor used to create a stub
 CodeInstaller::CodeInstaller(Handle& target_method, BufferBlob*& blob, jlong& id) {
   No_Safepoint_Verifier no_safepoint;
-  _env = CURRENT_ENV;
   
-  _oop_recorder = new OopRecorder(_env->arena());
-  _env->set_oop_recorder(_oop_recorder);
+  _oop_recorder = new OopRecorder(&_arena);
   initialize_fields(target_method(), NULL);
   assert(_name != NULL, "installMethod needs NON-NULL name");
 
@@ -366,10 +361,9 @@
   buffer.initialize_stubs_size(256);
   buffer.initialize_consts_size(_constants_size);
 
-  _debug_recorder = new DebugInformationRecorder(_env->oop_recorder());
+  _debug_recorder = new DebugInformationRecorder(_oop_recorder);
   _debug_recorder->set_oopmaps(new OopMapSet());
   
-  _env->set_debug_info(_debug_recorder);
   buffer.initialize_oop_recorder(_oop_recorder);
 
   _instructions = buffer.insts();
@@ -405,33 +399,30 @@
 void CodeInstaller::assumption_MethodContents(Handle assumption) {
   Handle method_handle = Assumptions_MethodContents::method(assumption());
   methodHandle method = getMethodFromHotSpotMethod(method_handle());
-  ciMethod* m = (ciMethod*) CURRENT_ENV->get_method(method());
-
-  _dependencies->assert_evol_method(m);
+  _dependencies->assert_evol_method(method());
 }
 
 void CodeInstaller::assumption_ConcreteSubtype(Handle assumption) {
   Handle context_handle = Assumptions_ConcreteSubtype::context(assumption());
-  ciKlass* context = (ciKlass*) CURRENT_ENV->get_klass(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(context_handle)));
-
-  Handle type_handle = Assumptions_ConcreteSubtype::subtype(assumption());
-  ciKlass* type = (ciKlass*) CURRENT_ENV->get_klass(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(type_handle)));
+  Handle subtype_handle = Assumptions_ConcreteSubtype::subtype(assumption());
+  Klass* context = asKlass(HotSpotResolvedObjectType::metaspaceKlass(context_handle));
+  Klass* subtype = asKlass(HotSpotResolvedObjectType::metaspaceKlass(subtype_handle));
 
-  _dependencies->assert_leaf_type(type);
-  if (context != type) {
+  _dependencies->assert_leaf_type(subtype);
+  if (context != subtype) {
     assert(context->is_abstract(), "");
-    _dependencies->assert_abstract_with_unique_concrete_subtype(context, type);
+    _dependencies->assert_abstract_with_unique_concrete_subtype(context, subtype);
   }
 }
 
 void CodeInstaller::assumption_ConcreteMethod(Handle assumption) {
   Handle impl_handle = Assumptions_ConcreteMethod::impl(assumption());
+  Handle context_handle = Assumptions_ConcreteMethod::context(assumption());
+
   methodHandle impl = getMethodFromHotSpotMethod(impl_handle());
-  ciMethod* m = (ciMethod*) CURRENT_ENV->get_method(impl());
-  
-  Handle context_handle = Assumptions_ConcreteMethod::context(assumption());
-  ciKlass* context = (ciKlass*) CURRENT_ENV->get_klass(java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(context_handle)));
-  _dependencies->assert_unique_concrete_method(context, m);
+  Klass* context = asKlass(HotSpotResolvedObjectType::metaspaceKlass(context_handle));
+
+  _dependencies->assert_unique_concrete_method(context, impl());
 }
 
 void CodeInstaller::process_exception_handlers() {
--- a/src/share/vm/graal/graalCodeInstaller.hpp	Thu Nov 29 17:19:13 2012 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.hpp	Fri Nov 30 08:30:22 2012 +0100
@@ -54,7 +54,7 @@
     MARK_ACCESS_FIELD_PATCHING      = 0x4002
   };
 
-  ciEnv*        _env;
+  Arena         _arena;
 
   oop           _comp_result;
   oop           _name;
--- a/src/share/vm/graal/graalCompiler.cpp	Thu Nov 29 17:19:13 2012 +0100
+++ b/src/share/vm/graal/graalCompiler.cpp	Fri Nov 30 08:30:22 2012 +0100
@@ -161,13 +161,11 @@
 
   assert(_initialized, "must already be initialized");
   ResourceMark rm;
-  ciEnv* current_env = JavaThread::current()->env();
-  JavaThread::current()->set_env(NULL);
+  assert(JavaThread::current()->env() == NULL, "ciEnv should be null");
   JavaThread::current()->set_compiling(true);
   Handle holder = GraalCompiler::createHotSpotResolvedObjectType(method, CHECK);
   jboolean success = VMToCompiler::compileMethod(method(), holder, entry_bci, blocking, method->graal_priority());
   JavaThread::current()->set_compiling(false);
-  JavaThread::current()->set_env(current_env);
   if (success != JNI_TRUE) {
     method->clear_queued_for_compilation();
     CompilationPolicy::policy()->delay_compilation(method());
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Thu Nov 29 17:19:13 2012 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Fri Nov 30 08:30:22 2012 +0100
@@ -28,7 +28,6 @@
 #include "oops/fieldStreams.hpp"
 #include "runtime/javaCalls.hpp"
 #include "c1/c1_Runtime1.hpp"
-#include "ci/ciMethodData.hpp"
 #include "compiler/compileBroker.hpp"
 #include "compiler/compilerOracle.hpp"
 #include "graal/graalCompilerToVM.hpp"
@@ -741,8 +740,6 @@
   Handle compResultHandle = JNIHandles::resolve(compResult);
   nmethod* nm = NULL;
   methodHandle method = getMethodFromHotSpotMethod(HotSpotCompilationResult::method(compResult));
-  Arena arena;
-  ciEnv env(&arena);
   Handle installed_code_handle = JNIHandles::resolve(installed_code);
   GraalEnv::CodeInstallResult result;
   CodeInstaller installer(compResultHandle, method, result, nm, installed_code_handle);
--- a/src/share/vm/graal/graalEnv.cpp	Thu Nov 29 17:19:13 2012 +0100
+++ b/src/share/vm/graal/graalEnv.cpp	Fri Nov 30 08:30:22 2012 +0100
@@ -45,8 +45,6 @@
 #include "c1/c1_Runtime1.hpp"
 
 // ------------------------------------------------------------------
-// ciEnv::check_klass_accessiblity
-//
 // Note: the logic of this method should mirror the logic of
 // constantPoolOopDesc::verify_constant_pool_resolve.
 bool GraalEnv::check_klass_accessibility(KlassHandle accessing_klass, KlassHandle resolved_klass) {
@@ -68,7 +66,6 @@
 }
 
 // ------------------------------------------------------------------
-// ciEnv::get_klass_by_name_impl
 KlassHandle GraalEnv::get_klass_by_name_impl(KlassHandle& accessing_klass,
                                           constantPoolHandle& cpool,
                                           Symbol* sym,
@@ -120,7 +117,7 @@
                                                  sym->utf8_length()-1,
                                                  CHECK_(KlassHandle()));
 
-    // Get element ciKlass recursively.
+    // Get element Klass recursively.
     KlassHandle elem_klass =
       get_klass_by_name_impl(accessing_klass,
                              cpool,
@@ -148,7 +145,6 @@
 }
 
 // ------------------------------------------------------------------
-// ciEnv::get_klass_by_name
 KlassHandle GraalEnv::get_klass_by_name(KlassHandle& accessing_klass,
                                   Symbol* klass_name,
                                   bool require_local) {
@@ -161,8 +157,6 @@
 }
 
 // ------------------------------------------------------------------
-// ciEnv::get_klass_by_index_impl
-//
 // Implementation of get_klass_by_index.
 KlassHandle GraalEnv::get_klass_by_index_impl(constantPoolHandle& cpool,
                                         int index,
@@ -222,8 +216,6 @@
 }
 
 // ------------------------------------------------------------------
-// ciEnv::get_klass_by_index
-//
 // Get a klass from the constant pool.
 KlassHandle GraalEnv::get_klass_by_index(constantPoolHandle& cpool,
                                    int index,
@@ -235,8 +227,6 @@
 }
 
 // ------------------------------------------------------------------
-// ciEnv::get_field_by_index_impl
-//
 // Implementation of get_field_by_index.
 //
 // Implementation note: the results of field lookups are cached
@@ -257,9 +247,6 @@
   Symbol* signature = cpool->symbol_at(sig_index);
 
   // Get the field's declared holder.
-  //
-  // Note: we actually create a ciInstanceKlass for this klass,
-  // even though we may not need to.
   int holder_index = cpool->klass_ref_index_at(index);
   bool holder_is_accessible;
   KlassHandle declared_holder = get_klass_by_index(cpool, holder_index,
@@ -284,8 +271,6 @@
 }
 
 // ------------------------------------------------------------------
-// ciEnv::get_field_by_index
-//
 // Get a field by index from a klass's constant pool.
 void GraalEnv::get_field_by_index(instanceKlassHandle& accessor, fieldDescriptor& fd, int index) {
   ResourceMark rm;
@@ -293,8 +278,6 @@
 }
 
 // ------------------------------------------------------------------
-// ciEnv::lookup_method
-//
 // Perform an appropriate method lookup based on accessor, holder,
 // name, signature, and bytecode.
 methodHandle GraalEnv::lookup_method(instanceKlassHandle& h_accessor,
@@ -332,7 +315,6 @@
 
 
 // ------------------------------------------------------------------
-// ciEnv::get_method_by_index_impl
 methodHandle GraalEnv::get_method_by_index_impl(constantPoolHandle& cpool,
                                           int index, Bytecodes::Code bc,
                                           instanceKlassHandle& accessor) {
@@ -360,23 +342,16 @@
   }
 
   // Either the declared holder was not loaded, or the method could
-  // not be found.  Create a dummy ciMethod to represent the failed
-  // lookup.
+  // not be found.
 
   return NULL;
 }
 
 // ------------------------------------------------------------------
-// ciEnv::get_instance_klass_for_declared_method_holder
 instanceKlassHandle GraalEnv::get_instance_klass_for_declared_method_holder(KlassHandle& method_holder) {
-  // For the case of <array>.clone(), the method holder can be a ciArrayKlass
-  // instead of a ciInstanceKlass.  For that case simply pretend that the
+  // For the case of <array>.clone(), the method holder can be an ArrayKlass*
+  // instead of an InstanceKlass*.  For that case simply pretend that the
   // declared holder is Object.clone since that's where the call will bottom out.
-  // A more correct fix would trickle out through many interfaces in CI,
-  // requiring ciInstanceKlass* to become ciKlass* and many more places would
-  // require checks to make sure the expected type was found.  Given that this
-  // only occurs for clone() the more extensive fix seems like overkill so
-  // instead we simply smear the array type into Object.
   if (method_holder->oop_is_instance()) {
     return instanceKlassHandle(method_holder());
   } else if (method_holder->oop_is_array()) {
@@ -389,7 +364,6 @@
 
 
 // ------------------------------------------------------------------
-// ciEnv::get_method_by_index
 methodHandle GraalEnv::get_method_by_index(constantPoolHandle& cpool,
                                      int index, Bytecodes::Code bc,
                                      instanceKlassHandle& accessor) {
@@ -399,7 +373,6 @@
 }
 
 // ------------------------------------------------------------------
-// ciEnv::check_for_system_dictionary_modification
 // Check for changes to the system dictionary during compilation
 // class loads, evolution, breakpoints
 bool GraalEnv::check_for_system_dictionary_modification(Dependencies* dependencies) {
@@ -427,7 +400,6 @@
 }
 
 // ------------------------------------------------------------------
-// ciEnv::register_method
 GraalEnv::CodeInstallResult GraalEnv::register_method(
                                 methodHandle& method,
                                 nmethod*& nm,
--- a/src/share/vm/graal/graalEnv.hpp	Thu Nov 29 17:19:13 2012 +0100
+++ b/src/share/vm/graal/graalEnv.hpp	Fri Nov 30 08:30:22 2012 +0100
@@ -34,7 +34,6 @@
 
 class CompileTask;
 
-// ciEnv
 //
 // This class is the top level broker for requests from the compiler
 // to the VM.
@@ -136,12 +135,8 @@
                        bool                      has_unsafe_access,
                        Handle                    installed_code);
 
-  static ciKlass*  find_system_klass(ciSymbol* klass_name);
-  // Note:  To find a class from its name string, use ciSymbol::make,
-  // but consider adding to vmSymbols.hpp instead.
-
-  // converts the ciKlass* representing the holder of a method into a
-  // ciInstanceKlass*.  This is needed since the holder of a method in
+  // converts the Klass* representing the holder of a method into a
+  // InstanceKlass*.  This is needed since the holder of a method in
   // the bytecodes could be an array type.  Basically this converts
   // array types into java/lang/Object and other types stay as they are.
   static instanceKlassHandle get_instance_klass_for_declared_method_holder(KlassHandle& klass);
--- a/src/share/vm/prims/jni.cpp	Thu Nov 29 17:19:13 2012 +0100
+++ b/src/share/vm/prims/jni.cpp	Fri Nov 30 08:30:22 2012 +0100
@@ -5152,9 +5152,8 @@
     *(JNIEnv**)penv = thread->jni_environment();
 
 #ifdef GRAAL
-      GraalCompiler* compiler = GraalCompiler::instance();
-      ciObjectFactory::initialize(); 
-      compiler->initialize();
+    GraalCompiler* compiler = GraalCompiler::instance();
+    compiler->initialize();
 #endif
 
     // Tracks the time application was running before GC