changeset 6950:41938af2b3d8

modifications to support non-perm-gen changes in HotSpot fixed issue when intrinsifying Class.getModifiers() for primitive classes
author Doug Simon <doug.simon@oracle.com>
date Wed, 14 Nov 2012 11:28:02 +0100
parents d09b0fed89db
children e54fcd0405f6
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/FieldIntrospection.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DirectCallOp.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerObject.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotKlassOop.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeInterpreterInterface.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCompiledMethod.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotJavaType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypeUnresolved.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CastFromHub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotIndirectCallTargetNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/InstanceOfSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/BytecodeInterpreter.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_getModifiers01.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MaterializeNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/WordStamp.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/InstanceOfSnippetsTemplates.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetCounter.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java src/share/vm/classfile/systemDictionary.hpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalCompiler.cpp src/share/vm/graal/graalCompilerToVM.cpp src/share/vm/graal/graalJavaAccess.hpp src/share/vm/oops/instanceKlass.cpp src/share/vm/oops/method.cpp src/share/vm/oops/method.hpp src/share/vm/runtime/reflectionUtils.cpp
diffstat 76 files changed, 1284 insertions(+), 906 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java	Wed Nov 14 11:28:02 2012 +0100
@@ -104,7 +104,16 @@
         }
     }
 
+    /**
+     * Determines if a given type can have subtypes. This analysis is purely static; no
+     * assumptions are made.
+     *
+     * @return true if {@code type} has no subtype(s)
+     */
     public static boolean isFinalClass(ResolvedJavaType type) {
-        return Modifier.isFinal(type.getModifiers()) || (type.isArrayClass() && Modifier.isFinal(type.getComponentType().getModifiers()));
+        if (type.isArrayClass()) {
+            return isFinalClass(type.getComponentType());
+        }
+        return Modifier.isFinal(type.getModifiers());
     }
 }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java	Wed Nov 14 11:28:02 2012 +0100
@@ -22,37 +22,40 @@
  */
 package com.oracle.graal.api.code;
 
+import java.util.*;
+
 import com.oracle.graal.api.meta.*;
 
 /**
- * An instance of this class represents an object whose allocation was removed by escape analysis. The information stored in the {@link VirtualObject} is used during
- * deoptimization to recreate the object.
+ * An instance of this class represents an object whose allocation was removed by escape analysis.
+ * The information stored in the {@link VirtualObject} is used during deoptimization to recreate the object.
  */
 public final class VirtualObject extends Value {
     private static final long serialVersionUID = -2907197776426346021L;
 
-    private final JavaType type;
+    private final ResolvedJavaType type;
     private Value[] values;
     private final int id;
 
     /**
-     * Creates a new {@link VirtualObject} for the given type, with the given fields. If the type is an instance class
-     * then the values array needs to have one entry for each field, ordered in like the fields returned by
-     * {@link ResolvedJavaType#getDeclaredFields()}. If the type is an array then the length of the values array determines
+     * Creates a new {@link VirtualObject} for the given type, with the given fields.
+     * If {@code type} is an instance class then {@code values} provides the values for the fields
+     * returned by {@link ResolvedJavaType#getInstanceFields(boolean) getInstanceFields(true)}.
+     * If {@code type} is an array then the length of the values array determines
      * the reallocated array length.
      *
      * @param type the type of the object whose allocation was removed during compilation. This can be either an
      *            instance of an array type.
-     * @param values an array containing all the values to be stored into the object when it is recreated.
+     * @param values an array containing all the values to be stored into the object when it is recreated
      * @param id a unique id that identifies the object within the debug information for one position in the compiled
      *            code.
      * @return a new {@link VirtualObject} instance.
      */
-    public static VirtualObject get(JavaType type, Value[] values, int id) {
+    public static VirtualObject get(ResolvedJavaType type, Value[] values, int id) {
         return new VirtualObject(type, values, id);
     }
 
-    private VirtualObject(JavaType type, Value[] values, int id) {
+    private VirtualObject(ResolvedJavaType type, Value[] values, int id) {
         super(Kind.Object);
         this.type = type;
         this.values = values;
@@ -61,7 +64,29 @@
 
     @Override
     public String toString() {
-        return "vobject:" + id;
+        StringBuilder buf = new StringBuilder("vobject:").append(MetaUtil.toJavaName(type, false)).append(':').append(id).append('{');
+        if (values == null) {
+            buf.append("<uninitialized>");
+        } else {
+            if (type.isArrayClass()) {
+                for (int i = 0; i < values.length; i++) {
+                    if (i != 0) {
+                        buf.append(',');
+                    }
+                    buf.append(i).append('=').append(values[i]);
+                }
+            } else {
+                ResolvedJavaField[] fields = type.getInstanceFields(true);
+                assert fields.length == values.length : type + ", fields=" + Arrays.toString(fields) + ", values=" + values;
+                for (int i = 0; i < values.length; i++) {
+                    if (i != 0) {
+                        buf.append(',');
+                    }
+                    buf.append(fields[i].getName()).append('=').append(values[i]);
+                }
+            }
+        }
+        return buf.append('}').toString();
     }
 
     /**
@@ -87,6 +112,7 @@
 
     /**
      * Overwrites the current set of values with a new one.
+     *
      * @param values an array containing all the values to be stored into the object when it is recreated.
      */
     public void setValues(Value[] values) {
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Wed Nov 14 11:28:02 2012 +0100
@@ -480,7 +480,7 @@
      * @return the read value encapsulated in a {@link Constant} object
      */
     public Constant readUnsafeConstant(Object object, long displacement) {
-        assert object != null;
+        assert object != null : displacement;
         switch (this) {
             case Boolean:
                 return Constant.forBoolean(unsafe().getBoolean(object, displacement));
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Wed Nov 14 11:28:02 2012 +0100
@@ -31,7 +31,7 @@
 
     /**
      * Returns the resolved Java type representing a given Java class.
-     * 
+     *
      * @param clazz the Java class object
      * @return the resolved Java type object
      */
@@ -49,15 +49,16 @@
 
     /**
      * Returns the resolved Java type of the given {@link Constant} object.
-     * 
+     *
      * @return {@code null} if {@code constant.isNull() || !constant.kind.isObject()}
      */
     ResolvedJavaType lookupJavaType(Constant constant);
 
     /**
-     * Compares two object constants. Since a given runtime might not want to expose the real objects to the compiler,
-     * the {@link Constant#asObject()} cannot be compared directly.
-     * 
+     * Compares two constants for equality.
+     * This is used instead of {@link Constant#equals(Object)} in case where the runtime
+     * may have an interpretation for object equality other than {@code x.asObject() == y.asObject()}.
+     *
      * @return {@code true} if the two parameters represent the same runtime object, {@code false} otherwise
      */
     boolean constantEquals(Constant x, Constant y);
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java	Wed Nov 14 11:28:02 2012 +0100
@@ -38,8 +38,13 @@
     int getModifiers();
 
     /**
+     * Determines if this field was injected by the VM. Such a field, for example, is not derived from a class file.
+     */
+    boolean isInternal();
+
+    /**
      * Gets the constant value of this field for a given object, if available.
-     * 
+     *
      * @param receiver object from which this field's value is to be read. This value is ignored if this field is
      *            static.
      * @return the constant value of this field or {@code null} if the constant value is not available
@@ -48,7 +53,7 @@
 
     /**
      * Gets the current value of this field for a given object, if available.
-     * 
+     *
      * @param receiver object from which this field's value is to be read. This value is ignored if this field is
      *            static.
      * @return the value of this field or {@code null} if the value is not available (e.g., because the field holder is
@@ -63,7 +68,7 @@
 
     /**
      * Returns the annotation for the specified type of this field, if such an annotation is present.
-     * 
+     *
      * @param annotationClass the Class object corresponding to the annotation type
      * @return this element's annotation for the specified annotation type if present on this field, else {@code null}
      */
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Wed Nov 14 11:28:02 2012 +0100
@@ -106,6 +106,7 @@
     /**
      * Returns the Java language modifiers for this type, as an integer. The {@link Modifier} class should be used to
      * decode the modifiers. Only the flags specified in the JVM specification will be included in the returned mask.
+     * This method is identical to {@link Class#getModifiers()} in terms of the value return for this type.
      */
     int getModifiers();
 
@@ -138,16 +139,18 @@
     boolean isInstance(Constant obj);
 
     /**
-     * Attempts to get an exact type for this type. Final classes, arrays of final classes, and primitive types all have
-     * exact types.
+     * Returns this type if it is an exact type otherwise returns null.
+     * This type is exact if it is void, primitive, final, or an array of a final or primitive type.
      *
-     * @return the exact type of this type, if it exists; {@code null} otherwise
+     * @return this type if it is exact; {@code null} otherwise
      */
-    ResolvedJavaType getExactType();
+    ResolvedJavaType asExactType();
 
     /**
-     * Gets the superclass of this type, or {@code null} if it does not exist. This method is analogous to
-     * {@link Class#getSuperclass()}.
+     * Gets the super class of this type.
+     * If this type represents either the {@code Object} class, a primitive type, or void, then
+     * null is returned.  If this object represents an array class or an interface then the
+     * type object representing the {@code Object} class is returned.
      */
     ResolvedJavaType getSuperclass();
 
@@ -188,9 +191,9 @@
     ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method);
 
     /**
-     * Given an JavaMethod a, returns a concrete JavaMethod b that is the only possible unique target for a virtual call
-     * on a(). Returns {@code null} if either no such concrete method or more than one such method exists. Returns the
-     * method a if a is a concrete method that is not overridden.
+     * Given a {@link ResolvedJavaMethod} a, returns a concrete {@link ResolvedJavaMethod} b that is the only possible
+     * unique target for a virtual call on a(). Returns {@code null} if either no such concrete method or more than one
+     * such method exists. Returns the method a if a is a concrete method that is not overridden.
      * <p>
      * If the compiler uses the result of this method for its compilation, it must register an assumption because
      * dynamic class loading can invalidate the result of this method.
@@ -202,12 +205,14 @@
     ResolvedJavaMethod findUniqueConcreteMethod(ResolvedJavaMethod method);
 
     /**
-     * Returns the instance fields declared in this class. A zero-length array is returned for array and primitive
-     * types.
+     * Returns the instance fields of this class, including {@linkplain ResolvedJavaField#isInternal() internal} fields.
+     * A zero-length array is returned for array and primitive types. The order of fields returned by this method is
+     * stable. That is, for a single JVM execution the same order is returned each time this method is called.
      *
+     * @param includeSuperclasses if true, then instance fields for the complete hierarchy of this type are included in the result
      * @return an array of instance fields
      */
-    ResolvedJavaField[] getDeclaredFields();
+    ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses);
 
     /**
      * Returns the annotation for the specified type of this class, if such an annotation is present.
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Wed Nov 14 11:28:02 2012 +0100
@@ -632,10 +632,10 @@
     @Override
     protected void emitSequentialSwitch(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) {
         // Making a copy of the switch value is necessary because jump table destroys the input value
-        if (key.getKind() == Kind.Int) {
+        if (key.getKind() == Kind.Int || key.getKind() == Kind.Long) {
             append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, Value.ILLEGAL));
         } else {
-            assert key.getKind() == Kind.Object;
+            assert key.getKind() == Kind.Object : key.getKind();
             append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, newVariable(Kind.Object)));
         }
     }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Wed Nov 14 11:28:02 2012 +0100
@@ -83,7 +83,6 @@
                             entry.getValue().setValues(new Value[]{toValue(boxedVirtualObjectNode.getUnboxedValue())});
                         } else {
                             Value[] values = new Value[vobj.entryCount()];
-                            entry.getValue().setValues(values);
                             if (values.length > 0) {
                                 changed = true;
                                 VirtualObjectState currentField = (VirtualObjectState) objectStates.get(vobj);
@@ -92,6 +91,7 @@
                                     values[i] = toValue(currentField.fieldValues().get(i));
                                 }
                             }
+                            entry.getValue().setValues(values);
                         }
                     }
                 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Nov 14 11:28:02 2012 +0100
@@ -845,6 +845,7 @@
                 // only a few entries
                 emitSequentialSwitch(x, value, defaultTarget);
             } else {
+                assert value.getKind() == Kind.Int;
                 long valueRange = x.keyAt(keyCount - 1).asLong() - x.keyAt(0).asLong() + 1;
                 int switchRangeCount = switchRangeCount(x);
                 int rangeDensity = keyCount / switchRangeCount;
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/FieldIntrospection.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/FieldIntrospection.java	Wed Nov 14 11:28:02 2012 +0100
@@ -43,11 +43,14 @@
         }
     }
 
-    protected static final Unsafe unsafe = getUnsafe();
+    /**
+     * An instance of {@link Unsafe} for use within Graal.
+     */
+    public static final Unsafe unsafe = getUnsafe();
 
     private static Unsafe getUnsafe() {
         try {
-            // this will only fail if graal is not part of the boot class path
+            // this will fail if Graal is not part of the boot class path
             return Unsafe.getUnsafe();
         } catch (SecurityException e) {
             // nothing to do
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DirectCallOp.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DirectCallOp.java	Wed Nov 14 11:28:02 2012 +0100
@@ -41,9 +41,9 @@
  * A direct call that complies with the conventions for such calls in HotSpot.
  * In particular, for calls using an inline cache, a MOVE instruction is
  * emitted just prior to the aligned direct call. This instruction
- * (which moves null in RAX) is patched by the C++ Graal code to replace the
- * null constant with Universe::non_oop_word(), a special sentinel
- * used for the initial value of the klassOop in an inline cache.
+ * (which moves 0L in RAX) is patched by the C++ Graal code to replace the
+ * 0L constant with Universe::non_oop_word(), a special sentinel
+ * used for the initial value of the Klass in an inline cache.
  * <p>
  * For non-inline cache calls, a static call stub is emitted.
  */
@@ -89,10 +89,10 @@
         } else {
             assert invokeKind == Virtual || invokeKind == Interface;
             // The mark for an invocation that uses an inline cache must be placed at the instruction
-            // that loads the klassOop from the inline cache so that the C++ code can find it
-            // and replace the inline null value with Universe::non_oop_word()
+            // that loads the Klass from the inline cache so that the C++ code can find it
+            // and replace the inline 0L value with Universe::non_oop_word()
             tasm.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE);
-            AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Object), Constant.NULL_OBJECT);
+            AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Long), Constant.LONG_0);
         }
 
         emitAlignmentForDirectCall(tasm, masm);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Wed Nov 14 11:28:02 2012 +0100
@@ -32,8 +32,8 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
+import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.*;
 import com.oracle.graal.compiler.amd64.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.hotspot.*;
@@ -153,11 +153,11 @@
 
         @Override
         protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
-            Value methodOop = AMD64.rbx.asValue();
-            emitMove(operand(((HotSpotIndirectCallTargetNode) callTarget).methodOop()), methodOop);
+            Value metaspaceMethod = AMD64.rbx.asValue();
+            emitMove(operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod()), metaspaceMethod);
             Value targetAddress = AMD64.rax.asValue();
             emitMove(operand(callTarget.computedAddress()), targetAddress);
-            append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, methodOop, targetAddress, callState));
+            append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, metaspaceMethod, targetAddress, callState));
         }
     }
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Wed Nov 14 11:28:02 2012 +0100
@@ -87,24 +87,24 @@
         addRuntimeCall(NEW_OBJECT_ARRAY, c.newObjectArrayStub,
                 /*        temps */ new Register[] {rcx, rdi, rsi},
                 /*          ret */ rax.asValue(Kind.Object),
-                /* arg0:    hub */ rdx.asValue(Kind.Object),
+                /* arg0:    hub */ rdx.asValue(word),
                 /* arg1: length */ rbx.asValue(Kind.Int));
 
         addRuntimeCall(NEW_TYPE_ARRAY, c.newTypeArrayStub,
                 /*        temps */ new Register[] {rcx, rdi, rsi},
                 /*          ret */ rax.asValue(Kind.Object),
-                /* arg0:    hub */ rdx.asValue(Kind.Object),
+                /* arg0:    hub */ rdx.asValue(word),
                 /* arg1: length */ rbx.asValue(Kind.Int));
 
         addRuntimeCall(NEW_INSTANCE, c.newInstanceStub,
                 /*        temps */ null,
                 /*          ret */ rax.asValue(Kind.Object),
-                /* arg0:    hub */ rdx.asValue(Kind.Object));
+                /* arg0:    hub */ rdx.asValue(word));
 
         addRuntimeCall(NEW_MULTI_ARRAY, c.newMultiArrayStub,
                 /*        temps */ null,
                 /*          ret */ rax.asValue(Kind.Object),
-                /* arg0:    hub */ rax.asValue(Kind.Object),
+                /* arg0:    hub */ rax.asValue(word),
                 /* arg1:   rank */ rbx.asValue(Kind.Int),
                 /* arg2:   dims */ rcx.asValue(word));
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java	Wed Nov 14 11:28:02 2012 +0100
@@ -38,7 +38,7 @@
 
 /**
  * A register indirect call that complies with the extra conventions for such calls in HotSpot.
- * In particular, the methodOop of the callee must be in RBX for the case where a vtable entry's
+ * In particular, the metaspace Method of the callee must be in RBX for the case where a vtable entry's
  * _from_compiled_entry is the address of an C2I adapter. Such adapters expect the target
  * method to be in RBX.
  */
@@ -46,28 +46,28 @@
 final class AMD64IndirectCallOp extends IndirectCallOp {
 
     /**
-     * Vtable stubs expect the methodOop in RBX.
+     * Vtable stubs expect the metaspace Method in RBX.
      */
-    public static final Register METHOD_OOP = AMD64.rbx;
+    public static final Register METHOD = AMD64.rbx;
 
-    @Use({REG}) protected Value methodOop;
+    @Use({REG}) protected Value metaspaceMethod;
 
-    AMD64IndirectCallOp(Object targetMethod, Value result, Value[] parameters, Value[] temps, Value methodOop, Value targetAddress, LIRFrameState state) {
+    AMD64IndirectCallOp(Object targetMethod, Value result, Value[] parameters, Value[] temps, Value metaspaceMethod, Value targetAddress, LIRFrameState state) {
         super(targetMethod, result, parameters, temps, targetAddress, state);
-        this.methodOop = methodOop;
+        this.metaspaceMethod = metaspaceMethod;
     }
 
     @Override
     public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
         tasm.recordMark(Marks.MARK_INLINE_INVOKEVIRTUAL);
         Register callReg = asRegister(targetAddress);
-        assert callReg != METHOD_OOP;
+        assert callReg != METHOD;
         AMD64Call.indirectCall(tasm, masm, callReg, targetMethod, state);
     }
 
     @Override
     protected void verify() {
         super.verify();
-        assert asRegister(methodOop) == METHOD_OOP;
+        assert asRegister(metaspaceMethod) == METHOD;
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerObject.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerObject.java	Wed Nov 14 11:28:02 2012 +0100
@@ -28,7 +28,7 @@
 
 
 /**
- * Parent class for all HotSpot Ri... types.
+ * Parent class for all HotSpot types that need to be serialized.
  */
 public abstract class CompilerObject implements Serializable, FormatWithToString {
     private static final long serialVersionUID = -4551670987101214877L;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Wed Nov 14 11:28:02 2012 +0100
@@ -161,33 +161,33 @@
 
     public JavaType lookupType(String name, HotSpotResolvedJavaType accessingClass, boolean eagerResolve) {
         if (name.length() == 1 && vmToCompiler instanceof VMToCompilerImpl) {
-            VMToCompilerImpl exitsNative = (VMToCompilerImpl) vmToCompiler;
+            VMToCompilerImpl impl = (VMToCompilerImpl) vmToCompiler;
             Kind kind = Kind.fromPrimitiveOrVoidTypeChar(name.charAt(0));
             switch(kind) {
                 case Boolean:
-                    return exitsNative.typeBoolean;
+                    return impl.typeBoolean;
                 case Byte:
-                    return exitsNative.typeByte;
+                    return impl.typeByte;
                 case Char:
-                    return exitsNative.typeChar;
+                    return impl.typeChar;
                 case Double:
-                    return exitsNative.typeDouble;
+                    return impl.typeDouble;
                 case Float:
-                    return exitsNative.typeFloat;
+                    return impl.typeFloat;
                 case Illegal:
                     break;
                 case Int:
-                    return exitsNative.typeInt;
+                    return impl.typeInt;
                 case Jsr:
                     break;
                 case Long:
-                    return exitsNative.typeLong;
+                    return impl.typeLong;
                 case Object:
                     break;
                 case Short:
-                    return exitsNative.typeShort;
+                    return impl.typeShort;
                 case Void:
-                    return exitsNative.typeVoid;
+                    return impl.typeVoid;
             }
         }
         return compilerToVm.lookupType(name, accessingClass, eagerResolve);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotKlassOop.java	Mon Nov 12 23:37:12 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot;
-
-import com.oracle.graal.api.meta.*;
-
-/**
- * A mechanism for safely conveying a HotSpot klassOop value from the compiler to the C++ code.
- * Such values should not be directly exposed to Java code as they are not real Java
- * objects. For instance, invoking a method on them or using them in an <code>instanceof</code>
- * expression will most likely crash the VM.
- */
-public class HotSpotKlassOop extends CompilerObject {
-
-    private static final long serialVersionUID = -5445542223575839143L;
-
-    public final ResolvedJavaType type;
-
-    public HotSpotKlassOop(ResolvedJavaType type) {
-        this.type = type;
-    }
-
-    @Override
-    public String toString() {
-        return "HotSpotKlassOop<" + type.toJava().getName() + ">";
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeInterpreterInterface.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeInterpreterInterface.java	Wed Nov 14 11:28:02 2012 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.hotspot;
 
+import static com.oracle.graal.graph.FieldIntrospection.*;
+
 import java.lang.reflect.*;
 
 import sun.misc.*;
@@ -32,8 +34,6 @@
 
 public class HotSpotRuntimeInterpreterInterface implements RuntimeInterpreterInterface {
 
-    private static final Unsafe unsafe = loadUnsafe();
-
     private final MetaAccessProvider metaProvider;
 
     public HotSpotRuntimeInterpreterInterface(MetaAccessProvider metaProvider) {
@@ -322,18 +322,4 @@
         }
         return accessorBase;
     }
-
-    private static Unsafe loadUnsafe() {
-        try {
-            return Unsafe.getUnsafe();
-        } catch (SecurityException e) {
-        }
-        try {
-            Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
-            theUnsafeInstance.setAccessible(true);
-            return (Unsafe) theUnsafeInstance.get(Unsafe.class);
-        } catch (Exception e) {
-            throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e);
-        }
-    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Wed Nov 14 11:28:02 2012 +0100
@@ -53,7 +53,7 @@
     public int markOffset;
 
     /**
-     * The offset of the hub/klassOop word in an object's header.
+     * The offset of the hub (i.e. Klass*) in an object's header.
      */
     public int hubOffset;
 
@@ -63,11 +63,21 @@
     public int prototypeMarkWordOffset;
 
     /**
-     * The offset of an the array length in an array's header.
+     * The offset of the array length word in an array object's header.
      */
     public int arrayLengthOffset;
 
     /**
+     * The offset of the _length field in an Array metaspace object (see array.hpp).
+     */
+    public int metaspaceArrayLengthOffset;
+
+    /**
+     * The offset of the _data field in an Array metaspace object (see array.hpp).
+     */
+    public int metaspaceArrayBaseOffset;
+
+    /**
      * The offset of the _super_check_offset field in a Klass.
      */
     public int superCheckOffsetOffset;
@@ -134,18 +144,70 @@
      */
     public int biasedLockPattern;
 
+    /**
+     * Offset of _access_flags in metaspace Method object.
+     */
+    public int methodAccessFlagsOffset;
+
+    /**
+     * Offset of _max_locals in metaspace Method object.
+     */
+    public int methodMaxLocalsOffset;
+
+    /**
+     * Offset of _max_stack in metaspace Method object.
+     */
+    public int methodMaxStackOffset;
+
+    /**
+     * Value of extra_stack_entries() in method.hpp.
+     */
+    public int extraStackEntries;
+
+    /**
+     * Value of JVM_ACC_HAS_FINALIZER in accessFlags.hpp.
+     */
+    public int klassHasFinalizerFlag;
+
     public int threadExceptionOopOffset;
     public int threadExceptionPcOffset;
-    public int threadMultiNewArrayStorageOffset;
     public long cardtableStartAddress;
     public int cardtableShift;
     public long safepointPollingAddress;
     public boolean isPollingPageFar;
+
+    /**
+     * The offset of the _java_mirror field (of type {@link Class}) in a Klass.
+     */
     public int classMirrorOffset;
+
     public int runtimeCallStackSize;
+
+    /**
+     * The offset of the _modifier_flags field in a Klass.
+     */
     public int klassModifierFlagsOffset;
-    public int klassOopOffset;
-    public int graalMirrorKlassOffset;
+
+    /**
+     * The offset of the _access_flags field in a Klass.
+     */
+    public int klassAccessFlagsOffset;
+
+    /**
+     * The offset of the injected klass field in a {@link Class}.
+     */
+    public int klassOffset;
+
+    /**
+     * The offset of the injected graal_mirror field in a {@link Class}.
+     */
+    public int graalMirrorInClassOffset;
+
+    /**
+     * The offset of the _method_data field in a metaspace Method.
+     */
+    public int methodDataOffset;
+
     public int nmethodEntryOffset;
     public int methodCompiledEntryOffset;
     public int basicLockSize;
@@ -195,7 +257,6 @@
     public long logObjectStub;
     public long logPrintfStub;
 
-
     public void check() {
         assert vmPageSize >= 16;
         assert codeEntryAlignment > 0;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed Nov 14 11:28:02 2012 +0100
@@ -34,19 +34,75 @@
  */
 public interface CompilerToVM {
 
-    byte[] getBytecode(HotSpotResolvedJavaMethod method);
+    /**
+     * Copies the original bytecode of a given method into a given byte array.
+     *
+     * @param metaspaceMethod the metaspace Method object
+     * @param code the array into which to copy the original bytecode
+     * @return the value of {@code code}
+     */
+    byte[] initializeBytecode(long metaspaceMethod, byte[] code);
 
-    String getSignature(HotSpotResolvedJavaMethod method);
+    String getSignature(long metaspaceMethod);
+
+    ExceptionHandler[] initializeExceptionHandlers(long metaspaceMethod, ExceptionHandler[] handlers);
 
-    ExceptionHandler[] getExceptionHandlers(HotSpotResolvedJavaMethod method);
+    /**
+     * Determines if a given metaspace Method object has balanced monitors.
+     *
+     * @param metaspaceMethod the metaspace Method object to query
+     * @return true if the method has balanced monitors
+     */
+    boolean hasBalancedMonitors(long metaspaceMethod);
 
-    boolean hasBalancedMonitors(HotSpotResolvedJavaMethod method);
-
-    JavaMethod getUniqueConcreteMethod(HotSpotResolvedJavaMethod method);
+    /**
+     * Determines if a given metaspace Method object is compilable. A method may not be compilable
+     * for a number of reasons such as:
+     * <ul>
+     * <li>a CompileOracle directive may prevent compilation of methods</li>
+     * <li>the method may have a bytecode breakpoint set</li>
+     * <li>the method may have other bytecode features that require special handling by the VM</li>
+     * </ul>
+     *
+     * A non-compilable method should not be inlined.
+     *
+     * @param metaspaceMethod the metaspace Method object to query
+     * @return true if the method is compilable
+     */
+    boolean isMethodCompilable(long metaspaceMethod);
 
-    int getInvocationCount(HotSpotResolvedJavaMethod method);
+    /**
+     * Used to implement {@link ResolvedJavaType#findUniqueConcreteMethod(ResolvedJavaMethod)}.
+     *
+     * @param metaspaceMethod the metaspace Method on which to based the search
+     * @param resultHolder the holder of the result is put in element 0 of this array
+     * @return the metaspace Method result or 0 is there is no unique concrete method for {@code metaspaceMethod}
+     */
+    long getUniqueConcreteMethod(long metaspaceMethod, HotSpotResolvedJavaType[] resultHolder);
 
-    HotSpotMethodData getMethodData(HotSpotResolvedJavaMethod method);
+    /**
+     * Gets the invocation count for a method.
+     *
+     * @param metaspaceMethod the metaspace Method object to query
+     * @return the invocation count for the method
+     */
+    int getInvocationCount(long metaspaceMethod);
+
+    /**
+     * Initializes a {@link HotSpotResolvedJavaMethod} object from a metaspace Method object.
+     *
+     * @param metaspaceMethod the metaspace Method object
+     * @param method address of a metaspace Method object
+     */
+    void initializeMethod(long metaspaceMethod, HotSpotResolvedJavaMethod method);
+
+    /**
+     * Initializes a {@link HotSpotMethodData} object from a metaspace MethodData object.
+     *
+     * @param metaspaceMethodData the metaspace MethodData object
+     * @param methodData the object to initialize from the metaspace object
+     */
+    void initializeMethodData(long metaspaceMethodData, HotSpotMethodData methodData);
 
     JavaType lookupType(String name, HotSpotResolvedJavaType accessingClass, boolean eagerResolve);
 
@@ -60,7 +116,16 @@
 
     void lookupReferencedTypeInPool(HotSpotResolvedJavaType pool, int cpi, byte opcode);
 
-    HotSpotCompiledMethod installMethod(HotSpotCompilationResult compResult, boolean makeDefault, HotSpotCodeInfo info);
+    /**
+     * Installs the result of a compilation into the code cache.
+     *
+     * @param compResult the result of a compilation
+     * @param code if not null, then the code is installed as the non-default compiled code for the associated method
+     *            and the details of the installation are written to this object
+     * @param info additional information about the installation are written to this object if it is not null
+     * @return the value of {@code code}
+     */
+    HotSpotInstalledCode installCode(HotSpotCompilationResult compResult, HotSpotInstalledCode code, HotSpotCodeInfo info);
 
     void initializeConfiguration(HotSpotVMConfig config);
 
@@ -70,47 +135,53 @@
 
     JavaType getLeastCommonAncestor(HotSpotResolvedJavaType thisType, HotSpotResolvedJavaType otherType);
 
-    JavaType getPrimitiveArrayType(Kind kind);
-
-    JavaType getArrayOf(HotSpotResolvedJavaType klass);
-
-    JavaType getComponentType(HotSpotResolvedJavaType klass);
-
     boolean isTypeInitialized(HotSpotResolvedJavaType klass);
 
     void initializeType(HotSpotResolvedJavaType klass);
 
-    JavaType getType(Class<?> javaClass);
+    ResolvedJavaType getResolvedType(Class<?> javaClass);
 
     JavaType getUniqueConcreteSubtype(HotSpotResolvedJavaType klass);
 
-    JavaType getSuperType(HotSpotResolvedJavaType klass);
-
     int getArrayLength(Constant array);
 
-    boolean compareConstantObjects(Constant x, Constant y);
-
+    /**
+     * Gets the type of an object constant.
+     */
     JavaType getJavaType(Constant constant);
 
-    ResolvedJavaField[] getFields(HotSpotResolvedJavaType klass);
+    HotSpotResolvedJavaField[] getInstanceFields(HotSpotResolvedJavaType klass);
 
-    int getCompiledCodeSize(HotSpotResolvedJavaMethod method);
+    /**
+     * Gets the compiled code size for a method.
+     *
+     * @param metaspaceMethod the metaspace Method object to query
+     * @return the compiled code size the method
+     */
+    int getCompiledCodeSize(long metaspaceMethod);
 
-    JavaMethod getJavaMethod(Method reflectionMethod);
+    /**
+     * Gets the metaspace Method object corresponding to a given reflection {@link Method} object.
+     *
+     * @param reflectionMethod
+     * @param resultHolder the holder of the result is put in element 0 of this array
+     * @return the metaspace Method result for {@code reflectionMethod}
+     */
+    long getMetaspaceMethod(Method reflectionMethod, HotSpotResolvedJavaType[] resultHolder);
 
-    ResolvedJavaField getJavaField(Field reflectionField);
+    HotSpotResolvedJavaField getJavaField(Field reflectionField);
 
     long getMaxCallTargetOffset(long stub);
 
     String disassembleNative(byte[] code, long address);
 
-    StackTraceElement getStackTraceElement(HotSpotResolvedJavaMethod method, int bci);
+    StackTraceElement getStackTraceElement(long metaspaceMethod, int bci);
 
-    Object executeCompiledMethod(HotSpotCompiledMethod method, Object arg1, Object arg2, Object arg3);
+    Object executeCompiledMethod(long metaspaceMethod, long nmethod, Object arg1, Object arg2, Object arg3);
 
-    Object executeCompiledMethodVarargs(HotSpotCompiledMethod method, Object... args);
+    Object executeCompiledMethodVarargs(long metaspaceMethod, long nmethod, Object... args);
 
-    int getVtableEntryOffset(HotSpotResolvedJavaMethod method);
+    int getVtableEntryOffset(long metaspaceMethod);
 
     long[] getDeoptedLeafGraphIds();
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Wed Nov 14 11:28:02 2012 +0100
@@ -35,28 +35,31 @@
 public class CompilerToVMImpl implements CompilerToVM {
 
     @Override
-    public native JavaMethod getJavaMethod(Method reflectionMethod);
+    public native long getMetaspaceMethod(Method reflectionMethod, HotSpotResolvedJavaType[] resultHolder);
 
     @Override
-    public native ResolvedJavaField getJavaField(Field reflectionMethod);
+    public native HotSpotResolvedJavaField getJavaField(Field reflectionMethod);
 
     @Override
-    public native byte[] getBytecode(HotSpotResolvedJavaMethod method);
+    public native byte[] initializeBytecode(long metaspaceMethod, byte[] code);
+
+    @Override
+    public native String getSignature(long metaspaceMethod);
 
     @Override
-    public native String getSignature(HotSpotResolvedJavaMethod method);
+    public native ExceptionHandler[] initializeExceptionHandlers(long metaspaceMethod, ExceptionHandler[] handlers);
 
     @Override
-    public native ExceptionHandler[] getExceptionHandlers(HotSpotResolvedJavaMethod method);
+    public native boolean hasBalancedMonitors(long metaspaceMethod);
 
     @Override
-    public native boolean hasBalancedMonitors(HotSpotResolvedJavaMethod method);
+    public native boolean isMethodCompilable(long metaspaceMethod);
 
     @Override
-    public native JavaMethod getUniqueConcreteMethod(HotSpotResolvedJavaMethod method);
+    public native long getUniqueConcreteMethod(long metaspaceMethod, HotSpotResolvedJavaType[] resultHolder);
 
     @Override
-    public native int getInvocationCount(HotSpotResolvedJavaMethod method);
+    public native int getInvocationCount(long metaspaceMethod);
 
     @Override
     public native JavaType lookupType(String name, HotSpotResolvedJavaType accessingClass, boolean eagerResolve);
@@ -77,7 +80,7 @@
     public native JavaField lookupFieldInPool(HotSpotResolvedJavaType pool, int cpi, byte opcode);
 
     @Override
-    public native HotSpotCompiledMethod installMethod(HotSpotCompilationResult comp, boolean makeDefault, HotSpotCodeInfo info);
+    public native HotSpotInstalledCode installCode(HotSpotCompilationResult comp, HotSpotInstalledCode code, HotSpotCodeInfo info);
 
     @Override
     public native void initializeConfiguration(HotSpotVMConfig config);
@@ -92,31 +95,22 @@
     public native JavaType getLeastCommonAncestor(HotSpotResolvedJavaType thisType, HotSpotResolvedJavaType otherType);
 
     @Override
-    public native JavaType getPrimitiveArrayType(Kind kind);
-
-    @Override
-    public native JavaType getArrayOf(HotSpotResolvedJavaType klass);
-
-    @Override
-    public native JavaType getComponentType(HotSpotResolvedJavaType klass);
-
-    @Override
     public native JavaType getUniqueConcreteSubtype(HotSpotResolvedJavaType klass);
 
     @Override
-    public native JavaType getSuperType(HotSpotResolvedJavaType klass);
-
-    @Override
     public native boolean isTypeInitialized(HotSpotResolvedJavaType klass);
 
     @Override
     public native void initializeType(HotSpotResolvedJavaType klass);
 
     @Override
-    public native HotSpotMethodData getMethodData(HotSpotResolvedJavaMethod method);
+    public native void initializeMethod(long metaspaceMethod, HotSpotResolvedJavaMethod method);
 
     @Override
-    public native JavaType getType(Class<?> javaClass);
+    public native void initializeMethodData(long metaspaceMethodData, HotSpotMethodData methodData);
+
+    @Override
+    public native ResolvedJavaType getResolvedType(Class<?> javaClass);
 
     @Override
     public int getArrayLength(Constant array) {
@@ -124,24 +118,19 @@
     }
 
     @Override
-    public boolean compareConstantObjects(Constant x, Constant y) {
-        return x.asObject() == y.asObject();
-    }
-
-    @Override
     public JavaType getJavaType(Constant constant) {
         Object o = constant.asObject();
         if (o == null) {
             return null;
         }
-        return getType(o.getClass());
+        return HotSpotResolvedJavaType.fromClass(o.getClass());
     }
 
     @Override
-    public native ResolvedJavaField[] getFields(HotSpotResolvedJavaType klass);
+    public native HotSpotResolvedJavaField[] getInstanceFields(HotSpotResolvedJavaType klass);
 
     @Override
-    public native int getCompiledCodeSize(HotSpotResolvedJavaMethod method);
+    public native int getCompiledCodeSize(long metaspaceMethod);
 
     @Override
     public native long getMaxCallTargetOffset(long stub);
@@ -150,16 +139,16 @@
     public native String disassembleNative(byte[] code, long address);
 
     @Override
-    public native StackTraceElement getStackTraceElement(HotSpotResolvedJavaMethod method, int bci);
+    public native StackTraceElement getStackTraceElement(long metaspaceMethod, int bci);
 
     @Override
-    public native Object executeCompiledMethod(HotSpotCompiledMethod method, Object arg1, Object arg2, Object arg3);
+    public native Object executeCompiledMethod(long metaspaceMethod, long nmethod, Object arg1, Object arg2, Object arg3);
 
     @Override
-    public native Object executeCompiledMethodVarargs(HotSpotCompiledMethod method, Object... args);
+    public native Object executeCompiledMethodVarargs(long metaspaceMethod, long nmethod, Object... args);
 
     @Override
-    public native int getVtableEntryOffset(HotSpotResolvedJavaMethod method);
+    public native int getVtableEntryOffset(long metaspaceMethod);
 
     @Override
     public native long[] getDeoptedLeafGraphIds();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Wed Nov 14 11:28:02 2012 +0100
@@ -33,7 +33,7 @@
  */
 public interface VMToCompiler {
 
-    boolean compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, boolean blocking, int priority) throws Throwable;
+    boolean compileMethod(long metaspaceMethod, HotSpotResolvedJavaType holder, int entryBCI, boolean blocking, int priority) throws Throwable;
 
     void shutdownCompiler() throws Throwable;
 
@@ -43,15 +43,36 @@
 
     PrintStream log();
 
-    JavaMethod createJavaMethod(String name, String signature, JavaType holder);
+    JavaMethod createUnresolvedJavaMethod(String name, String signature, JavaType holder);
 
     Signature createSignature(String signature);
 
-    JavaField createJavaField(JavaType holder, String name, JavaType type, int offset, int flags);
+    JavaField createJavaField(JavaType holder, String name, JavaType type, int offset, int flags, boolean internal);
+
+    ResolvedJavaMethod createResolvedJavaMethod(JavaType holder, long metaspaceMethod);
 
     JavaType createPrimitiveJavaType(int basicType);
 
-    JavaType createJavaType(String name);
+    JavaType createUnresolvedJavaType(String name);
+
+    /**
+     * Creates a resolved Java type.
+     *
+     * @param metaspaceKlass the metaspace Klass object for the type
+     * @param name the {@linkplain JavaType#getName() name} of the type
+     * @param simpleName a simple, unqualified name for the type
+     * @param javaMirror the {@link Class} mirror
+     * @param hasFinalizableSubclass specifies if the type has a finalizable subtype
+     * @param sizeOrSpecies the size of an instance of the type, or {@link HotSpotResolvedJavaType#INTERFACE_SPECIES_VALUE} or {@link HotSpotResolvedJavaType#ARRAY_SPECIES_VALUE}
+     * @return the resolved type associated with {@code javaMirror} which may not be the type instantiated by this call
+     *         in the case of another thread racing to create the same type
+     */
+    ResolvedJavaType createResolvedJavaType(long metaspaceKlass,
+                    String name,
+                    String simpleName,
+                    Class javaMirror,
+                    boolean hasFinalizableSubclass,
+                    int sizeOrSpecies);
 
     Constant createConstant(Kind kind, long value);
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Wed Nov 14 11:28:02 2012 +0100
@@ -23,6 +23,8 @@
 
 package com.oracle.graal.hotspot.bridge;
 
+import static com.oracle.graal.graph.FieldIntrospection.*;
+
 import java.io.*;
 import java.lang.reflect.*;
 import java.util.*;
@@ -81,7 +83,26 @@
         typeVoid = new HotSpotTypePrimitive(Kind.Void);
     }
 
+    private static void initMirror(HotSpotTypePrimitive type, long offset) {
+        Class< ? > mirror = type.toJava();
+        unsafe.putObject(mirror, offset, type);
+        assert unsafe.getObject(mirror, offset) == type;
+    }
+
+
     public void startCompiler() throws Throwable {
+
+        long offset = HotSpotGraalRuntime.getInstance().getConfig().graalMirrorInClassOffset;
+        initMirror(typeBoolean, offset);
+        initMirror(typeChar, offset);
+        initMirror(typeFloat, offset);
+        initMirror(typeDouble, offset);
+        initMirror(typeByte, offset);
+        initMirror(typeShort, offset);
+        initMirror(typeInt, offset);
+        initMirror(typeLong, offset);
+        initMirror(typeVoid, offset);
+
         if (GraalOptions.LogFile != null) {
             try {
                 final boolean enableAutoflush = true;
@@ -348,7 +369,13 @@
     }
 
     @Override
+    public boolean compileMethod(long metaspaceMethod, final HotSpotResolvedJavaType holder, final int entryBCI, boolean blocking, int priority) throws Throwable {
+        HotSpotResolvedJavaMethod method = holder.createMethod(metaspaceMethod);
+        return compileMethod(method, entryBCI, blocking, priority);
+    }
+
     public boolean compileMethod(final HotSpotResolvedJavaMethod method, final int entryBCI, boolean blocking, int priority) throws Throwable {
+
         if (CompilationTask.withinEnqueue.get()) {
             // This is required to avoid deadlocking a compiler thread. The issue is that a
             // java.util.concurrent.BlockingQueue is used to implement the compilation worker
@@ -356,6 +383,7 @@
             // to add something to its own queue.
             return false;
         }
+
         CompilationTask.withinEnqueue.set(Boolean.TRUE);
 
         try {
@@ -402,6 +430,7 @@
                 CompilationTask osrTask = CompilationTask.create(graalRuntime, createPhasePlan(osrOptimisticOpts, true), osrOptimisticOpts, method, entryBCI, osrId, Integer.MAX_VALUE, callback);
                 compileQueue.execute(osrTask);
                 latch.await();
+                return true;
             }
             return true;
         } finally {
@@ -410,7 +439,7 @@
     }
 
     @Override
-    public JavaMethod createJavaMethod(String name, String signature, JavaType holder) {
+    public JavaMethod createUnresolvedJavaMethod(String name, String signature, JavaType holder) {
         return new HotSpotMethodUnresolved(name, signature, holder);
     }
 
@@ -420,15 +449,21 @@
     }
 
     @Override
-    public JavaField createJavaField(JavaType holder, String name, JavaType type, int offset, int flags) {
+    public JavaField createJavaField(JavaType holder, String name, JavaType type, int offset, int flags, boolean internal) {
         if (offset != -1) {
             HotSpotResolvedJavaType resolved = (HotSpotResolvedJavaType) holder;
-            return resolved.createField(name, type, offset, flags);
+            return resolved.createField(name, type, offset, flags, internal);
         }
         return new HotSpotUnresolvedField(holder, name, type);
     }
 
     @Override
+    public ResolvedJavaMethod createResolvedJavaMethod(JavaType holder, long metaspaceMethod) {
+        HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) holder;
+        return type.createMethod(metaspaceMethod);
+    }
+
+    @Override
     public ResolvedJavaType createPrimitiveJavaType(int basicType) {
         switch (basicType) {
             case 4:
@@ -455,8 +490,44 @@
     }
 
     @Override
-    public JavaType createJavaType(String name) {
-        return new HotSpotTypeUnresolved(name);
+    public HotSpotTypeUnresolved createUnresolvedJavaType(String name) {
+        int dims = 0;
+        int startIndex = 0;
+        while (name.charAt(startIndex) == '[') {
+            startIndex++;
+            dims++;
+        }
+
+        // Decode name if necessary.
+        if (name.charAt(name.length() - 1) == ';') {
+            assert name.charAt(startIndex) == 'L';
+            return new HotSpotTypeUnresolved(name, name.substring(startIndex + 1, name.length() - 1), dims);
+        } else {
+            return new HotSpotTypeUnresolved(HotSpotTypeUnresolved.getFullName(name, dims), name, dims);
+        }
+    }
+
+    @Override
+    public HotSpotResolvedJavaType createResolvedJavaType(long metaspaceKlass,
+                    String name,
+                    String simpleName,
+                    Class javaMirror,
+                    boolean hasFinalizableSubclass,
+                    int sizeOrSpecies) {
+        HotSpotResolvedJavaType type = new HotSpotResolvedJavaType(
+                                        metaspaceKlass,
+                                        name,
+                                        simpleName,
+                                        javaMirror,
+                                        hasFinalizableSubclass,
+                                        sizeOrSpecies);
+
+        long offset = HotSpotGraalRuntime.getInstance().getConfig().graalMirrorInClassOffset;
+        if (!unsafe.compareAndSwapObject(javaMirror, offset, null, type)) {
+            // lost the race - return the existing value instead
+            type = (HotSpotResolvedJavaType) unsafe.getObject(javaMirror, offset);
+        }
+        return type;
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCompiledMethod.java	Mon Nov 12 23:37:12 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.meta;
-
-import java.lang.reflect.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.hotspot.*;
-
-/**
- * Implementation of {@link InstalledCode} for HotSpot.
- * Stores a reference to the nmethod which contains the compiled code.
- * The nmethod also stores a weak reference to the HotSpotCompiledMethod
- * instance which is necessary to keep the nmethod from being unloaded.
- */
-public class HotSpotCompiledMethod extends CompilerObject implements InstalledCode {
-
-    private static final long serialVersionUID = 156632908220561612L;
-
-    private final ResolvedJavaMethod method;
-    private long nmethod;
-
-    public HotSpotCompiledMethod(ResolvedJavaMethod method) {
-        this.method = method;
-    }
-
-    @Override
-    public ResolvedJavaMethod getMethod() {
-        return method;
-    }
-
-    @Override
-    public boolean isValid() {
-        return nmethod != 0;
-    }
-
-    @Override
-    public String toString() {
-        return "compiled method " + method + " @" + nmethod;
-    }
-
-    @Override
-    public Object execute(Object arg1, Object arg2, Object arg3) {
-        assert method.getSignature().getParameterCount(!Modifier.isStatic(method.getModifiers())) == 3;
-        assert method.getSignature().getParameterKind(0) == Kind.Object;
-        assert method.getSignature().getParameterKind(1) == Kind.Object;
-        assert !Modifier.isStatic(method.getModifiers()) || method.getSignature().getParameterKind(2) == Kind.Object;
-        return HotSpotGraalRuntime.getInstance().getCompilerToVM().executeCompiledMethod(this, arg1, arg2, arg3);
-    }
-
-    private boolean checkArgs(Object... args) {
-        Kind[] sig = MetaUtil.signatureToKinds(method);
-        assert args.length == sig.length : MetaUtil.format("%H.%n(%p): expected ", method) + sig.length + " args, got " + args.length;
-        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].toBoxedJavaClass() == arg.getClass() : MetaUtil.format("%H.%n(%p): expected arg ", method) + i + " to be " + sig[i] + ", not " + arg.getClass();
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public Object executeVarargs(Object... args) {
-        assert checkArgs(args);
-        return HotSpotGraalRuntime.getInstance().getCompilerToVM().executeCompiledMethodVarargs(this, args);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java	Wed Nov 14 11:28:02 2012 +0100
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+
+/**
+ * Implementation of {@link InstalledCode} for HotSpot.
+ * Stores a reference to the nmethod which contains the compiled code.
+ * The nmethod also stores a weak reference to the HotSpotCompiledMethod
+ * instance which is necessary to keep the nmethod from being unloaded.
+ */
+public class HotSpotInstalledCode extends CompilerObject implements InstalledCode {
+
+    private static final long serialVersionUID = 156632908220561612L;
+
+    private final HotSpotResolvedJavaMethod method;
+    private long nmethod;
+
+    public HotSpotInstalledCode(HotSpotResolvedJavaMethod method) {
+        this.method = method;
+    }
+
+    @Override
+    public ResolvedJavaMethod getMethod() {
+        return method;
+    }
+
+    @Override
+    public boolean isValid() {
+        return nmethod != 0;
+    }
+
+    @Override
+    public String toString() {
+        return "compiled method " + method + " @" + nmethod;
+    }
+
+    @Override
+    public Object execute(Object arg1, Object arg2, Object arg3) {
+        assert method.getSignature().getParameterCount(!Modifier.isStatic(method.getModifiers())) == 3;
+        assert method.getSignature().getParameterKind(0) == Kind.Object;
+        assert method.getSignature().getParameterKind(1) == Kind.Object;
+        assert !Modifier.isStatic(method.getModifiers()) || method.getSignature().getParameterKind(2) == Kind.Object;
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().executeCompiledMethod(method.metaspaceMethod, nmethod, arg1, arg2, arg3);
+    }
+
+    private boolean checkArgs(Object... args) {
+        Kind[] sig = MetaUtil.signatureToKinds(method);
+        assert args.length == sig.length : MetaUtil.format("%H.%n(%p): expected ", method) + sig.length + " args, got " + args.length;
+        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].toBoxedJavaClass() == arg.getClass() : MetaUtil.format("%H.%n(%p): expected arg ", method) + i + " to be " + sig[i] + ", not " + arg.getClass();
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public Object executeVarargs(Object... args) {
+        assert checkArgs(args);
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().executeCompiledMethodVarargs(method.metaspaceMethod, nmethod, args);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotJavaType.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotJavaType.java	Wed Nov 14 11:28:02 2012 +0100
@@ -30,7 +30,12 @@
  */
 public abstract class HotSpotJavaType extends CompilerObject implements JavaType {
     private static final long serialVersionUID = -4252886265301910771L;
-    protected String name;
+
+    private final String name;
+
+    public HotSpotJavaType(String name) {
+        this.name = name;
+    }
 
     @Override
     public final String getName() {
@@ -38,8 +43,7 @@
     }
 
     /**
-     * Gets the object representing the C++ klassOop for this type.
-     * Such a value cannot be safely exposed to Java code.
+     * Gets the address of the C++ Klass object for this type.
      */
-    public abstract HotSpotKlassOop klassOop();
+    public abstract Constant klass();
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Wed Nov 14 11:28:02 2012 +0100
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.hotspot.meta;
 
-import java.util.*;
+import static com.oracle.graal.graph.FieldIntrospection.*;
 
-import sun.misc.*;
+import java.util.*;
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
@@ -32,20 +32,17 @@
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.phases.*;
 
-
+/**
+ * Access to a HotSpot MethodData structure (defined in methodData.hpp).
+ */
 public final class HotSpotMethodData extends CompilerObject {
 
     private static final long serialVersionUID = -8873133496591225071L;
 
-    static {
-        config = HotSpotGraalRuntime.getInstance().getConfig();
-    }
-
-    // TODO (chaeubl) use same logic as in NodeClass?
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
+    private static final HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
     private static final HotSpotMethodDataAccessor NO_DATA_NO_EXCEPTION_ACCESSOR = new NoMethodData(ExceptionSeen.FALSE);
     private static final HotSpotMethodDataAccessor NO_DATA_EXCEPTION_POSSIBLY_NOT_RECORDED_ACCESSOR = new NoMethodData(ExceptionSeen.NOT_SUPPORTED);
-    private static final HotSpotVMConfig config;
+
     // sorted by tag
     private static final HotSpotMethodDataAccessor[] PROFILE_DATA_ACCESSORS = {
         null, new BitData(), new CounterData(), new JumpData(),
@@ -53,12 +50,17 @@
         new BranchData(), new MultiBranchData(), new ArgInfoData()
     };
 
-    private Object hotspotMirror;
+    /**
+     * Reference to the C++ MethodData object.
+     */
+    private final long metaspaceMethodData;
+
     private int normalDataSize;
     private int extraDataSize;
 
-    private HotSpotMethodData() {
-        throw new IllegalStateException("this constructor is never actually called, because the objects are allocated from within the VM");
+    HotSpotMethodData(long metaspaceMethodData) {
+        this.metaspaceMethodData = metaspaceMethodData;
+        HotSpotGraalRuntime.getInstance().getCompilerToVM().initializeMethodData(metaspaceMethodData, this);
     }
 
     public boolean hasNormalData() {
@@ -79,7 +81,7 @@
 
     public int getDeoptimizationCount(DeoptimizationReason reason) {
         int reasonIndex = HotSpotGraalRuntime.getInstance().getRuntime().convertDeoptReason(reason);
-        return unsafe.getByte(hotspotMirror, (long) config.methodDataOopTrapHistoryOffset + reasonIndex) & 0xFF;
+        return unsafe.getByte(null, metaspaceMethodData + config.methodDataOopTrapHistoryOffset + reasonIndex) & 0xFF;
     }
 
     public HotSpotMethodDataAccessor getNormalData(int position) {
@@ -116,17 +118,17 @@
 
     private int readUnsignedByte(int position, int offsetInBytes) {
         long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
-        return unsafe.getByte(hotspotMirror, fullOffsetInBytes) & 0xFF;
+        return unsafe.getByte(null, metaspaceMethodData + fullOffsetInBytes) & 0xFF;
     }
 
     private int readUnsignedShort(int position, int offsetInBytes) {
         long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
-        return unsafe.getShort(hotspotMirror, fullOffsetInBytes) & 0xFFFF;
+        return unsafe.getShort(null, metaspaceMethodData + fullOffsetInBytes) & 0xFFFF;
     }
 
     private long readUnsignedInt(int position, int offsetInBytes) {
         long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
-        return unsafe.getInt(hotspotMirror, fullOffsetInBytes) & 0xFFFFFFFFL;
+        return unsafe.getInt(null, metaspaceMethodData + fullOffsetInBytes) & 0xFFFFFFFFL;
     }
 
     private int readUnsignedIntAsSignedInt(int position, int offsetInBytes) {
@@ -136,12 +138,12 @@
 
     private int readInt(int position, int offsetInBytes) {
         long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
-        return unsafe.getInt(hotspotMirror, fullOffsetInBytes);
+        return unsafe.getInt(null, metaspaceMethodData + fullOffsetInBytes);
     }
 
-    private Object readObject(int position, int offsetInBytes) {
+    private long readLong(int position, int offsetInBytes) {
         long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
-        return unsafe.getObject(hotspotMirror, fullOffsetInBytes);
+        return unsafe.getLong(null, metaspaceMethodData + fullOffsetInBytes);
     }
 
     private static int truncateLongToInt(long value) {
@@ -338,17 +340,9 @@
             int entries = 0;
 
             for (int i = 0; i < typeProfileWidth; i++) {
-                Object receiverKlassOop = data.readObject(position, getReceiverOffset(i));
-                if (receiverKlassOop != null) {
-                    Object graalMirror = unsafe.getObject(receiverKlassOop, (long) config.graalMirrorKlassOffset);
-                    if (graalMirror == null) {
-                        Class<?> javaClass = (Class<?>) unsafe.getObject(receiverKlassOop, (long) config.classMirrorOffset);
-                        graalMirror = HotSpotGraalRuntime.getInstance().getCompilerToVM().getType(javaClass);
-                        assert graalMirror != null : "must not return null";
-                    }
-
-
-                    types[entries] = (ResolvedJavaType) graalMirror;
+                long receiverKlass = data.readLong(position, getReceiverOffset(i));
+                if (receiverKlass != 0) {
+                    types[entries] = HotSpotResolvedJavaType.fromMetaspaceKlass(receiverKlass);
 
                     long count = data.readUnsignedInt(position, getCountOffset(i));
                     totalCount += count;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Wed Nov 14 11:28:02 2012 +0100
@@ -36,34 +36,49 @@
  */
 public class HotSpotResolvedJavaField extends CompilerObject implements ResolvedJavaField {
 
+    // Must not conflict with any fields flags used by the VM - the assertion in the constructor checks this assumption
+    private static final int FIELD_INTERNAL_FLAG = 0x80000000;
+
     private static final long serialVersionUID = 7692985878836955683L;
-    private final ResolvedJavaType holder;
+    private final HotSpotResolvedJavaType holder;
     private final String name;
     private final JavaType type;
     private final int offset;
-    private final int accessFlags;
-    private Constant constant;                // Constant part only valid for static fields.
+    private final int flags;
+    private Constant constant;
 
-    public HotSpotResolvedJavaField(ResolvedJavaType holder, String name, JavaType type, int offset, int accessFlags) {
+    public HotSpotResolvedJavaField(HotSpotResolvedJavaType holder, String name, JavaType type, int offset, int flags, boolean internal) {
+        assert (flags & FIELD_INTERNAL_FLAG) == 0;
         this.holder = holder;
         this.name = name;
         this.type = type;
         assert offset != -1;
         this.offset = offset;
-        this.accessFlags = accessFlags;
+        if (internal) {
+            this.flags = flags | FIELD_INTERNAL_FLAG;
+        } else {
+            this.flags = flags;
+        }
     }
 
     @Override
     public int getModifiers() {
-        return accessFlags;
+        return flags & Modifier.fieldModifiers();
     }
 
     @Override
+    public boolean isInternal() {
+        return (flags & FIELD_INTERNAL_FLAG) != 0;
+    }
+
+    private static final String SystemClassName = MetaUtil.toInternalName(System.class.getName());
+
+    @Override
     public Constant readConstantValue(Constant receiver) {
         if (receiver == null) {
-            assert Modifier.isStatic(accessFlags);
+            assert Modifier.isStatic(flags);
             if (constant == null) {
-                if (holder.isInitialized() && holder.toJava() != System.class) {
+                if (holder.isInitialized() && !holder.getName().equals(SystemClassName)) {
                     if (Modifier.isFinal(getModifiers()) || assumeStaticFieldsFinal(holder.toJava())) {
                         constant = readValue(receiver);
                     }
@@ -71,7 +86,7 @@
             }
             return constant;
         } else {
-            assert !Modifier.isStatic(accessFlags);
+            assert !Modifier.isStatic(flags);
             // TODO (chaeubl) HotSpot does not trust final non-static fields (see ciField.cpp)
             if (Modifier.isFinal(getModifiers())) {
                 return readValue(receiver);
@@ -83,14 +98,14 @@
     @Override
     public Constant readValue(Constant receiver) {
         if (receiver == null) {
-            assert Modifier.isStatic(accessFlags);
+            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 null;
         } else {
-            assert !Modifier.isStatic(accessFlags);
+            assert !Modifier.isStatic(flags);
             return this.getKind().readUnsafeConstant(receiver.asObject(), offset);
         }
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Wed Nov 14 11:28:02 2012 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.hotspot.meta;
 
+import static com.oracle.graal.graph.FieldIntrospection.*;
+
 import java.lang.annotation.*;
 import java.lang.reflect.*;
 import java.util.*;
@@ -40,29 +42,27 @@
 
     private static final long serialVersionUID = -5486975070147586588L;
 
-    /** DO NOT USE IN JAVA CODE! */
-    @SuppressWarnings("unused")
-    @Deprecated
-    private Object javaMirror;
+    /**
+     * Reference to metaspace Method object.
+     */
+    final long metaspaceMethod;
 
-    // cached values
-    private final int codeSize;
-    private final int accessFlags;
-    private final int maxLocals;
-    private final int maxStackSize;
+    private final HotSpotResolvedJavaType holder;
+    private /*final*/ int codeSize;
+    private /*final*/ int exceptionHandlerCount;
     private Signature signature;
     private Boolean hasBalancedMonitors;
     private Map<Object, Object> compilerStorage;
-    private ResolvedJavaType holder;
     private HotSpotMethodData methodData;
     private byte[] code;
-    private boolean canBeInlined;
     private int compilationComplexity;
 
     private CompilationTask currentTask;
 
-    private HotSpotResolvedJavaMethod() {
-        throw new IllegalStateException("this constructor is never actually called, because the objects are allocated from within the VM");
+    HotSpotResolvedJavaMethod(HotSpotResolvedJavaType holder, long metaspaceMethod) {
+        this.metaspaceMethod = metaspaceMethod;
+        this.holder = holder;
+        HotSpotGraalRuntime.getInstance().getCompilerToVM().initializeMethod(metaspaceMethod, this);
     }
 
     @Override
@@ -72,18 +72,20 @@
 
     @Override
     public int getModifiers() {
-        return accessFlags;
+        HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
+        return unsafe.getInt(null, metaspaceMethod + config.methodAccessFlagsOffset) & Modifier.methodModifiers();
     }
 
     @Override
     public boolean canBeStaticallyBound() {
-        return (Modifier.isFinal(getModifiers()) || Modifier.isPrivate(getModifiers()) || Modifier.isStatic(getModifiers())) && !Modifier.isAbstract(getModifiers());
+        int modifiers = getModifiers();
+        return (Modifier.isFinal(modifiers) || Modifier.isPrivate(modifiers) || Modifier.isStatic(modifiers)) && !Modifier.isAbstract(modifiers);
     }
 
     @Override
     public byte[] getCode() {
         if (code == null) {
-            code = HotSpotGraalRuntime.getInstance().getCompilerToVM().getBytecode(this);
+            code = HotSpotGraalRuntime.getInstance().getCompilerToVM().initializeBytecode(metaspaceMethod, new byte[codeSize]);
             assert code.length == codeSize : "expected: " + codeSize + ", actual: " + code.length;
         }
         return code;
@@ -96,12 +98,19 @@
 
     @Override
     public ExceptionHandler[] getExceptionHandlers() {
-        return HotSpotGraalRuntime.getInstance().getCompilerToVM().getExceptionHandlers(this);
+        if (exceptionHandlerCount == 0) {
+            return new ExceptionHandler[0];
+        }
+        ExceptionHandler[] handlers = new ExceptionHandler[exceptionHandlerCount];
+        for (int i = 0; i < exceptionHandlerCount; i++) {
+            handlers[i] = new ExceptionHandler(-1, -1, -1, -1, null);
+        }
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().initializeExceptionHandlers(metaspaceMethod, handlers);
     }
 
     public boolean hasBalancedMonitors() {
         if (hasBalancedMonitors == null) {
-            hasBalancedMonitors = HotSpotGraalRuntime.getInstance().getCompilerToVM().hasBalancedMonitors(this);
+            hasBalancedMonitors = HotSpotGraalRuntime.getInstance().getCompilerToVM().hasBalancedMonitors(metaspaceMethod);
         }
         return hasBalancedMonitors;
     }
@@ -118,32 +127,40 @@
 
     @Override
     public int getMaxLocals() {
-        return maxLocals;
+        HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
+        return unsafe.getShort(null, metaspaceMethod + config.methodMaxLocalsOffset) & 0xFFFF;
     }
 
     @Override
     public int getMaxStackSize() {
-        return maxStackSize;
+        HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
+        return config.extraStackEntries + (unsafe.getShort(null, metaspaceMethod + config.methodMaxStackOffset) & 0xFFFF);
     }
 
     @Override
     public StackTraceElement asStackTraceElement(int bci) {
         if (bci < 0 || bci >= codeSize) {
             // HotSpot code can only construct stack trace elements for valid bcis
-            StackTraceElement ste = HotSpotGraalRuntime.getInstance().getCompilerToVM().getStackTraceElement(this, 0);
+            StackTraceElement ste = HotSpotGraalRuntime.getInstance().getCompilerToVM().getStackTraceElement(metaspaceMethod, 0);
             return new StackTraceElement(ste.getClassName(), ste.getMethodName(), ste.getFileName(), -1);
         }
-        return HotSpotGraalRuntime.getInstance().getCompilerToVM().getStackTraceElement(this, bci);
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().getStackTraceElement(metaspaceMethod, bci);
     }
 
     public ResolvedJavaMethod uniqueConcreteMethod() {
-        return (ResolvedJavaMethod) HotSpotGraalRuntime.getInstance().getCompilerToVM().getUniqueConcreteMethod(this);
+        HotSpotResolvedJavaType[] resultHolder = {null};
+        long ucm = HotSpotGraalRuntime.getInstance().getCompilerToVM().getUniqueConcreteMethod(metaspaceMethod, resultHolder);
+        if (ucm != 0L) {
+            assert resultHolder[0] != null;
+            return resultHolder[0].createMethod(ucm);
+        }
+        return null;
     }
 
     @Override
     public Signature getSignature() {
         if (signature == null) {
-            signature = new HotSpotSignature(HotSpotGraalRuntime.getInstance().getCompilerToVM().getSignature(this));
+            signature = new HotSpotSignature(HotSpotGraalRuntime.getInstance().getCompilerToVM().getSignature(metaspaceMethod));
         }
         return signature;
     }
@@ -154,11 +171,11 @@
     }
 
     public int getCompiledCodeSize() {
-        return HotSpotGraalRuntime.getInstance().getCompilerToVM().getCompiledCodeSize(this);
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().getCompiledCodeSize(metaspaceMethod);
     }
 
     public int invocationCount() {
-        return HotSpotGraalRuntime.getInstance().getCompilerToVM().getInvocationCount(this);
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().getInvocationCount(metaspaceMethod);
     }
 
     @Override
@@ -182,7 +199,10 @@
         ProfilingInfo info;
 
         if (GraalOptions.UseProfilingInformation && methodData == null) {
-            methodData = HotSpotGraalRuntime.getInstance().getCompilerToVM().getMethodData(this);
+            long metaspaceMethodData = unsafe.getLong(null, metaspaceMethod + HotSpotGraalRuntime.getInstance().getConfig().methodDataOffset);
+            if (metaspaceMethodData != 0) {
+                methodData = new HotSpotMethodData(metaspaceMethodData);
+            }
         }
 
         if (methodData == null || (!methodData.hasNormalData() && !methodData.hasExtraData())) {
@@ -255,7 +275,7 @@
 
     @Override
     public boolean canBeInlined() {
-        return canBeInlined;
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().isMethodCompilable(metaspaceMethod);
     }
 
     /**
@@ -267,7 +287,7 @@
         if (!holder.isInitialized()) {
             return -1;
         }
-        return HotSpotGraalRuntime.getInstance().getCompilerToVM().getVtableEntryOffset(this);
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().getVtableEntryOffset(metaspaceMethod);
     }
 
     public void setCurrentTask(CompilationTask task) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Wed Nov 14 11:28:02 2012 +0100
@@ -22,12 +22,13 @@
  */
 package com.oracle.graal.hotspot.meta;
 
+import static com.oracle.graal.graph.FieldIntrospection.*;
+
 import java.lang.annotation.*;
 import java.lang.reflect.*;
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 
 /**
@@ -37,54 +38,129 @@
 
     private static final long serialVersionUID = 3481514353553840471L;
 
-    private Class javaMirror;
-    private String simpleName;
-    private int accessFlags;
-    private boolean hasFinalizer;
-    private boolean hasFinalizableSubclass;
-    private int superCheckOffset;
-    private boolean isArrayClass;
-    private boolean isInstanceClass;
-    private boolean isInterface;
-    private int instanceSize;
+    /**
+     * Value for the {@code sizeOrSpecies} parameter in {@link HotSpotResolvedJavaType#HotSpotResolvedJavaType}
+     * denoting that the new type represents an interface class.
+     */
+    public static final int INTERFACE_SPECIES_VALUE = Integer.MIN_VALUE;
+
+    /**
+     * Value for the {@code sizeOrSpecies} parameter in {@link HotSpotResolvedJavaType#HotSpotResolvedJavaType}
+     * denoting that the new type represents an array class.
+     */
+    public static final int ARRAY_SPECIES_VALUE = Integer.MAX_VALUE;
+
+    /**
+     * Reference to the metaspace Klass object.
+     */
+    private final long metaspaceKlass;
+
+    private final Class<?> javaMirror; // this could be read directly from 'metaspaceKlass'...
+    private final String simpleName;
+    private final boolean hasFinalizableSubclass;
+
+    /**
+     * The instance size for an instance type, {@link HotSpotResolvedJavaType#INTERFACE_SPECIES_VALUE} denoting
+     * an interface type or {@link HotSpotResolvedJavaType#ARRAY_SPECIES_VALUE} denoting an array type.
+     */
+    private final int sizeOrSpecies;
+
     private HashMap<Long, ResolvedJavaField> fieldCache;
-    private ResolvedJavaType superType;
+    private HashMap<Long, HotSpotResolvedJavaMethod> methodCache;
+    private HotSpotResolvedJavaField[] instanceFields;
     private ResolvedJavaType[] interfaces;
-    private boolean superTypeSet;
-    private ResolvedJavaField[] fields;
     private ConstantPool constantPool;
     private boolean isInitialized;
     private ResolvedJavaType arrayOfType;
 
-    private HotSpotResolvedJavaType() {
-        throw new GraalInternalError(HotSpotResolvedJavaType.class + " should only be created from C++ code");
+    /**
+     * Gets the Graal mirror from a HotSpot metaspace Klass native object.
+     *
+     * @param metaspaceKlass a metaspace Klass object boxed in a {@link Constant}
+     * @return the {@link ResolvedJavaType} corresponding to {@code klassConstant}
+     */
+    public static ResolvedJavaType fromMetaspaceKlass(Constant metaspaceKlass) {
+        assert metaspaceKlass.getKind().isLong();
+        return fromMetaspaceKlass(metaspaceKlass.asLong());
+    }
+
+    /**
+     * Gets the Graal mirror from a HotSpot metaspace Klass native object.
+     *
+     * @param metaspaceKlass a metaspace Klass object
+     * @return the {@link ResolvedJavaType} corresponding to {@code metaspaceKlass}
+     */
+    public static ResolvedJavaType fromMetaspaceKlass(long metaspaceKlass) {
+        assert metaspaceKlass != 0;
+        Class javaClass = (Class) unsafe.getObject(null, metaspaceKlass + HotSpotGraalRuntime.getInstance().getConfig().classMirrorOffset);
+        assert javaClass != null;
+        return fromClass(javaClass);
+    }
+
+    /**
+     * Gets the Graal mirror from a {@link Class} object.
+     *
+     * @return the {@link HotSpotResolvedJavaType} corresponding to {@code javaClass}
+     */
+    public static ResolvedJavaType fromClass(Class javaClass) {
+        ResolvedJavaType type = (ResolvedJavaType) unsafe.getObject(javaClass, (long) HotSpotGraalRuntime.getInstance().getConfig().graalMirrorInClassOffset);
+        if (type == null) {
+            type = HotSpotGraalRuntime.getInstance().getCompilerToVM().getResolvedType(javaClass);
+            assert type != null;
+        }
+        return type;
+    }
+
+    /**
+     * @param hasFinalizableSubclass
+     * @param sizeOrSpecies the size of an instance of the type, or {@link HotSpotResolvedJavaType#INTERFACE_SPECIES_VALUE} or {@link HotSpotResolvedJavaType#ARRAY_SPECIES_VALUE}
+     */
+    public HotSpotResolvedJavaType(long metaspaceKlass,
+                    String name,
+                    String simpleName,
+                    Class javaMirror,
+                    boolean hasFinalizableSubclass,
+                    int sizeOrSpecies) {
+        super(name);
+        this.metaspaceKlass = metaspaceKlass;
+        this.javaMirror = javaMirror;
+        this.simpleName = simpleName;
+        this.hasFinalizableSubclass = hasFinalizableSubclass;
+        this.sizeOrSpecies = sizeOrSpecies;
+        assert name.charAt(0) != '[' || sizeOrSpecies == ARRAY_SPECIES_VALUE : name + " " + Long.toHexString(sizeOrSpecies);
+        assert javaMirror.isArray() == isArrayClass();
+        assert javaMirror.isInterface() == isInterface();
+        //System.out.println("0x" + Long.toHexString(metaspaceKlass) + ": " + name);
     }
 
     @Override
     public int getModifiers() {
-        return accessFlags;
+        return javaMirror.getModifiers();
+    }
+
+    public int getAccessFlags() {
+        HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
+        return unsafe.getInt(null, metaspaceKlass + config.klassAccessFlagsOffset);
     }
 
     @Override
     public ResolvedJavaType getArrayClass() {
         if (arrayOfType == null) {
-           arrayOfType = (ResolvedJavaType) HotSpotGraalRuntime.getInstance().getCompilerToVM().getArrayOf(this);
+            arrayOfType = fromClass(Array.newInstance(javaMirror, 0).getClass());
         }
         return arrayOfType;
     }
 
     @Override
     public ResolvedJavaType getComponentType() {
-        if (isArrayClass) {
-            return (ResolvedJavaType) HotSpotGraalRuntime.getInstance().getCompilerToVM().getComponentType(this);
-        }
-        return null;
+        Class javaComponentType = javaMirror.getComponentType();
+        return javaComponentType == null ? null : fromClass(javaComponentType);
     }
 
     @Override
     public ResolvedJavaType findUniqueConcreteSubtype() {
         if (isArrayClass()) {
-            return Modifier.isFinal(getComponentType().getModifiers()) ? this : null;
+            return getComponentType().findUniqueConcreteSubtype() != null ? this : null;
         } else {
             ResolvedJavaType subtype = (ResolvedJavaType) HotSpotGraalRuntime.getInstance().getCompilerToVM().getUniqueConcreteSubtype(this);
             assert subtype == null || !subtype.isInterface();
@@ -94,25 +170,17 @@
 
     @Override
     public ResolvedJavaType getSuperclass() {
-        if (!superTypeSet) {
-            Class<?> javaSuper = toJava().getSuperclass();
-            if (javaSuper == null) {
-                superType = null;
-            } else {
-                superType = HotSpotGraalRuntime.getInstance().getRuntime().lookupJavaType(javaSuper);
-            }
-            superTypeSet = true;
-        }
-        return superType;
+        Class javaSuperclass = javaMirror.getSuperclass();
+        return javaSuperclass == null ? null : fromClass(javaSuperclass);
     }
 
     @Override
     public ResolvedJavaType[] getInterfaces() {
         if (interfaces == null) {
-            Class[] javaInterfaces = toJava().getInterfaces();
+            Class[] javaInterfaces = javaMirror.getInterfaces();
             ResolvedJavaType[] result = new ResolvedJavaType[javaInterfaces.length];
             for (int i = 0; i < javaInterfaces.length; i++) {
-                result[i] = HotSpotGraalRuntime.getInstance().getRuntime().lookupJavaType(javaInterfaces[i]);
+                result[i] = fromClass(javaInterfaces[i]);
             }
             interfaces = result;
         }
@@ -129,11 +197,11 @@
     }
 
     @Override
-    public ResolvedJavaType getExactType() {
-        if (Modifier.isFinal(accessFlags)) {
-            return this;
+    public ResolvedJavaType asExactType() {
+        if (isArrayClass()) {
+            return getComponentType().asExactType() != null ? this : null;
         }
-        return null;
+        return Modifier.isFinal(getModifiers()) ? this : null;
     }
 
     @Override
@@ -142,7 +210,7 @@
             case JavaClass:
                 return Constant.forObject(javaMirror);
             case ObjectHub:
-                return Constant.forObject(klassOop());
+                return klass();
             case StaticPrimitiveFields:
             case StaticObjectFields:
                 return Constant.forObject(javaMirror);
@@ -159,13 +227,13 @@
 
     @Override
     public boolean hasFinalizer() {
-        return hasFinalizer;
+        HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
+        return (getAccessFlags() & config.klassHasFinalizerFlag) != 0;
     }
 
     @Override
     public boolean isArrayClass() {
-        assert isArrayClass ^ (isInterface || isInstanceClass);
-        return isArrayClass;
+        return sizeOrSpecies == ARRAY_SPECIES_VALUE;
     }
 
     @Override
@@ -191,14 +259,12 @@
 
     @Override
     public boolean isInstanceClass() {
-        assert isInstanceClass ^ (isInterface || isArrayClass);
-        return isInstanceClass;
+        return !isArrayClass() && !isInterface();
     }
 
     @Override
     public boolean isInterface() {
-        assert isInterface ^ (isInstanceClass || isArrayClass);
-        return isInterface;
+        return sizeOrSpecies == INTERFACE_SPECIES_VALUE;
     }
 
     @Override
@@ -236,13 +302,29 @@
     /**
      * Gets the instance size of this type. If an instance of this type cannot
      * be fast path allocated, then the returned value is negative (its absolute
-     * value gives the size).
+     * value gives the size). Must not be called if this is an array or interface type.
      */
     public int instanceSize() {
-        return instanceSize;
+        assert !isArrayClass();
+        assert !isInterface();
+        return sizeOrSpecies;
     }
 
-    public synchronized ResolvedJavaField createField(String fieldName, JavaType type, int offset, int flags) {
+    public synchronized HotSpotResolvedJavaMethod createMethod(long metaspaceMethod) {
+        HotSpotResolvedJavaMethod method = null;
+        if (methodCache == null) {
+            methodCache = new HashMap<>(8);
+        } else {
+            method = methodCache.get(metaspaceMethod);
+        }
+        if (method == null) {
+            method = new HotSpotResolvedJavaMethod(this, metaspaceMethod);
+            methodCache.put(metaspaceMethod, method);
+        }
+        return method;
+    }
+
+    public synchronized ResolvedJavaField createField(String fieldName, JavaType type, int offset, int flags, boolean internal) {
         ResolvedJavaField result = null;
 
         long id = offset + ((long) flags << 32);
@@ -255,11 +337,11 @@
         }
 
         if (result == null) {
-            result = new HotSpotResolvedJavaField(this, fieldName, type, offset, flags);
+            result = new HotSpotResolvedJavaField(this, fieldName, type, offset, flags, internal);
             fieldCache.put(id, result);
         } else {
             assert result.getName().equals(fieldName);
-            assert result.getModifiers() == flags;
+            assert result.getModifiers() == (Modifier.fieldModifiers() & flags);
         }
 
         return result;
@@ -271,15 +353,37 @@
     }
 
     @Override
-    public ResolvedJavaField[] getDeclaredFields() {
-        if (fields == null) {
-            if (isArrayClass) {
-                fields = new ResolvedJavaField[0];
+    public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) {
+        if (instanceFields == null) {
+            if (isArrayClass() && isInterface()) {
+                instanceFields = new HotSpotResolvedJavaField[0];
             } else {
-                fields = HotSpotGraalRuntime.getInstance().getCompilerToVM().getFields(this);
+                HotSpotResolvedJavaField[] myFields = HotSpotGraalRuntime.getInstance().getCompilerToVM().getInstanceFields(this);
+                if (javaMirror != Object.class) {
+                    HotSpotResolvedJavaField[] superFields = (HotSpotResolvedJavaField[]) getSuperclass().getInstanceFields(true);
+                    HotSpotResolvedJavaField[] fields = Arrays.copyOf(superFields, superFields.length + myFields.length);
+                    System.arraycopy(myFields, 0, fields, superFields.length, myFields.length);
+                    instanceFields = fields;
+                } else {
+                    assert myFields.length == 0 : "java.lang.Object has fields!";
+                    instanceFields = myFields;
+                }
             }
         }
-        return fields;
+        if (!includeSuperclasses) {
+            int myFieldsStart = 0;
+            while (myFieldsStart < instanceFields.length && instanceFields[myFieldsStart].getDeclaringClass() != this) {
+                myFieldsStart++;
+            }
+            if (myFieldsStart == 0) {
+                return instanceFields;
+            }
+            if (myFieldsStart == instanceFields.length) {
+                return new HotSpotResolvedJavaField[0];
+            }
+            return Arrays.copyOfRange(instanceFields, myFieldsStart, instanceFields.length);
+        }
+        return instanceFields;
     }
 
     @Override
@@ -289,7 +393,7 @@
 
     @Override
     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-        return toJava().getAnnotation(annotationClass);
+        return javaMirror.getAnnotation(annotationClass);
     }
 
     @Override
@@ -297,23 +401,19 @@
         return this;
     }
 
-    // this value may require identity semantics so cache it
-    private HotSpotKlassOop klassOopCache;
-
     @Override
-    public synchronized HotSpotKlassOop klassOop() {
-        if (klassOopCache == null) {
-            klassOopCache = new HotSpotKlassOop(this);
-        }
-        return klassOopCache;
+    public Constant klass() {
+        Kind wordKind = HotSpotGraalRuntime.getInstance().getTarget().wordKind;
+        return wordKind.isLong() ? Constant.forLong(metaspaceKlass) : Constant.forInt((int) metaspaceKlass);
     }
 
     public boolean isPrimaryType() {
-        return HotSpotGraalRuntime.getInstance().getConfig().secondarySuperCacheOffset != superCheckOffset;
+        return HotSpotGraalRuntime.getInstance().getConfig().secondarySuperCacheOffset != superCheckOffset();
     }
 
     public int superCheckOffset() {
-        return superCheckOffset;
+        HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
+        return unsafe.getInt(null, metaspaceKlass + config.superCheckOffsetOffset);
     }
 
     public long prototypeMarkWord() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Nov 14 11:28:02 2012 +0100
@@ -22,10 +22,13 @@
  */
 package com.oracle.graal.hotspot.meta;
 
+import static com.oracle.graal.api.code.DeoptimizationAction.*;
 import static com.oracle.graal.api.code.MemoryBarriers.*;
+import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.api.meta.Value.*;
 import static com.oracle.graal.hotspot.snippets.SystemSnippets.*;
 import static com.oracle.graal.java.GraphBuilderPhase.*;
+import static com.oracle.graal.nodes.StructuredGraph.*;
 import static com.oracle.graal.nodes.UnwindNode.*;
 import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*;
 import static com.oracle.graal.snippets.Log.*;
@@ -336,7 +339,7 @@
 
     @Override
     public boolean constantEquals(Constant x, Constant y) {
-        return graalRuntime.getCompilerToVM().compareConstantObjects(x, y);
+        return x.equals(y);
     }
 
     @Override
@@ -365,6 +368,7 @@
     @Override
     public void lower(Node n, LoweringTool tool) {
         StructuredGraph graph = (StructuredGraph) n.graph();
+        Kind wordKind = graalRuntime.getTarget().wordKind;
         if (n instanceof ArrayLengthNode) {
             ArrayLengthNode arrayLengthNode = (ArrayLengthNode) n;
             SafeReadNode safeReadArrayLength = safeReadArrayLength(arrayLengthNode.array(), StructuredGraph.INVALID_GRAPH_ID);
@@ -391,17 +395,17 @@
                         if (vtableEntryOffset > 0) {
                             // We use LocationNode.ANY_LOCATION for the reads that access the vtable entry and the compiled code entry
                             // as HotSpot does not guarantee they are final values.
-                            LoadHubNode hub = graph.add(new LoadHubNode(receiver));
-                            Kind wordKind = graalRuntime.getTarget().wordKind;
-                            Stamp nonNullWordStamp = StampFactory.forWord(wordKind, true);
-                            ReadNode methodOop = graph.add(new ReadNode(hub, LocationNode.create(LocationNode.ANY_LOCATION, wordKind, vtableEntryOffset, graph), nonNullWordStamp));
-                            ReadNode compiledEntry = graph.add(new ReadNode(methodOop, LocationNode.create(LocationNode.ANY_LOCATION, wordKind, config.methodCompiledEntryOffset, graph), nonNullWordStamp));
+                            assert vtableEntryOffset > 0;
+                            LoadHubNode hub = graph.add(new LoadHubNode(receiver, wordKind));
+                            Stamp nonZeroWordStamp = StampFactory.forWord(wordKind, true);
+                            ReadNode metaspaceMethod = graph.add(new ReadNode(hub, LocationNode.create(LocationNode.ANY_LOCATION, wordKind, vtableEntryOffset, graph), nonZeroWordStamp));
+                            ReadNode compiledEntry = graph.add(new ReadNode(metaspaceMethod, LocationNode.create(LocationNode.ANY_LOCATION, wordKind, config.methodCompiledEntryOffset, graph), nonZeroWordStamp));
 
-                            loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(methodOop, compiledEntry, parameters, invoke.node().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall));
+                            loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters, invoke.node().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall));
 
                             graph.addBeforeFixed(invoke.node(), hub);
-                            graph.addAfterFixed(hub, methodOop);
-                            graph.addAfterFixed(methodOop, compiledEntry);
+                            graph.addAfterFixed(hub, metaspaceMethod);
+                            graph.addAfterFixed(metaspaceMethod, compiledEntry);
                         }
                     }
                 }
@@ -427,11 +431,10 @@
         } 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(storeField.field(), storeField.field().getKind(), field.offset(), graph)));
+            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()));
             memoryWrite.setStateAfter(storeField.stateAfter());
             graph.replaceFixedWithFixed(storeField, memoryWrite);
-
             FixedWithNextNode last = memoryWrite;
             if (field.getKind() == Kind.Object && !memoryWrite.value().objectStamp().alwaysNull()) {
                 FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(memoryWrite.object()));
@@ -462,9 +465,7 @@
             }
         } else if (n instanceof LoadIndexedNode) {
             LoadIndexedNode loadIndexed = (LoadIndexedNode) n;
-
             ValueNode boundsCheck = createBoundsCheck(loadIndexed, tool);
-
             Kind elementKind = loadIndexed.elementKind();
             LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index());
             ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), arrayLocation, loadIndexed.stamp()));
@@ -489,8 +490,10 @@
                         value = checkcast;
                     }
                 } else {
-                    LoadHubNode arrayClass = graph.add(new LoadHubNode(array));
-                    FloatingReadNode arrayElementKlass = graph.unique(new FloatingReadNode(arrayClass, LocationNode.create(LocationNode.FINAL_LOCATION, Kind.Object, config.arrayClassElementOffset, graph), null, StampFactory.objectNonNull()));
+                    Stamp nonZeroWordStamp = StampFactory.forWord(wordKind, true);
+                    LoadHubNode arrayClass = graph.add(new LoadHubNode(array, wordKind));
+                    LocationNode location = LocationNode.create(LocationNode.FINAL_LOCATION, wordKind, config.arrayClassElementOffset, graph);
+                    FloatingReadNode arrayElementKlass = graph.unique(new FloatingReadNode(arrayClass, location, null, nonZeroWordStamp));
                     CheckCastDynamicNode checkcast = graph.add(new CheckCastDynamicNode(arrayElementKlass, value));
                     graph.addBeforeFixed(storeIndexed, checkcast);
                     graph.addBeforeFixed(checkcast, arrayClass);
@@ -511,9 +514,6 @@
             assert load.kind() != Kind.Illegal;
             IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, load.loadKind(), load.displacement(), load.offset(), graph, false);
             ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp()));
-            if (load.object().kind().isObject()) {
-                memoryRead.dependencies().add(tool.createNullCheckGuard(load.object(), StructuredGraph.INVALID_GRAPH_ID));
-            }
             graph.replaceFixedWithFixed(load, memoryRead);
         } else if (n instanceof UnsafeStoreNode) {
             UnsafeStoreNode store = (UnsafeStoreNode) n;
@@ -536,10 +536,11 @@
             }
         } else if (n instanceof LoadHubNode) {
             LoadHubNode loadHub = (LoadHubNode) n;
-            LocationNode location = LocationNode.create(LocationNode.FINAL_LOCATION, Kind.Object, config.hubOffset, graph);
+            assert loadHub.kind() == wordKind;
+            LocationNode location = LocationNode.create(LocationNode.FINAL_LOCATION, wordKind, config.hubOffset, graph);
             ValueNode object = loadHub.object();
             ValueNode guard = tool.createNullCheckGuard(object, StructuredGraph.INVALID_GRAPH_ID);
-            ReadNode hub = graph.add(new ReadNode(object, location, StampFactory.objectNonNull()));
+            ReadNode hub = graph.add(new ReadNode(object, location, StampFactory.forWord(wordKind, true)));
             hub.dependencies().add(guard);
             graph.replaceFixed(loadHub, hub);
         } else if (n instanceof CheckCastNode) {
@@ -580,7 +581,7 @@
     private static ValueNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) {
         StructuredGraph graph = (StructuredGraph) n.graph();
         ArrayLengthNode arrayLength = graph.add(new ArrayLengthNode(n.array()));
-        ValueNode guard = tool.createGuard(graph.unique(new IntegerBelowThanNode(n.index(), arrayLength)), DeoptimizationReason.BoundsCheckException, DeoptimizationAction.InvalidateReprofile, n.leafGraphId());
+        ValueNode guard = tool.createGuard(graph.unique(new IntegerBelowThanNode(n.index(), arrayLength)), BoundsCheckException, InvalidateReprofile, n.leafGraphId());
 
         graph.addBeforeFixed(n, arrayLength);
         return guard;
@@ -588,10 +589,10 @@
 
     @Override
     public StructuredGraph intrinsicGraph(ResolvedJavaMethod caller, int bci, ResolvedJavaMethod method, List<? extends Node> parameters) {
-        JavaType holder = method.getDeclaringClass();
+        ResolvedJavaType holder = method.getDeclaringClass();
         String fullName = method.getName() + ((HotSpotSignature) method.getSignature()).asString();
-        String holderName = holder.getName();
-        if (holderName.equals("Ljava/lang/Object;")) {
+        Kind wordKind = graalRuntime.getTarget().wordKind;
+        if (holder.toJava() == Object.class) {
             if (fullName.equals("getClass()Ljava/lang/Class;")) {
                 ValueNode obj = (ValueNode) parameters.get(0);
                 ObjectStamp stamp = (ObjectStamp) obj.stamp();
@@ -604,7 +605,7 @@
                 }
                 StructuredGraph graph = new StructuredGraph();
                 LocalNode receiver = graph.unique(new LocalNode(0, StampFactory.objectNonNull()));
-                LoadHubNode hub = graph.add(new LoadHubNode(receiver));
+                LoadHubNode hub = graph.add(new LoadHubNode(receiver, wordKind));
                 Stamp resultStamp = StampFactory.declaredNonNull(lookupJavaType(Class.class));
                 FloatingReadNode result = graph.unique(new FloatingReadNode(hub, LocationNode.create(LocationNode.FINAL_LOCATION, Kind.Object, config.classMirrorOffset, graph), null, resultStamp));
                 ReturnNode ret = graph.add(new ReturnNode(result));
@@ -612,19 +613,22 @@
                 hub.setNext(ret);
                 return graph;
             }
-        } else if (holderName.equals("Ljava/lang/Class;")) {
+        } else if (holder.toJava() == Class.class) {
             if (fullName.equals("getModifiers()I")) {
                 StructuredGraph graph = new StructuredGraph();
                 LocalNode receiver = graph.unique(new LocalNode(0, StampFactory.objectNonNull()));
-                SafeReadNode klassOop = safeRead(graph, Kind.Object, receiver, config.klassOopOffset, StampFactory.objectNonNull(), StructuredGraph.INVALID_GRAPH_ID);
-                graph.start().setNext(klassOop);
-                // TODO(thomaswue): Care about primitive classes! Crashes for primitive classes at the moment (klassOop == null)
-                FloatingReadNode result = graph.unique(new FloatingReadNode(klassOop, LocationNode.create(LocationNode.FINAL_LOCATION, Kind.Int, config.klassModifierFlagsOffset, graph), null, StampFactory.intValue()));
-                ReturnNode ret = graph.add(new ReturnNode(result));
-                klassOop.setNext(ret);
+                SafeReadNode klass = safeRead(graph, wordKind, receiver, config.klassOffset, StampFactory.forWord(wordKind, true), INVALID_GRAPH_ID);
+                graph.start().setNext(klass);
+                LocationNode location = LocationNode.create(LocationNode.FINAL_LOCATION, Kind.Int, config.klassModifierFlagsOffset, graph);
+                FloatingReadNode readModifiers = graph.unique(new FloatingReadNode(klass, location, null, StampFactory.intValue()));
+                CompareNode isZero = CompareNode.createCompareNode(Condition.EQ, klass, ConstantNode.defaultForKind(wordKind, graph));
+                GuardNode guard = graph.unique(new GuardNode(isZero, graph.start(), NullCheckException, InvalidateReprofile, true, INVALID_GRAPH_ID));
+                readModifiers.dependencies().add(guard);
+                ReturnNode ret = graph.add(new ReturnNode(readModifiers));
+                klass.setNext(ret);
                 return graph;
             }
-        } else if (holderName.equals("Ljava/lang/Thread;")) {
+        } else if (holder.toJava() == 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))));
@@ -640,7 +644,7 @@
     }
 
     public ResolvedJavaType lookupJavaType(Class<?> clazz) {
-        return (ResolvedJavaType) graalRuntime.getCompilerToVM().getType(clazz);
+        return HotSpotResolvedJavaType.fromClass(clazz);
     }
 
     public Object lookupCallTarget(Object target) {
@@ -656,7 +660,11 @@
     }
 
     public ResolvedJavaMethod lookupJavaMethod(Method reflectionMethod) {
-        return (ResolvedJavaMethod) graalRuntime.getCompilerToVM().getJavaMethod(reflectionMethod);
+        CompilerToVM c2vm = graalRuntime.getCompilerToVM();
+        HotSpotResolvedJavaType[] resultHolder = {null};
+        long metaspaceMethod = c2vm.getMetaspaceMethod(reflectionMethod, resultHolder);
+        assert metaspaceMethod != 0L;
+        return resultHolder[0].createMethod(metaspaceMethod);
     }
 
     @Override
@@ -673,15 +681,16 @@
         return hsInfo;
     }
 
-    public void installMethod(ResolvedJavaMethod method, int entryBCI, CompilationResult compResult, CodeInfo[] info) {
+    public void installMethod(HotSpotResolvedJavaMethod method, int entryBCI, CompilationResult compResult, CodeInfo[] info) {
         HotSpotCodeInfo hsInfo = makeInfo(method, compResult, info);
-        graalRuntime.getCompilerToVM().installMethod(new HotSpotCompilationResult((HotSpotResolvedJavaMethod) method, entryBCI, compResult), true, hsInfo);
+        graalRuntime.getCompilerToVM().installCode(new HotSpotCompilationResult(method, entryBCI, compResult), null, hsInfo);
     }
 
     @Override
     public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, CodeInfo[] info) {
         HotSpotCodeInfo hsInfo = makeInfo(method, compResult, info);
-        return graalRuntime.getCompilerToVM().installMethod(new HotSpotCompilationResult((HotSpotResolvedJavaMethod) method, -1, compResult), false, hsInfo);
+        HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method;
+        return graalRuntime.getCompilerToVM().installCode(new HotSpotCompilationResult(hotspotMethod, -1, compResult), new HotSpotInstalledCode(hotspotMethod), hsInfo);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java	Wed Nov 14 11:28:02 2012 +0100
@@ -27,7 +27,6 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.*;
 
 /**
  * Implementation of {@link JavaType} for primitive HotSpot types.
@@ -35,24 +34,25 @@
 public final class HotSpotTypePrimitive extends HotSpotJavaType implements ResolvedJavaType {
 
     private static final long serialVersionUID = -6208552348908071473L;
-    private Kind kind;
-    private final HotSpotKlassOop klassOop;
+    private final Kind kind;
+    private final Class<?> javaMirror;
+    private final Class javaArrayMirror;
 
     public HotSpotTypePrimitive(Kind kind) {
+        super(String.valueOf(Character.toUpperCase(kind.getTypeChar())));
         this.kind = kind;
-        this.name = String.valueOf(Character.toUpperCase(kind.getTypeChar()));
-        this.klassOop = new HotSpotKlassOop(this);
+        this.javaMirror = kind.toJavaClass();
+        this.javaArrayMirror = kind.isVoid() ? null : Array.newInstance(javaMirror, 0).getClass();
     }
 
     @Override
     public int getModifiers() {
-        assert kind != null && kind.toJavaClass() != null;
         return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC;
     }
 
     @Override
     public ResolvedJavaType getArrayClass() {
-        return (ResolvedJavaType) HotSpotGraalRuntime.getInstance().getCompilerToVM().getPrimitiveArrayType(kind);
+        return HotSpotResolvedJavaType.fromClass(javaArrayMirror);
     }
 
     @Override
@@ -61,12 +61,13 @@
     }
 
     @Override
-    public ResolvedJavaType getExactType() {
+    public ResolvedJavaType asExactType() {
         return this;
     }
 
     @Override
     public ResolvedJavaType getSuperclass() {
+        assert javaMirror.getSuperclass() == null;
         return null;
     }
 
@@ -151,18 +152,18 @@
     }
 
     @Override
-    public ResolvedJavaField[] getDeclaredFields() {
+    public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) {
         return new ResolvedJavaField[0];
     }
 
     @Override
     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-        return toJava().getAnnotation(annotationClass);
+        return javaMirror.getAnnotation(annotationClass);
     }
 
     @Override
     public Class< ? > toJava() {
-        return kind.toJavaClass();
+        return javaMirror;
     }
 
     @Override
@@ -171,8 +172,8 @@
     }
 
     @Override
-    public HotSpotKlassOop klassOop() {
-        return klassOop;
+    public Constant klass() {
+        throw GraalInternalError.shouldNotReachHere("HotSpotTypePrimitive.klass()");
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypeUnresolved.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypeUnresolved.java	Wed Nov 14 11:28:02 2012 +0100
@@ -35,40 +35,15 @@
     public final String simpleName;
     public final int dimensions;
 
-    /**
-     * Creates a new unresolved type for a specified type descriptor.
-     */
-    public HotSpotTypeUnresolved(String name) {
-        assert name.length() > 0 : "name cannot be empty";
+    public HotSpotTypeUnresolved(String name, String simpleName, int dimensions) {
+        super(getFullName(name, dimensions));
+        assert dimensions >= 0;
+        this.simpleName = simpleName;
 
-        int dims = 0;
-        int startIndex = 0;
-        while (name.charAt(startIndex) == '[') {
-            startIndex++;
-            dims++;
-        }
-
-        // Decode name if necessary.
-        if (name.charAt(name.length() - 1) == ';') {
-            assert name.charAt(startIndex) == 'L';
-            this.simpleName = name.substring(startIndex + 1, name.length() - 1);
-            this.name = name;
-        } else {
-            this.simpleName = name;
-            this.name = getFullName(name, dims);
-        }
-
-        this.dimensions = dims;
+        this.dimensions = dimensions;
     }
 
-    public HotSpotTypeUnresolved(String name, int dimensions) {
-        assert dimensions >= 0;
-        this.simpleName = name;
-        this.dimensions = dimensions;
-        this.name = getFullName(name, dimensions);
-    }
-
-    private static String getFullName(String name, int dimensions) {
+    public static String getFullName(String name, int dimensions) {
         StringBuilder str = new StringBuilder(name.length() + dimensions + 2);
         for (int i = 0; i < dimensions; i++) {
             str.append('[');
@@ -80,12 +55,14 @@
     @Override
     public JavaType getComponentType() {
         assert dimensions > 0 : "no array class" + getName();
-        return new HotSpotTypeUnresolved(simpleName, dimensions - 1);
+        String name = getFullName(getName(), dimensions - 1);
+        return new HotSpotTypeUnresolved(name, simpleName, dimensions - 1);
     }
 
     @Override
     public JavaType getArrayClass() {
-        return new HotSpotTypeUnresolved(simpleName, dimensions + 1);
+        String name = getFullName(getName(), dimensions + 1);
+        return new HotSpotTypeUnresolved(name, simpleName, dimensions + 1);
     }
 
     @Override
@@ -110,11 +87,11 @@
 
     @Override
     public ResolvedJavaType resolve(ResolvedJavaType accessingClass) {
-        return (ResolvedJavaType) HotSpotGraalRuntime.getInstance().lookupType(name, (HotSpotResolvedJavaType) accessingClass, true);
+        return (ResolvedJavaType) HotSpotGraalRuntime.getInstance().lookupType(getName(), (HotSpotResolvedJavaType) accessingClass, true);
     }
 
     @Override
-    public HotSpotKlassOop klassOop() {
-        throw GraalInternalError.shouldNotReachHere("HotSpotTypeUnresolved.klassOop");
+    public Constant klass() {
+        throw GraalInternalError.shouldNotReachHere("HotSpotTypeUnresolved.klass()");
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CastFromHub.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CastFromHub.java	Wed Nov 14 11:28:02 2012 +0100
@@ -23,13 +23,14 @@
 package com.oracle.graal.hotspot.nodes;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.snippets.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.snippets.*;
 
 /**
  * This node is used by the {@link NewObjectSnippets} to give a formatted new instance or object its exact type.
@@ -55,12 +56,12 @@
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         if (hub.isConstant()) {
-            ResolvedJavaType type = ((HotSpotKlassOop) this.hub.asConstant().asObject()).type;
+            ResolvedJavaType type = HotSpotResolvedJavaType.fromMetaspaceKlass(hub.asConstant());
             return graph().unique(new UnsafeCastNode(object, type, true, true));
         }
         return this;
     }
 
     @NodeIntrinsic
-    public static native <T> T castFromHub(Object object, Object hub);
+    public static native <T> T castFromHub(Object object, Word hub);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotIndirectCallTargetNode.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotIndirectCallTargetNode.java	Wed Nov 14 11:28:02 2012 +0100
@@ -31,14 +31,14 @@
 
 public class HotSpotIndirectCallTargetNode extends IndirectCallTargetNode {
 
-    @Input private ValueNode methodOop;
+    @Input private ValueNode metaspaceMethod;
 
-    public HotSpotIndirectCallTargetNode(ValueNode methodOop, ValueNode computedAddress, List<ValueNode> arguments, Stamp returnStamp, Kind[] signature, Object target, Type callType) {
+    public HotSpotIndirectCallTargetNode(ValueNode metaspaceMethod, ValueNode computedAddress, List<ValueNode> arguments, Stamp returnStamp, Kind[] signature, Object target, Type callType) {
         super(computedAddress, arguments, returnStamp, signature, target, callType);
-        this.methodOop = methodOop;
+        this.metaspaceMethod = metaspaceMethod;
     }
 
-    public ValueNode methodOop() {
-        return methodOop;
+    public ValueNode metaspaceMethod() {
+        return metaspaceMethod;
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java	Wed Nov 14 11:28:02 2012 +0100
@@ -22,15 +22,18 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.RuntimeCall.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.snippets.*;
 
 /**
  * Node implementing a call to HotSpot's {@code new_[object|type]_array} stub.
@@ -43,9 +46,9 @@
     @Input private final ValueNode length;
     private final boolean isObjectArray;
 
-    public static final Descriptor NEW_OBJECT_ARRAY = new Descriptor("new_object_array", false, Kind.Object, Kind.Object, Kind.Int);
+    public static final Descriptor NEW_OBJECT_ARRAY = new Descriptor("new_object_array", false, Kind.Object, wordKind(), Kind.Int);
 
-    public static final Descriptor NEW_TYPE_ARRAY = new Descriptor("new_type_array", false, Kind.Object, Kind.Object, Kind.Int);
+    public static final Descriptor NEW_TYPE_ARRAY = new Descriptor("new_type_array", false, Kind.Object, wordKind(), Kind.Int);
 
     public NewArrayStubCall(boolean isObjectArray, ValueNode hub, ValueNode length) {
         super(defaultStamp);
@@ -57,8 +60,7 @@
     @Override
     public boolean inferStamp() {
         if (stamp() == defaultStamp && hub.isConstant()) {
-            HotSpotKlassOop klassOop = (HotSpotKlassOop) this.hub.asConstant().asObject();
-            updateStamp(StampFactory.exactNonNull(klassOop.type));
+            updateStamp(StampFactory.exactNonNull(HotSpotResolvedJavaType.fromMetaspaceKlass(hub.asConstant())));
             return true;
         }
         return false;
@@ -72,5 +74,5 @@
     }
 
     @NodeIntrinsic
-    public static native Object call(@ConstantNodeParameter boolean isObjectArray, Object hub, int length);
+    public static native Object call(@ConstantNodeParameter boolean isObjectArray, Word hub, int length);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java	Wed Nov 14 11:28:02 2012 +0100
@@ -22,15 +22,18 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.RuntimeCall.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.snippets.*;
 
 /**
  * Node implementing a call to HotSpot's {@code new_instance} stub.
@@ -41,7 +44,7 @@
 
     @Input private final ValueNode hub;
 
-    public static final Descriptor NEW_INSTANCE = new Descriptor("new_instance", false, Kind.Object, Kind.Object);
+    public static final Descriptor NEW_INSTANCE = new Descriptor("new_instance", false, Kind.Object, wordKind());
 
     public NewInstanceStubCall(ValueNode hub) {
         super(defaultStamp);
@@ -51,8 +54,7 @@
     @Override
     public boolean inferStamp() {
         if (stamp() == defaultStamp && hub.isConstant()) {
-            HotSpotKlassOop klassOop = (HotSpotKlassOop) this.hub.asConstant().asObject();
-            updateStamp(StampFactory.exactNonNull(klassOop.type));
+            updateStamp(StampFactory.exactNonNull(HotSpotResolvedJavaType.fromMetaspaceKlass(hub.asConstant())));
             return true;
         }
         return false;
@@ -66,5 +68,5 @@
     }
 
     @NodeIntrinsic
-    public static native Object call(Object hub);
+    public static native Object call(Word hub);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java	Wed Nov 14 11:28:02 2012 +0100
@@ -29,7 +29,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
@@ -46,7 +46,7 @@
     @Input private final ValueNode dims;
     private final int rank;
 
-    public static final Descriptor NEW_MULTI_ARRAY = new Descriptor("new_multi_array", false, Kind.Object, Kind.Object, Kind.Int, wordKind());
+    public static final Descriptor NEW_MULTI_ARRAY = new Descriptor("new_multi_array", false, Kind.Object, wordKind(), Kind.Int, wordKind());
 
     public NewMultiArrayStubCall(ValueNode hub, int rank, ValueNode dims) {
         super(defaultStamp);
@@ -58,8 +58,7 @@
     @Override
     public boolean inferStamp() {
         if (stamp() == defaultStamp && hub.isConstant()) {
-            HotSpotKlassOop klassOop = (HotSpotKlassOop) this.hub.asConstant().asObject();
-            updateStamp(StampFactory.exactNonNull(klassOop.type));
+            updateStamp(StampFactory.exactNonNull(HotSpotResolvedJavaType.fromMetaspaceKlass(hub.asConstant())));
             return true;
         }
         return false;
@@ -73,5 +72,5 @@
     }
 
     @NodeIntrinsic
-    public static native Object call(Object hub, @ConstantNodeParameter int rank, Word dims);
+    public static native Object call(Word hub, @ConstantNodeParameter int rank, Word dims);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java	Wed Nov 14 11:28:02 2012 +0100
@@ -22,23 +22,25 @@
  */
 package com.oracle.graal.hotspot.snippets;
 import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import static com.oracle.graal.snippets.Snippet.Varargs.*;
 import static com.oracle.graal.snippets.SnippetTemplate.*;
 import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.hotspot.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Node.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.snippets.*;
 import com.oracle.graal.snippets.Snippet.ConstantParameter;
 import com.oracle.graal.snippets.Snippet.Parameter;
+import com.oracle.graal.snippets.Snippet.Varargs;
 import com.oracle.graal.snippets.Snippet.VarargsParameter;
 import com.oracle.graal.snippets.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.snippets.SnippetTemplate.Arguments;
@@ -53,21 +55,25 @@
  */
 public class CheckCastSnippets implements SnippetsInterface {
 
+    @NodeIntrinsic(BreakpointNode.class)
+    static native void bkpt(Object object, Word hub, Word objectHub);
+
     /**
      * Type test used when the type being tested against is a final type.
      */
     @Snippet
     public static Object checkcastExact(
                     @Parameter("object") Object object,
-                    @Parameter("exactHub") Object exactHub,
+                    @Parameter("exactHub") Word exactHub,
                     @ConstantParameter("checkNull") boolean checkNull) {
         if (checkNull && object == null) {
             isNull.inc();
             return object;
         }
-        Object objectHub = loadHub(object);
+        Word objectHub = loadHub(object);
         if (objectHub != exactHub) {
             exactMiss.inc();
+            //bkpt(object, exactHub, objectHub);
             DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ClassCastException);
         }
         exactHit.inc();
@@ -83,7 +89,7 @@
      */
     @Snippet
     public static Object checkcastPrimary(
-                    @Parameter("hub") Object hub,
+                    @Parameter("hub") Word hub,
                     @Parameter("object") Object object,
                     @ConstantParameter("checkNull") boolean checkNull,
                     @ConstantParameter("superCheckOffset") int superCheckOffset) {
@@ -91,8 +97,8 @@
             isNull.inc();
             return object;
         }
-        Object objectHub = loadHub(object);
-        if (UnsafeLoadNode.loadObject(objectHub, 0, superCheckOffset, true) != hub) {
+        Word objectHub = loadHub(object);
+        if (loadWordFromWord(objectHub, superCheckOffset) != hub) {
             displayMiss.inc();
             DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ClassCastException);
         }
@@ -105,19 +111,19 @@
      */
     @Snippet
     public static Object checkcastSecondary(
-                    @Parameter("hub") Object hub,
+                    @Parameter("hub") Word hub,
                     @Parameter("object") Object object,
-                    @VarargsParameter("hints") Object[] hints,
+                    @VarargsParameter("hints") Word[] hints,
                     @ConstantParameter("checkNull") boolean checkNull) {
         if (checkNull && object == null) {
             isNull.inc();
             return object;
         }
-        Object objectHub = loadHub(object);
+        Word objectHub = loadHub(object);
         // if we get an exact match: succeed immediately
         ExplodeLoopNode.explodeLoop();
         for (int i = 0; i < hints.length; i++) {
-            Object hintHub = hints[i];
+            Word hintHub = hints[i];
             if (hintHub == objectHub) {
                 hintsHit.inc();
                 return object;
@@ -135,28 +141,27 @@
      */
     @Snippet
     public static Object checkcastDynamic(
-                    @Parameter("hub") Object hub,
+                    @Parameter("hub") Word hub,
                     @Parameter("object") Object object,
                     @ConstantParameter("checkNull") boolean checkNull) {
         if (checkNull && object == null) {
             isNull.inc();
             return object;
         }
-        Object objectHub = loadHub(object);
+        Word objectHub = loadHub(object);
         if (!checkUnknownSubType(hub, objectHub)) {
             DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ClassCastException);
         }
         return object;
     }
 
-    //This is used instead of a Java array read to avoid the array bounds check.
-    static Object loadNonNullObjectElement(Object array, int index) {
-        return UnsafeLoadNode.loadObject(array, arrayBaseOffset(Kind.Object), index * arrayIndexScale(Kind.Object), true);
+    static Word loadWordElement(Word metaspaceArray, int index) {
+        return loadWordFromWord(metaspaceArray, metaspaceArrayBaseOffset() + index * wordSize());
     }
 
-    static boolean checkSecondarySubType(Object t, Object s) {
+    static boolean checkSecondarySubType(Word t, Word s) {
         // if (S.cache == T) return true
-        if (UnsafeLoadNode.loadObject(s, 0, secondarySuperCacheOffset(), true) == t) {
+        if (loadWordFromWord(s, secondarySuperCacheOffset()) == t) {
             cacheHit.inc();
             return true;
         }
@@ -168,11 +173,11 @@
         }
 
         // if (S.scan_s_s_array(T)) { S.cache = T; return true; }
-        Object[] secondarySupers = UnsafeCastNode.cast(UnsafeLoadNode.loadObject(s, 0, secondarySupersOffset(), true), Object[].class);
-
-        for (int i = 0; i < secondarySupers.length; i++) {
-            if (t == loadNonNullObjectElement(secondarySupers, i)) {
-                DirectObjectStoreNode.storeObject(s, secondarySuperCacheOffset(), 0, t);
+        Word secondarySupers = loadWordFromWord(s, secondarySupersOffset());
+        int length = loadIntFromWord(secondarySupers, metaspaceArrayLengthOffset());
+        for (int i = 0; i < length; i++) {
+            if (t == loadWordElement(secondarySupers, i)) {
+                DirectObjectStoreNode.storeWord(s, secondarySuperCacheOffset(), 0, t);
                 secondariesHit.inc();
                 return true;
             }
@@ -181,13 +186,13 @@
         return false;
     }
 
-    static boolean checkUnknownSubType(Object t, Object s) {
+    static boolean checkUnknownSubType(Word t, Word s) {
         // int off = T.offset
         int superCheckOffset = UnsafeLoadNode.load(t, 0, superCheckOffsetOffset(), Kind.Int);
         boolean primary = superCheckOffset != secondarySuperCacheOffset();
 
         // if (T = S[off]) return true
-        if (UnsafeLoadNode.loadObject(s, 0, superCheckOffset, true) == t) {
+        if (loadWordFromWord(s, superCheckOffset) == t) {
             if (primary) {
                 cacheHit.inc();
             } else {
@@ -209,10 +214,11 @@
         }
 
         // if (S.scan_s_s_array(T)) { S.cache = T; return true; }
-        Object[] secondarySupers = UnsafeCastNode.cast(UnsafeLoadNode.loadObject(s, 0, secondarySupersOffset(), true), Object[].class);
-        for (int i = 0; i < secondarySupers.length; i++) {
-            if (t == loadNonNullObjectElement(secondarySupers, i)) {
-                DirectObjectStoreNode.storeObject(s, secondarySuperCacheOffset(), 0, t);
+        Word secondarySupers = loadWordFromWord(s, secondarySupersOffset());
+        int length = loadIntFromWord(secondarySupers, metaspaceArrayLengthOffset());
+        for (int i = 0; i < length; i++) {
+            if (t == loadWordElement(secondarySupers, i)) {
+                DirectObjectStoreNode.storeWord(s, secondarySuperCacheOffset(), 0, t);
                 secondariesHit.inc();
                 return true;
             }
@@ -231,10 +237,10 @@
 
         public Templates(CodeCacheProvider runtime) {
             super(runtime, CheckCastSnippets.class);
-            exact = snippet("checkcastExact", Object.class, Object.class, boolean.class);
-            primary = snippet("checkcastPrimary", Object.class, Object.class, boolean.class, int.class);
-            secondary = snippet("checkcastSecondary", Object.class, Object.class, Object[].class, boolean.class);
-            dynamic = snippet("checkcastDynamic", Object.class, Object.class, boolean.class);
+            exact = snippet("checkcastExact", Object.class, Word.class, boolean.class);
+            primary = snippet("checkcastPrimary", Word.class, Object.class, boolean.class, int.class);
+            secondary = snippet("checkcastSecondary", Word.class, Object.class, Word[].class, boolean.class);
+            dynamic = snippet("checkcastDynamic", Word.class, Object.class, boolean.class);
         }
 
         /**
@@ -243,16 +249,16 @@
         public void lower(CheckCastNode checkcast, LoweringTool tool) {
             StructuredGraph graph = (StructuredGraph) checkcast.graph();
             ValueNode object = checkcast.object();
+            final HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) checkcast.type();
             TypeCheckHints hintInfo = new TypeCheckHints(checkcast.type(), checkcast.profile(), tool.assumptions(), GraalOptions.CheckcastMinHintHitProbability, GraalOptions.CheckcastMaxHints);
-            final HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) checkcast.type();
-            ValueNode hub = ConstantNode.forObject(type.klassOop(), runtime, checkcast.graph());
+            ValueNode hub = ConstantNode.forConstant(type.klass(), runtime, checkcast.graph());
             boolean checkNull = !object.stamp().nonNull();
             Arguments arguments;
             Key key;
 
             assert type != null;
             if (hintInfo.exact) {
-                HotSpotKlassOop[] hints = createHints(hintInfo);
+                ConstantNode[] hints = createHints(hintInfo, runtime, graph);
                 assert hints.length == 1;
                 key = new Key(exact).add("checkNull", checkNull);
                 arguments = arguments("object", object).add("exactHub", hints[0]);
@@ -260,8 +266,8 @@
                 key = new Key(primary).add("checkNull", checkNull).add("superCheckOffset", type.superCheckOffset());
                 arguments = arguments("hub", hub).add("object", object);
             } else {
-                HotSpotKlassOop[] hints = createHints(hintInfo);
-                key = new Key(secondary).add("hints", vargargs(Object.class, hints.length)).add("checkNull", checkNull);
+                ConstantNode[] hints = createHints(hintInfo, runtime, graph);
+                key = new Key(secondary).add("hints", Varargs.vargargs(new Word[hints.length], StampFactory.forWord(wordKind(), true))).add("checkNull", checkNull);
                 arguments = arguments("hub", hub).add("object", object).add("hints", hints);
             }
 
@@ -287,10 +293,10 @@
             template.instantiate(runtime, checkcast, DEFAULT_REPLACER, arguments);
         }
 
-        static HotSpotKlassOop[] createHints(TypeCheckHints hints) {
-            HotSpotKlassOop[] hintHubs = new HotSpotKlassOop[hints.types.length];
+        static ConstantNode[] createHints(TypeCheckHints hints, MetaAccessProvider runtime, Graph graph) {
+            ConstantNode[] hintHubs = new ConstantNode[hints.types.length];
             for (int i = 0; i < hintHubs.length; i++) {
-                hintHubs[i] = ((HotSpotJavaType) hints.types[i]).klassOop();
+                hintHubs[i] = ConstantNode.forConstant(((HotSpotJavaType) hints.types[i]).klass(), runtime, graph);
             }
             return hintHubs;
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java	Wed Nov 14 11:28:02 2012 +0100
@@ -138,6 +138,16 @@
     }
 
     @Fold
+    static int metaspaceArrayLengthOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().metaspaceArrayLengthOffset;
+    }
+
+    @Fold
+    static int metaspaceArrayBaseOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().metaspaceArrayBaseOffset;
+    }
+
+    @Fold
     static int arrayLengthOffset() {
         return HotSpotGraalRuntime.getInstance().getConfig().arrayLengthOffset;
     }
@@ -190,11 +200,10 @@
     /**
      * Loads the hub from a object, null checking it first.
      */
-    static Object loadHub(Object object) {
-        return LoadHubNode.loadHub(object);
+    static Word loadHub(Object object) {
+        return loadHubIntrinsic(object, wordKind());
     }
 
-
     static Object verifyOop(Object object) {
         if (verifyOops()) {
             VerifyOopStubCall.call(object);
@@ -216,6 +225,11 @@
         return HotSpotSnippetUtils.registerAsWord(threadRegister());
     }
 
+    static int loadIntFromWord(Word address, int offset) {
+        Integer value = UnsafeLoadNode.load(address, 0, offset, Kind.Int);
+        return value;
+    }
+
     static Word loadWordFromWord(Word address, int offset) {
         return loadWordFromWordIntrinsic(address, 0, offset, wordKind());
     }
@@ -233,6 +247,9 @@
     @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true)
     private static native Word loadWordFromWordIntrinsic(Word address, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind wordKind);
 
+    @NodeIntrinsic(value = LoadHubNode.class, setStampFromReturnType = true)
+    static native Word loadHubIntrinsic(Object object, @ConstantNodeParameter Kind word);
+
     static {
         assert arrayIndexScale(Kind.Byte) == 1;
         assert arrayIndexScale(Kind.Boolean) == 1;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/InstanceOfSnippets.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/InstanceOfSnippets.java	Wed Nov 14 11:28:02 2012 +0100
@@ -24,21 +24,20 @@
 import static com.oracle.graal.hotspot.snippets.CheckCastSnippets.*;
 import static com.oracle.graal.hotspot.snippets.CheckCastSnippets.Templates.*;
 import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
-import static com.oracle.graal.snippets.Snippet.Varargs.*;
 import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.snippets.*;
 import com.oracle.graal.snippets.Snippet.ConstantParameter;
 import com.oracle.graal.snippets.Snippet.Parameter;
+import com.oracle.graal.snippets.Snippet.Varargs;
 import com.oracle.graal.snippets.Snippet.VarargsParameter;
 import com.oracle.graal.snippets.SnippetTemplate.Arguments;
 import com.oracle.graal.snippets.SnippetTemplate.Key;
@@ -60,7 +59,7 @@
     @Snippet
     public static Object instanceofExact(
                     @Parameter("object") Object object,
-                    @Parameter("exactHub") Object exactHub,
+                    @Parameter("exactHub") Word exactHub,
                     @Parameter("trueValue") Object trueValue,
                     @Parameter("falseValue") Object falseValue,
                     @ConstantParameter("checkNull") boolean checkNull) {
@@ -68,7 +67,7 @@
             isNull.inc();
             return falseValue;
         }
-        Object objectHub = loadHub(object);
+        Word objectHub = loadHub(object);
         if (objectHub != exactHub) {
             exactMiss.inc();
             return falseValue;
@@ -82,7 +81,7 @@
      */
     @Snippet
     public static Object instanceofPrimary(
-                    @Parameter("hub") Object hub,
+                    @Parameter("hub") Word hub,
                     @Parameter("object") Object object,
                     @Parameter("trueValue") Object trueValue,
                     @Parameter("falseValue") Object falseValue,
@@ -92,8 +91,8 @@
             isNull.inc();
             return falseValue;
         }
-        Object objectHub = loadHub(object);
-        if (UnsafeLoadNode.loadObject(objectHub, 0, superCheckOffset, true) != hub) {
+        Word objectHub = loadHub(object);
+        if (loadWordFromWord(objectHub, superCheckOffset) != hub) {
             displayMiss.inc();
             return falseValue;
         }
@@ -106,21 +105,21 @@
      */
     @Snippet
     public static Object instanceofSecondary(
-                    @Parameter("hub") Object hub,
+                    @Parameter("hub") Word hub,
                     @Parameter("object") Object object,
                     @Parameter("trueValue") Object trueValue,
                     @Parameter("falseValue") Object falseValue,
-                    @VarargsParameter("hints") Object[] hints,
+                    @VarargsParameter("hints") Word[] hints,
                     @ConstantParameter("checkNull") boolean checkNull) {
         if (checkNull && object == null) {
             isNull.inc();
             return falseValue;
         }
-        Object objectHub = loadHub(object);
+        Word objectHub = loadHub(object);
         // if we get an exact match: succeed immediately
         ExplodeLoopNode.explodeLoop();
         for (int i = 0; i < hints.length; i++) {
-            Object hintHub = hints[i];
+            Word hintHub = hints[i];
             if (hintHub == objectHub) {
                 hintsHit.inc();
                 return trueValue;
@@ -132,9 +131,9 @@
         return trueValue;
     }
 
-    static boolean checkSecondarySubType(Object t, Object s) {
+    static boolean checkSecondarySubType(Word t, Word s) {
         // if (S.cache == T) return true
-        if (UnsafeLoadNode.loadObject(s, 0, secondarySuperCacheOffset(), true) == t) {
+        if (loadWordFromWord(s, secondarySuperCacheOffset()) == t) {
             cacheHit.inc();
             return true;
         }
@@ -146,10 +145,10 @@
         }
 
         // if (S.scan_s_s_array(T)) { S.cache = T; return true; }
-        Object[] secondarySupers = UnsafeCastNode.cast(UnsafeLoadNode.loadObject(s, 0, secondarySupersOffset(), true), Object[].class);
-
-        for (int i = 0; i < secondarySupers.length; i++) {
-            if (t == loadNonNullObjectElement(secondarySupers, i)) {
+        Word secondarySupers = loadWordFromWord(s, secondarySupersOffset());
+        int length = loadIntFromWord(secondarySupers, metaspaceArrayLengthOffset());
+        for (int i = 0; i < length; i++) {
+            if (t == loadWordElement(secondarySupers, i)) {
                 DirectObjectStoreNode.storeObject(s, secondarySuperCacheOffset(), 0, t);
                 secondariesHit.inc();
                 return true;
@@ -167,9 +166,9 @@
 
         public Templates(CodeCacheProvider runtime) {
             super(runtime, InstanceOfSnippets.class);
-            instanceofExact = snippet("instanceofExact", Object.class, Object.class, Object.class, Object.class, boolean.class);
-            instanceofPrimary = snippet("instanceofPrimary", Object.class, Object.class, Object.class, Object.class, boolean.class, int.class);
-            instanceofSecondary = snippet("instanceofSecondary", Object.class, Object.class, Object.class, Object.class, Object[].class, boolean.class);
+            instanceofExact = snippet("instanceofExact", Object.class, Word.class, Object.class, Object.class, boolean.class);
+            instanceofPrimary = snippet("instanceofPrimary", Word.class, Object.class, Object.class, Object.class, boolean.class, int.class);
+            instanceofSecondary = snippet("instanceofSecondary", Word.class, Object.class, Object.class, Object.class, Word[].class, boolean.class);
         }
 
         @Override
@@ -180,12 +179,12 @@
             ValueNode object = instanceOf.object();
             TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), instanceOf.profile(), tool.assumptions(), GraalOptions.InstanceOfMinHintHitProbability, GraalOptions.InstanceOfMaxHints);
             final HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) instanceOf.type();
-            ConstantNode hub = ConstantNode.forObject(type.klassOop(), runtime, instanceOf.graph());
+            ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, instanceOf.graph());
             boolean checkNull = !object.stamp().nonNull();
             Arguments arguments;
             Key key;
             if (hintInfo.exact) {
-                HotSpotKlassOop[] hints = createHints(hintInfo);
+                ConstantNode[] hints = createHints(hintInfo, runtime, hub.graph());
                 assert hints.length == 1;
                 key = new Key(instanceofExact).add("checkNull", checkNull);
                 arguments = arguments("object", object).add("exactHub", hints[0]).add("trueValue", trueValue).add("falseValue", falseValue);
@@ -193,8 +192,8 @@
                 key = new Key(instanceofPrimary).add("checkNull", checkNull).add("superCheckOffset", type.superCheckOffset());
                 arguments = arguments("hub", hub).add("object", object).add("trueValue", trueValue).add("falseValue", falseValue);
             } else {
-                HotSpotKlassOop[] hints = createHints(hintInfo);
-                key = new Key(instanceofSecondary).add("hints", vargargs(Object.class, hints.length)).add("checkNull", checkNull);
+                ConstantNode[] hints = createHints(hintInfo, runtime, hub.graph());
+                key = new Key(instanceofSecondary).add("hints", Varargs.vargargs(new Word[hints.length], StampFactory.forWord(wordKind(), true))).add("checkNull", checkNull);
                 arguments = arguments("hub", hub).add("object", object).add("hints", hints).add("trueValue", trueValue).add("falseValue", falseValue);
             }
             return new KeyAndArguments(key, arguments);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java	Wed Nov 14 11:28:02 2012 +0100
@@ -74,9 +74,13 @@
     public static final boolean CHECK_BALANCED_MONITORS = Boolean.getBoolean("graal.monitors.checkBalanced");
 
     @Snippet
-    public static void monitorenter(@Parameter("object") Object object, @ConstantParameter("trace") boolean trace) {
+    public static void monitorenter(@Parameter("object") Object object, @ConstantParameter("checkNull") boolean checkNull, @ConstantParameter("trace") boolean trace) {
         verifyOop(object);
 
+        if (checkNull && object == null) {
+            DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException);
+        }
+
         // Load the mark word - this includes a null-check on object
         final Word mark = loadWordFromObject(object, markOffset());
 
@@ -101,8 +105,8 @@
             } else {
                 // The bias pattern is present in the object's mark word. Need to check
                 // whether the bias owner and the epoch are both still current.
-                Object hub = loadHub(object);
-                final Word prototypeMarkWord = loadWordFromObject(hub, prototypeMarkWordOffset());
+                Word hub = loadHub(object);
+                final Word prototypeMarkWord = loadWordFromWord(hub, prototypeMarkWordOffset());
                 final Word thread = thread();
                 final Word tmp = prototypeMarkWord.or(thread).xor(mark).and(~ageMaskInPlace());
                 trace(trace, "prototypeMarkWord: 0x%016lx\n", prototypeMarkWord.toLong());
@@ -397,7 +401,7 @@
 
         public Templates(CodeCacheProvider runtime, boolean useFastLocking) {
             super(runtime, MonitorSnippets.class);
-            monitorenter = snippet("monitorenter", Object.class, boolean.class);
+            monitorenter = snippet("monitorenter", Object.class, boolean.class, boolean.class);
             monitorexit = snippet("monitorexit", Object.class, boolean.class);
             monitorenterStub = snippet("monitorenterStub", Object.class, boolean.class, boolean.class);
             monitorexitStub = snippet("monitorexitStub", Object.class, boolean.class);
@@ -418,7 +422,7 @@
             ResolvedJavaMethod method = eliminated ? monitorenterEliminated : useFastLocking ? monitorenter : monitorenterStub;
             boolean checkNull = !monitorenterNode.object().stamp().nonNull();
             Key key = new Key(method);
-            if (method == monitorenterStub) {
+            if (method != monitorenterEliminated) {
                 key.add("checkNull", checkNull);
             }
             if (!eliminated) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Wed Nov 14 11:28:02 2012 +0100
@@ -25,6 +25,7 @@
 import static com.oracle.graal.api.code.UnsignedMath.*;
 import static com.oracle.graal.hotspot.nodes.CastFromHub.*;
 import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
+import static com.oracle.graal.snippets.Snippet.Varargs.*;
 import static com.oracle.graal.snippets.SnippetTemplate.*;
 import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*;
 import static com.oracle.graal.snippets.nodes.DirectObjectStoreNode.*;
@@ -33,17 +34,16 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.snippets.*;
 import com.oracle.graal.snippets.Snippet.ConstantParameter;
 import com.oracle.graal.snippets.Snippet.Parameter;
-import com.oracle.graal.snippets.Snippet.Varargs;
 import com.oracle.graal.snippets.Snippet.VarargsParameter;
 import com.oracle.graal.snippets.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.snippets.SnippetTemplate.Arguments;
@@ -72,7 +72,7 @@
     @Snippet
     public static Object initializeObject(
                     @Parameter("memory") Word memory,
-                    @Parameter("hub") Object hub,
+                    @Parameter("hub") Word hub,
                     @Parameter("prototypeMarkWord") Word prototypeMarkWord,
                     @ConstantParameter("size") int size,
                     @ConstantParameter("fillContents") boolean fillContents,
@@ -94,7 +94,7 @@
     @Snippet
     public static Object initializeObjectArray(
                     @Parameter("memory") Word memory,
-                    @Parameter("hub") Object hub,
+                    @Parameter("hub") Word hub,
                     @Parameter("length") int length,
                     @Parameter("size") int size,
                     @Parameter("prototypeMarkWord") Word prototypeMarkWord,
@@ -111,7 +111,7 @@
     @Snippet
     public static Object initializePrimitiveArray(
                     @Parameter("memory") Word memory,
-                    @Parameter("hub") Object hub,
+                    @Parameter("hub") Word hub,
                     @Parameter("length") int length,
                     @Parameter("size") int size,
                     @Parameter("prototypeMarkWord") Word prototypeMarkWord,
@@ -125,7 +125,7 @@
         }
     }
 
-    private static Object initializeArray(Word memory, Object hub, int length, int size, Word prototypeMarkWord, int headerSize, boolean isObjectArray, boolean fillContents) {
+    private static Object initializeArray(Word memory, Word hub, int length, int size, Word prototypeMarkWord, int headerSize, boolean isObjectArray, boolean fillContents) {
         if (memory == Word.zero()) {
             if (isObjectArray) {
                 anewarray_stub.inc();
@@ -177,7 +177,7 @@
      */
     @Snippet
     public static Object newmultiarray(
-                    @Parameter("hub") Object hub,
+                    @Parameter("hub") Word hub,
                     @ConstantParameter("rank") int rank,
                     @VarargsParameter("dimensions") int[] dimensions) {
         Word dims = DimensionsNode.allocaDimsArray(rank, wordKind());
@@ -198,10 +198,10 @@
     /**
      * Formats some allocated memory with an object header zeroes out the rest.
      */
-    private static void formatObject(Object hub, int size, Word memory, Word compileTimePrototypeMarkWord, boolean fillContents) {
-        Word prototypeMarkWord = useBiasedLocking() ? loadWordFromObject(hub, prototypeMarkWordOffset()) : compileTimePrototypeMarkWord;
-        storeObject(memory, 0, markOffset(), prototypeMarkWord);
-        storeObject(memory, 0, hubOffset(), hub);
+    private static void formatObject(Word hub, int size, Word memory, Word compileTimePrototypeMarkWord, boolean fillContents) {
+        Word prototypeMarkWord = useBiasedLocking() ? loadWordFromWord(hub, prototypeMarkWordOffset()) : compileTimePrototypeMarkWord;
+        storeWord(memory, 0, markOffset(), prototypeMarkWord);
+        storeWord(memory, 0, hubOffset(), hub);
         if (fillContents) {
             if (size <= MAX_UNROLLED_OBJECT_ZEROING_SIZE) {
                 new_seqInit.inc();
@@ -221,9 +221,9 @@
     /**
      * Formats some allocated memory with an object header zeroes out the rest.
      */
-    private static void formatArray(Object hub, int size, int length, int headerSize, Word memory, Word prototypeMarkWord, boolean fillContents) {
-        storeObject(memory, 0, markOffset(), prototypeMarkWord);
-        storeObject(memory, 0, hubOffset(), hub);
+    private static void formatArray(Word hub, int size, int length, int headerSize, Word memory, Word prototypeMarkWord, boolean fillContents) {
+        storeWord(memory, 0, markOffset(), prototypeMarkWord);
+        storeWord(memory, 0, hubOffset(), hub);
         storeInt(memory, 0, arrayLengthOffset(), length);
         if (fillContents) {
             for (int offset = headerSize; offset < size; offset += wordSize()) {
@@ -248,11 +248,11 @@
             this.target = target;
             this.useTLAB = useTLAB;
             allocate = snippet("allocate", int.class);
-            initializeObject = snippet("initializeObject", Word.class, Object.class, Word.class, int.class, boolean.class, boolean.class);
-            initializeObjectArray = snippet("initializeObjectArray", Word.class, Object.class, int.class, int.class, Word.class, int.class, boolean.class, boolean.class);
-            initializePrimitiveArray = snippet("initializePrimitiveArray", Word.class, Object.class, int.class, int.class, Word.class, int.class, boolean.class, boolean.class);
+            initializeObject = snippet("initializeObject", Word.class, Word.class, Word.class, int.class, boolean.class, boolean.class);
+            initializeObjectArray = snippet("initializeObjectArray", Word.class, Word.class, int.class, int.class, Word.class, int.class, boolean.class, boolean.class);
+            initializePrimitiveArray = snippet("initializePrimitiveArray", Word.class, Word.class, int.class, int.class, Word.class, int.class, boolean.class, boolean.class);
             allocateArrayAndInitialize = snippet("allocateArrayAndInitialize", int.class, int.class, int.class, int.class, ResolvedJavaType.class, Kind.class);
-            newmultiarray = snippet("newmultiarray", Object.class, int.class, int[].class);
+            newmultiarray = snippet("newmultiarray", Word.class, int.class, int[].class);
         }
 
         /**
@@ -262,7 +262,7 @@
         public void lower(NewInstanceNode newInstanceNode, LoweringTool tool) {
             StructuredGraph graph = (StructuredGraph) newInstanceNode.graph();
             HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) newInstanceNode.instanceClass();
-            HotSpotKlassOop hub = type.klassOop();
+            ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph);
             int size = type.instanceSize();
             assert (size % wordSize()) == 0;
             assert size >= 0;
@@ -340,7 +340,7 @@
             StructuredGraph graph = (StructuredGraph) initializeNode.graph();
             HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) initializeNode.type();
             assert !type.isArrayClass();
-            HotSpotKlassOop hub = type.klassOop();
+            ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph);
             int size = type.instanceSize();
             assert (size % wordSize()) == 0;
             assert size >= 0;
@@ -358,7 +358,7 @@
             HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) initializeNode.type();
             ResolvedJavaType elementType = type.getComponentType();
             assert elementType != null;
-            HotSpotKlassOop hub = type.klassOop();
+            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());
@@ -378,8 +378,8 @@
                 dims[i] = newmultiarrayNode.dimension(i);
             }
             HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) newmultiarrayNode.type();
-            HotSpotKlassOop hub = type.klassOop();
-            Key key = new Key(newmultiarray).add("dimensions", Varargs.vargargs(int.class, rank)).add("rank", rank);
+            ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph);
+            Key key = new Key(newmultiarray).add("dimensions", vargargs(new int[rank], StampFactory.forKind(Kind.Int))).add("rank", rank);
             Arguments arguments = arguments("dimensions", dims).add("hub", hub);
             SnippetTemplate template = cache.get(key);
             template.instantiate(runtime, newmultiarrayNode, DEFAULT_REPLACER, arguments);
--- a/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/BytecodeInterpreter.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/BytecodeInterpreter.java	Wed Nov 14 11:28:02 2012 +0100
@@ -1633,7 +1633,7 @@
 
     private ResolvedJavaField findThrowableField(InterpreterFrame frame, String name) {
         ResolvedJavaType throwableType = resolveType(frame, Throwable.class);
-        ResolvedJavaField[] fields = throwableType.getDeclaredFields();
+        ResolvedJavaField[] fields = throwableType.getInstanceFields(false);
         for (int i = 0; i < fields.length; i++) {
             if (fields[i].getName().equals(name)) {
                 return fields[i];
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Nov 14 11:28:02 2012 +0100
@@ -951,7 +951,7 @@
             return;
         }
         // 1. check if the exact type of the receiver can be determined
-        ResolvedJavaType exact = klass.getExactType();
+        ResolvedJavaType exact = klass.asExactType();
         if (exact == null && receiver.objectStamp().isExactType()) {
             exact = receiver.objectStamp().type();
         }
@@ -1416,7 +1416,8 @@
             }
         }
 
-        if (initialized) {
+        ConstantNode typeInstruction = genTypeOrDeopt(Representation.ObjectHub, catchType, initialized);
+        if (typeInstruction != null) {
             Block nextBlock = block.successors.size() == 1 ? unwindBlock(block.deoptBci) : block.successors.get(1);
             ValueNode exception = frameState.stackAt(0);
             CheckCastNode checkCast = currentGraph.add(new CheckCastNode((ResolvedJavaType) catchType, exception, null));
@@ -1429,8 +1430,6 @@
             checkCast.setNext(catchSuccessor);
             IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new InstanceOfNode((ResolvedJavaType) catchType, exception, null)), checkCast, nextDispatch, 0.5, graphId));
             append(ifNode);
-        } else {
-            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Class_getModifiers01.java	Wed Nov 14 11:28:02 2012 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.jtt.lang;
+
+import java.io.*;
+
+import org.junit.*;
+
+@SuppressWarnings("static-method")
+public final class Class_getModifiers01 {
+
+    private static class PrivateStatic {}
+
+    private static final class PrivateStaticFinal {}
+
+    private static class Private {}
+
+    public static int test(Class c) {
+        return c.getModifiers();
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(Object.class.getModifiers(), test(Object.class));
+        Assert.assertEquals(Object[].class.getModifiers(), test(Object[].class));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(Serializable.class.getModifiers(), test(Serializable.class));
+        Assert.assertEquals(Serializable[].class.getModifiers(), test(Serializable[].class));
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(void.class.getModifiers(), test(void.class));
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        Assert.assertEquals(int.class.getModifiers(), test(int.class));
+        Assert.assertEquals(int[].class.getModifiers(), test(int[].class));
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertEquals(Private.class.getModifiers(), test(Private.class));
+        Assert.assertEquals(Private[].class.getModifiers(), test(Private[].class));
+    }
+
+    @Test
+    public void run5() throws Throwable {
+        Assert.assertEquals(PrivateStatic.class.getModifiers(), test(PrivateStatic.class));
+        Assert.assertEquals(PrivateStatic[].class.getModifiers(), test(PrivateStatic[].class));
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        Assert.assertEquals(PrivateStaticFinal.class.getModifiers(), test(PrivateStaticFinal.class));
+        Assert.assertEquals(PrivateStaticFinal[].class.getModifiers(), test(PrivateStaticFinal[].class));
+    }
+}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Wed Nov 14 11:28:02 2012 +0100
@@ -158,6 +158,12 @@
                     masm.cmpl(intKey, tasm.asIntConst(keyConstants[i]));
                     masm.jcc(ConditionFlag.equal, keyTargets[i].label());
                 }
+            } else if (key.getKind() == Kind.Long) {
+                Register longKey = asLongReg(key);
+                for (int i = 0; i < keyConstants.length; i++) {
+                    masm.cmpq(longKey, tasm.asLongConstRef(keyConstants[i]));
+                    masm.jcc(ConditionFlag.equal, keyTargets[i].label());
+                }
             } else if (key.getKind() == Kind.Object) {
                 Register intKey = asObjectReg(key);
                 Register temp = asObjectReg(scratch);
@@ -167,7 +173,7 @@
                     masm.jcc(ConditionFlag.equal, keyTargets[i].label());
                 }
             } else {
-                throw new GraalInternalError("sequential switch only supported for int and object");
+                throw new GraalInternalError("sequential switch only supported for int, long and object");
             }
             if (defaultTarget != null) {
                 masm.jmp(defaultTarget.label());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MaterializeNode.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MaterializeNode.java	Wed Nov 14 11:28:02 2012 +0100
@@ -22,36 +22,13 @@
  */
 package com.oracle.graal.nodes;
 
+import static com.oracle.graal.nodes.calc.CompareNode.*;
+
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.calc.*;
 
 public final class MaterializeNode extends ConditionalNode {
 
-    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().isFloatOrDouble();
-        CompareNode comparison;
-        if (condition == Condition.EQ) {
-            if (x.kind().isObject()) {
-                comparison = new ObjectEqualsNode(x, y);
-            } else {
-                assert x.kind().getStackKind().isStackInt() || x.kind().isLong();
-                comparison = new IntegerEqualsNode(x, y);
-            }
-        } else if (condition == Condition.LT) {
-            assert x.kind().getStackKind().isStackInt() || x.kind().isLong();
-            comparison = new IntegerLessThanNode(x, y);
-        } else {
-            assert condition == Condition.BT;
-            assert x.kind().getStackKind().isStackInt() || x.kind().isLong();
-            comparison = new IntegerBelowThanNode(x, y);
-        }
-
-        return x.graph().unique(comparison);
-    }
-
     private MaterializeNode(Condition condition, ValueNode x, ValueNode y) {
         this(createCompareNode(condition, x, y), ConstantNode.forInt(1, x.graph()), ConstantNode.forInt(0, x.graph()));
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Wed Nov 14 11:28:02 2012 +0100
@@ -102,7 +102,7 @@
     }
 
     public Kind kind() {
-        return stamp.kind();
+        return stamp().kind();
     }
 
     /**
@@ -147,9 +147,9 @@
     }
 
     public <T extends Stamp> boolean verifyStamp(Class<T> stampClass) {
-        assert stamp != null;
-        assert stampClass.isInstance(stamp) : this + " (" + GraphUtil.approxSourceLocation(this) + ") has unexpected stamp type: expected " + stampClass.getName() +
-            ", got " + stamp.getClass().getName();
+        assert stamp() != null;
+        assert stampClass.isInstance(stamp()) : this + " (" + GraphUtil.approxSourceLocation(this) + ") has unexpected stamp type: expected " + stampClass.getName() +
+            ", got " + stamp().getClass().getName() + ", usages=" + usages();
         return true;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Wed Nov 14 11:28:02 2012 +0100
@@ -127,4 +127,29 @@
         }
         return this;
     }
+
+    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().isFloatOrDouble();
+        CompareNode comparison;
+        if (condition == Condition.EQ) {
+            if (x.kind().isObject()) {
+                comparison = new ObjectEqualsNode(x, y);
+            } else {
+                assert x.kind().getStackKind().isStackInt() || x.kind().isLong();
+                comparison = new IntegerEqualsNode(x, y);
+            }
+        } else if (condition == Condition.LT) {
+            assert x.kind().getStackKind().isStackInt() || x.kind().isLong();
+            comparison = new IntegerLessThanNode(x, y);
+        } else {
+            assert condition == Condition.BT;
+            assert x.kind().getStackKind().isStackInt() || x.kind().isLong();
+            comparison = new IntegerBelowThanNode(x, y);
+        }
+
+        return x.graph().unique(comparison);
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java	Wed Nov 14 11:28:02 2012 +0100
@@ -87,7 +87,7 @@
         specialMethods.add(unboxingMethod);
 
         // Get the field that contains the boxed value.
-        ResolvedJavaField[] fields = runtime.lookupJavaType(type).getDeclaredFields();
+        ResolvedJavaField[] fields = runtime.lookupJavaType(type).getInstanceFields(false);
         ResolvedJavaField boxField = fields[0];
         assert fields.length == 1 && boxField.getKind() == kind;
         boxFields[kind.ordinal()] = boxField;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Wed Nov 14 11:28:02 2012 +0100
@@ -33,7 +33,7 @@
  * A floating read of a value from memory specified in terms of an object base and an object relative location.
  * This node does not null check the object.
  */
-public final class FloatingReadNode extends FloatingAccessNode implements Node.IterableNodeType, LIRLowerable/*, Canonicalizable*/ {
+public final class FloatingReadNode extends FloatingAccessNode implements Node.IterableNodeType, LIRLowerable, Canonicalizable {
 
     @Input private Node lastLocationAccess;
 
@@ -56,9 +56,8 @@
         gen.setResult(this, gen.emitLoad(gen.makeAddress(location(), object()), getNullCheck()));
     }
 
-    // Canonicalization disabled untill we have a solution for non-Object oops in Hotspot
-    /*@Override
+    @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         return ReadNode.canonicalizeRead(this, tool);
-    }*/
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Wed Nov 14 11:28:02 2012 +0100
@@ -39,8 +39,8 @@
         return object;
     }
 
-    public LoadHubNode(ValueNode object) {
-        super(StampFactory.objectNonNull());
+    public LoadHubNode(ValueNode object, Kind kind) {
+        super(StampFactory.forKind(kind));
         this.object = object;
     }
 
@@ -74,9 +74,6 @@
         return this;
     }
 
-    @NodeIntrinsic
-    public static native Object loadHub(Object object);
-
     @Override
     public void virtualize(VirtualizerTool tool) {
         VirtualObjectNode virtual = tool.getVirtualState(object());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Wed Nov 14 11:28:02 2012 +0100
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -32,7 +31,7 @@
 /**
  * Reads an {@linkplain AccessNode accessed} value.
  */
-public final class ReadNode extends AccessNode implements Node.IterableNodeType, LIRLowerable, Simplifiable/*, Canonicalizable*/ {
+public final class ReadNode extends AccessNode implements Node.IterableNodeType, LIRLowerable, Canonicalizable {
 
     public ReadNode(ValueNode object, ValueNode location, Stamp stamp) {
         super(object, location, stamp);
@@ -43,41 +42,30 @@
         gen.setResult(this, gen.emitLoad(gen.makeAddress(location(), object()), getNullCheck()));
     }
 
-    // Canonicalization disabled until we have a solution for non-Object oops in Hotspot
-    /*@Override
+    @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         return canonicalizeRead(this, tool);
-    }*/
+    }
 
     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) {
             if (read.location().locationIdentity() == LocationNode.FINAL_LOCATION && read.location().getClass() == LocationNode.class) {
                 Object value = read.object().asConstant().asObject();
-                long displacement = read.location().displacement();
-                Kind kind = read.location().getValueKind();
-                Constant constant = kind.readUnsafeConstant(value, displacement);
-                if (constant != null) {
-                    System.out.println("Canon read to " + constant);
-                    return ConstantNode.forConstant(constant, runtime, read.node().graph());
+                if (value != null) {
+                    long displacement = read.location().displacement();
+                    Kind kind = read.location().getValueKind();
+                    Constant constant = kind.readUnsafeConstant(value, displacement);
+                    if (constant != null) {
+                        System.out.println("Canonicalizd " + read + " to " + constant);
+                        return ConstantNode.forConstant(constant, runtime, read.node().graph());
+                    }
                 }
             }
         }
         return (ValueNode) read;
     }
 
-    @Override
-    public void simplify(SimplifierTool tool) {
-        if (object().isConstant() && object().asConstant().isNull()) {
-            FixedNode successor = next();
-            tool.deleteBranch(successor);
-            if (isAlive()) {
-                replaceAtPredecessor(graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException)));
-                safeDelete();
-            }
-        }
-    }
-
     private ReadNode(ValueNode object, ValueNode location) {
         this(object, location, StampFactory.forNodeIntrinsic());
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Wed Nov 14 11:28:02 2012 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -32,7 +30,7 @@
 /**
  * Writes a given {@linkplain #value() value} a {@linkplain AccessNode memory location}.
  */
-public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable, Simplifiable {
+public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable {
     @Input private ValueNode value;
     @Input(notDataflow = true) private FrameState stateAfter;
 
@@ -64,18 +62,6 @@
         gen.emitStore(gen.makeAddress(location(), object()), gen.operand(value()), getNullCheck());
     }
 
-    @Override
-    public void simplify(SimplifierTool tool) {
-        if (object().isConstant() && object().asConstant().isNull()) {
-            FixedNode successor = next();
-            tool.deleteBranch(successor);
-            if (isAlive()) {
-                replaceAtPredecessor(graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException)));
-                safeDelete();
-            }
-        }
-    }
-
     @NodeIntrinsic
     public static native void writeMemory(Object object, Object value, Object location);
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java	Wed Nov 14 11:28:02 2012 +0100
@@ -86,7 +86,7 @@
     private void fillEscapeFields(ResolvedJavaType type, List<ResolvedJavaField> escapeFields) {
         if (type != null) {
             fillEscapeFields(type.getSuperclass(), escapeFields);
-            for (ResolvedJavaField field : type.getDeclaredFields()) {
+            for (ResolvedJavaField field : type.getInstanceFields(true)) {
                 escapeFields.add(field);
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java	Wed Nov 14 11:28:02 2012 +0100
@@ -81,7 +81,7 @@
             for (int i = 0; i < keyCount(); i++) {
                 Constant typeHub = keyAt(i);
                 assert constant.getKind() == typeHub.getKind();
-                if (tool.runtime().constantEquals(value().asConstant(), typeHub)) {
+                if (tool.runtime().constantEquals(constant, typeHub)) {
                     survivingEdge = keySuccessorIndex(i);
                 }
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Wed Nov 14 11:28:02 2012 +0100
@@ -171,7 +171,7 @@
     public static Stamp declared(ResolvedJavaType type, boolean nonNull) {
         assert type != null;
         assert type.getKind() == Kind.Object;
-        ResolvedJavaType exact = type.getExactType();
+        ResolvedJavaType exact = type.asExactType();
         if (exact != null) {
             return new ObjectStamp(exact, true, nonNull, false);
         } else {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/WordStamp.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/WordStamp.java	Wed Nov 14 11:28:02 2012 +0100
@@ -27,7 +27,7 @@
 /**
  * Models the word type.
  */
-public class WordStamp extends Stamp {
+public class WordStamp extends IntegerStamp {
 
     private final boolean nonNull;
 
@@ -56,6 +56,11 @@
 
     @Override
     public Stamp meet(Stamp otherStamp) {
+        if (otherStamp.getClass() == IntegerStamp.class) {
+            IntegerStamp istamp = (IntegerStamp) otherStamp;
+            assert istamp.lowerBound() == istamp.upperBound() : "expected a word constant";
+            return istamp;
+        }
         WordStamp other = (WordStamp) otherStamp;
         boolean meetNonNull = nonNull && other.nonNull;
         if (meetNonNull == this.nonNull) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Wed Nov 14 11:28:02 2012 +0100
@@ -189,9 +189,9 @@
             // receiver null check must be before the type check
             InliningUtil.receiverNullCheck(invoke);
             ValueNode receiver = invoke.methodCallTarget().receiver();
-            LoadHubNode receiverHub = graph.add(new LoadHubNode(receiver));
             ConstantNode typeHub = ConstantNode.forConstant(type.getEncoding(Representation.ObjectHub), runtime, graph);
-            ObjectEqualsNode typeCheck = graph.unique(new ObjectEqualsNode(receiverHub, typeHub));
+            LoadHubNode receiverHub = graph.add(new LoadHubNode(receiver, typeHub.kind()));
+            CompareNode typeCheck = CompareNode.createCompareNode(Condition.EQ, receiverHub, typeHub);
             FixedGuardNode guard = graph.add(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile, invoke.leafGraphId()));
             ValueAnchorNode anchor = graph.add(new ValueAnchorNode());
             assert invoke.predecessor() != null;
@@ -333,7 +333,8 @@
             }
 
             // replace the invoke with a switch on the type of the actual receiver
-            LoadHubNode receiverHub = graph.add(new LoadHubNode(invoke.methodCallTarget().receiver()));
+            Kind hubKind = invoke.methodCallTarget().targetMethod().getDeclaringClass().getEncoding(Representation.ObjectHub).getKind();
+            LoadHubNode receiverHub = graph.add(new LoadHubNode(invoke.methodCallTarget().receiver(), hubKind));
             graph.addBeforeFixed(invoke.node(), receiverHub);
             FixedNode dispatchOnType = createDispatchOnType(graph, receiverHub, calleeEntryNodes, unknownTypeNode);
 
@@ -419,7 +420,8 @@
 
             MergeNode calleeEntryNode = graph.add(new MergeNode());
             calleeEntryNode.setProbability(invoke.probability());
-            LoadHubNode receiverHub = graph.add(new LoadHubNode(invoke.methodCallTarget().receiver()));
+            Kind hubKind = invoke.methodCallTarget().targetMethod().getDeclaringClass().getEncoding(Representation.ObjectHub).getKind();
+            LoadHubNode receiverHub = graph.add(new LoadHubNode(invoke.methodCallTarget().receiver(), hubKind));
             graph.addBeforeFixed(invoke.node(), receiverHub);
 
             FixedNode unknownTypeNode = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated, invoke.leafGraphId()));
@@ -436,7 +438,7 @@
             InliningUtil.inline(invoke, calleeGraph, false);
         }
 
-        private FixedNode createDispatchOnType(StructuredGraph graph, LoadHubNode objectClassNode, BeginNode[] calleeEntryNodes, FixedNode unknownTypeSux) {
+        private FixedNode createDispatchOnType(StructuredGraph graph, LoadHubNode hub, BeginNode[] calleeEntryNodes, FixedNode unknownTypeSux) {
             assert ptypes.length > 1;
 
             ResolvedJavaType[] types = new ResolvedJavaType[ptypes.length];
@@ -460,7 +462,7 @@
             probabilities[successors.length - 1] = notRecordedTypeProbability;
             keySuccessors[successors.length - 1] = successors.length - 1;
 
-            TypeSwitchNode typeSwitch = graph.add(new TypeSwitchNode(objectClassNode, successors, probabilities, types, probabilities, keySuccessors));
+            TypeSwitchNode typeSwitch = graph.add(new TypeSwitchNode(hub, successors, probabilities, types, probabilities, keySuccessors));
 
             return typeSwitch;
         }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Wed Nov 14 11:28:02 2012 +0100
@@ -67,7 +67,7 @@
     public static float   ProbabilityCapForInlining          = 1f;
 
     // escape analysis settings
-    public static boolean PartialEscapeAnalysis              = true;
+    public static boolean PartialEscapeAnalysis              = false;
     public static boolean EscapeAnalysisHistogram            = ____;
     public static int     EscapeAnalysisIterations           = 2;
     public static String  EscapeAnalyzeOnly                  = null;
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/InstanceOfSnippetsTemplates.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/InstanceOfSnippetsTemplates.java	Wed Nov 14 11:28:02 2012 +0100
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.snippets;
 
-import static com.oracle.graal.nodes.MaterializeNode.*;
+import static com.oracle.graal.nodes.calc.CompareNode.*;
 
 import java.util.*;
 
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java	Wed Nov 14 11:28:02 2012 +0100
@@ -28,6 +28,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.snippets.Word.Operation;
 import com.oracle.graal.snippets.nodes.*;
 
@@ -157,40 +158,50 @@
      * Wrapper for the prototype value of a {@linkplain VarargsParameter varargs} parameter.
      */
     public static class Varargs {
-        public final Object array;
-        private final Class componentType;
+        private final Object args;
+        private final Class argType;
         private final int length;
+        private final Stamp argStamp;
 
-        public static Varargs vargargs(Class componentType, int length) {
-            return new Varargs(Array.newInstance(componentType, length));
+        public static Varargs vargargs(Object array, Stamp argStamp) {
+            return new Varargs(array, argStamp);
         }
 
-        public Varargs(Object array) {
+        public Varargs(Object array, Stamp argStamp) {
             assert array != null;
-            this.componentType = array.getClass().getComponentType();
-            assert this.componentType != null;
+            this.argType = array.getClass().getComponentType();
+            this.argStamp = argStamp;
+            assert this.argType != null;
             this.length = java.lang.reflect.Array.getLength(array);
-            this.array = array;
+            this.args = array;
         }
 
         @Override
         public boolean equals(Object obj) {
             if (obj instanceof Varargs) {
                 Varargs other = (Varargs) obj;
-                return other.componentType == componentType &&
+                return other.argType == argType &&
                         other.length == length;
             }
             return false;
         }
 
+        public Object getArray() {
+            return args;
+        }
+
+        public Stamp getArgStamp() {
+            return argStamp;
+        }
+
         @Override
         public int hashCode() {
-            return componentType.hashCode() ^ length;
+            return argType.hashCode() ^ length;
         }
 
         @Override
         public String toString() {
-            return componentType.getName() + "[" + length + "]";
+            return argType.getName() + "[" + length + "]";
         }
     }
 }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetCounter.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetCounter.java	Wed Nov 14 11:28:02 2012 +0100
@@ -24,11 +24,11 @@
 
 //JaCoCo Exclude
 
+import static com.oracle.graal.graph.FieldIntrospection.*;
+
 import java.io.*;
 import java.util.*;
 
-import sun.misc.*;
-
 import com.oracle.graal.graph.*;
 import com.oracle.graal.snippets.Snippet.Fold;
 import com.oracle.graal.snippets.nodes.*;
@@ -96,7 +96,7 @@
     @Fold
     private static int countOffset() {
         try {
-            return (int) Unsafe.getUnsafe().objectFieldOffset(SnippetCounter.class.getDeclaredField("value"));
+            return (int) unsafe.objectFieldOffset(SnippetCounter.class.getDeclaredField("value"));
         } catch (Exception e) {
             throw new GraalInternalError(e);
         }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Wed Nov 14 11:28:02 2012 +0100
@@ -242,7 +242,8 @@
                 VarargsParameter vp = MetaUtil.getParameterAnnotation(VarargsParameter.class, i, method);
                 if (vp != null) {
                     String name = vp.value();
-                    Object array = ((Varargs) key.get(name)).array;
+                    Varargs varargs = (Varargs) key.get(name);
+                    Object array = varargs.getArray();
                     ConstantNode placeholder = ConstantNode.forObject(array, runtime, snippetCopy);
                     replacements.put(snippetGraph.getLocal(i), placeholder);
                     placeholders[i] = placeholder;
@@ -268,10 +269,11 @@
             VarargsParameter vp = varargsParameterAnnotations[i];
             if (vp != null) {
                 assert snippetCopy.getLocal(i) == null;
-                Object array = ((Varargs) key.get(vp.value())).array;
+                Varargs varargs = (Varargs) key.get(vp.value());
+                Object array = varargs.getArray();
                 int length = Array.getLength(array);
                 LocalNode[] locals = new LocalNode[length];
-                Stamp stamp = StampFactory.forKind(runtime.lookupJavaType(array.getClass().getComponentType()).getKind());
+                Stamp stamp = varargs.getArgStamp();
                 for (int j = 0; j < length; j++) {
                     assert (parameterCount & 0xFFFF) == parameterCount;
                     int idx = i << 16 | j;
@@ -394,7 +396,7 @@
     }
 
     private static boolean checkVarargs(final ResolvedJavaMethod method, Signature signature, int i, String name, Varargs varargs) {
-        Object arg = varargs.array;
+        Object arg = varargs.getArray();
         ResolvedJavaType type = (ResolvedJavaType) signature.getParameterType(i, method.getDeclaringClass());
         Class< ? > javaType = type.toJava();
         assert javaType.isArray() : "varargs parameter must be an array type";
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java	Wed Nov 14 11:28:02 2012 +0100
@@ -91,7 +91,7 @@
                 } else if (usage instanceof ObjectEqualsNode) {
                     ObjectEqualsNode compare = (ObjectEqualsNode) usage;
                     if (compare.x() == node || compare.y() == node) {
-                        verify(isWord(compare.x()) == isWord(compare.y()), node, compare.usages().first(), "cannot mixed word and now-word type in use of '==' or '!='");
+                        verify(isWord(compare.x()) == isWord(compare.y()), node, compare.usages().first(), "cannot mixed word and non-word type in use of '==' or '!='");
                     }
                 } else if (usage instanceof ArrayLengthNode) {
                     verify(!isWord(node) || ((ArrayLengthNode) usage).array() != node, node, usage, "cannot get array length from word value");
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java	Mon Nov 12 23:37:12 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java	Wed Nov 14 11:28:02 2012 +0100
@@ -80,6 +80,13 @@
             }
         }
 
+        // Replace ObjectEqualsNodes with IntegerEqualsNodes where the values being compared are words
+        for (LoadIndexedNode load : graph.getNodes().filter(LoadIndexedNode.class).snapshot()) {
+            if (isWord(load)) {
+                load.setStamp(StampFactory.forWord(wordKind, false));
+            }
+        }
+
         for (MethodCallTargetNode callTargetNode : graph.getNodes(MethodCallTargetNode.class).snapshot()) {
             ResolvedJavaMethod targetMethod = callTargetNode.targetMethod();
             Operation operation = targetMethod.getAnnotation(Word.Operation.class);
@@ -287,6 +294,9 @@
         if (node.stamp() instanceof WordStamp) {
             return true;
         }
+        if (node instanceof LoadIndexedNode) {
+            return isWord(((LoadIndexedNode) node).array().objectStamp().type().getComponentType());
+        }
         if (node.kind().isObject()) {
             return isWord(node.objectStamp().type());
         }
--- a/src/share/vm/classfile/systemDictionary.hpp	Mon Nov 12 23:37:12 2012 +0100
+++ b/src/share/vm/classfile/systemDictionary.hpp	Wed Nov 14 11:28:02 2012 +0100
@@ -184,10 +184,9 @@
   /* Support for Graal */                                                                                                \
   do_klass(GraalBitMap_klass,                     java_util_BitSet,                                             Opt) \
   /* graal.hotspot */                                                                                                \
-  do_klass(HotSpotKlassOop_klass,                 com_oracle_graal_hotspot_HotSpotKlassOop,                     Opt) \
   do_klass(HotSpotCompilationResult_klass,        com_oracle_graal_hotspot_HotSpotCompilationResult,            Opt) \
   do_klass(HotSpotCodeInfo_klass,                 com_oracle_graal_hotspot_meta_HotSpotCodeInfo,                Opt) \
-  do_klass(HotSpotInstalledCode_klass,            com_oracle_graal_hotspot_meta_HotSpotInstalledCode,          Opt) \
+  do_klass(HotSpotInstalledCode_klass,            com_oracle_graal_hotspot_meta_HotSpotInstalledCode,           Opt) \
   do_klass(HotSpotJavaType_klass,                 com_oracle_graal_hotspot_meta_HotSpotJavaType,                Opt) \
   do_klass(HotSpotMethodData_klass,               com_oracle_graal_hotspot_meta_HotSpotMethodData,              Opt) \
   do_klass(HotSpotResolvedJavaField_klass,        com_oracle_graal_hotspot_meta_HotSpotResolvedJavaField,       Opt) \
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Mon Nov 12 23:37:12 2012 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Wed Nov 14 11:28:02 2012 +0100
@@ -275,6 +275,7 @@
   GraalCompiler::initialize_buffer_blob();
   CodeBuffer buffer(JavaThread::current()->get_buffer_blob());
   jobject comp_result_obj = JNIHandles::make_local(comp_result());
+  jint entry_bci = HotSpotCompilationResult::entryBCI(comp_result);
   initialize_assumptions(JNIHandles::resolve(comp_result_obj));
 
   {
@@ -286,7 +287,7 @@
 
   int stack_slots = _total_frame_size / HeapWordSize; // conversion to words
 
-  nm = GraalEnv::register_method(method, -1, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
+  nm = GraalEnv::register_method(method, entry_bci, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
     &_implicit_exception_table, GraalCompiler::instance(), _debug_recorder, _dependencies, NULL, -1, true, false, bind_to_method);
 
   method->clear_queued_for_compilation();
--- a/src/share/vm/graal/graalCompiler.cpp	Mon Nov 12 23:37:12 2012 +0100
+++ b/src/share/vm/graal/graalCompiler.cpp	Wed Nov 14 11:28:02 2012 +0100
@@ -241,12 +241,17 @@
   }
 }
 
-Handle GraalCompiler::get_JavaTypeFromClass(Handle javaClassHandle, TRAPS) {
-  if (java_lang_Class::is_primitive(javaClassHandle())) {
-    BasicType basicType = java_lang_Class::primitive_type(javaClassHandle());
+Handle GraalCompiler::get_JavaTypeFromClass(Handle java_class, TRAPS) {
+  oop graal_mirror = java_lang_Class::graal_mirror(java_class());
+  if (graal_mirror != NULL) {
+    return graal_mirror;
+  }
+
+  if (java_lang_Class::is_primitive(java_class())) {
+    BasicType basicType = java_lang_Class::primitive_type(java_class());
     return VMToCompiler::createPrimitiveJavaType((int) basicType, THREAD);
   } else {
-    KlassHandle klass = java_lang_Class::as_Klass(javaClassHandle());
+    KlassHandle klass = java_lang_Class::as_Klass(java_class());
     Handle name = java_lang_String::create_from_symbol(klass->name(), CHECK_NULL);
     return GraalCompiler::createHotSpotResolvedJavaType(klass, name, CHECK_NULL);
   }
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Mon Nov 12 23:37:12 2012 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Wed Nov 14 11:28:02 2012 +0100
@@ -252,7 +252,11 @@
   HotSpotResolvedJavaMethod::set_name(hotspot_method, name());
   HotSpotResolvedJavaMethod::set_codeSize(hotspot_method, method->code_size());
   HotSpotResolvedJavaMethod::set_exceptionHandlerCount(hotspot_method, method->exception_table_length());
-  HotSpotResolvedJavaMethod::set_canBeInlined(hotspot_method, !method->is_not_compilable() && !CompilerOracle::should_not_inline(method));
+C2V_END
+
+C2V_VMENTRY(jboolean, isMethodCompilable,(JNIEnv *, jobject, jlong metaspace_method))
+  methodHandle method = asMethod(metaspace_method);
+  return !method->is_not_compilable() && !CompilerOracle::should_not_inline(method);
 C2V_END
 
 C2V_VMENTRY(void, initializeMethodData,(JNIEnv *, jobject, jlong metaspace_method_data, jobject hotspot_method_data))
@@ -535,19 +539,6 @@
   return JNIHandles::make_local(GraalCompiler::get_JavaType(lca, THREAD)());
 C2V_END
 
-C2V_VMENTRY(jobject, getComponentType, (JNIEnv *, jobject, jobject klass))
-  KlassHandle array_klass = java_lang_Class::as_Klass(HotSpotResolvedJavaType::javaMirror(klass));
-  if(array_klass->oop_is_typeArray()) {
-    BasicType t = TypeArrayKlass::cast(array_klass())->element_type();
-    oop primitive_type = VMToCompiler::createPrimitiveJavaType((int) t, CHECK_NULL);
-    return JNIHandles::make_local(primitive_type);
-  }
-  assert(array_klass->oop_is_objArray(), "just checking");
-  Klass* element_type = ObjArrayKlass::cast(array_klass())->element_klass();
-  assert(JNIHandles::resolve(klass) != NULL, "");
-  return JNIHandles::make_local(GraalCompiler::get_JavaType(element_type, THREAD)());
-C2V_END
-
 C2V_VMENTRY(jlong, getPrototypeMarkWord, (JNIEnv *, jobject, jobject klass))
   KlassHandle klass_handle(java_lang_Class::as_Klass(HotSpotResolvedJavaType::javaMirror(klass)));
   if (klass_handle->oop_is_array()) {
@@ -557,24 +548,6 @@
   }
 C2V_END
 
-C2V_VMENTRY(jobject, getSuperType, (JNIEnv *, jobject, jlong metaspace_klass))
-  KlassHandle klass_handle(asKlass(metaspace_klass));
-  Klass* k;
-
-  if (klass_handle->oop_is_array()) {
-    k = SystemDictionary::Object_klass();
-  } else {
-    guarantee(klass_handle->oop_is_instance(), "must be instance klass");  
-    k = klass_handle->super();
-  }
-
-  if (k != NULL) {
-    return JNIHandles::make_local(GraalCompiler::get_JavaType(k, THREAD)());
-  } else {
-    return NULL;
-  }
-C2V_END
-
 C2V_VMENTRY(jobject, getUniqueConcreteSubtype, (JNIEnv *, jobject, jobject klass))
   KlassHandle klass_handle(java_lang_Class::as_Klass(HotSpotResolvedJavaType::javaMirror(klass)));
   Klass *up_cast = klass_handle->up_cast_abstract();
@@ -596,14 +569,6 @@
   InstanceKlass::cast(klass)->initialize(JavaThread::current());
 C2V_END
 
-C2V_VMENTRY(jobject, getArrayOf, (JNIEnv *, jobject, jobject klass))
-  KlassHandle klass_handle(java_lang_Class::as_Klass(HotSpotResolvedJavaType::javaMirror(klass)));
-  KlassHandle arr = klass_handle->array_klass(THREAD);
-  Handle name = VmIds::toString<Handle>(arr->name(), CHECK_NULL);
-  assert(arr->oop_is_array(), "");
-  return JNIHandles::make_local(THREAD, GraalCompiler::createHotSpotResolvedJavaType(arr, name, THREAD)());
-C2V_END
-
 C2V_VMENTRY(jobject, getInstanceFields, (JNIEnv *, jobject, jobject klass))
   ResourceMark rm;
 
@@ -627,13 +592,6 @@
   return JNIHandles::make_local(field_array());
 C2V_END
 
-C2V_VMENTRY(jobject, getPrimitiveArrayType, (JNIEnv *env, jobject, jobject kind))
-  BasicType type = GraalCompiler::kindToBasicType(Kind::typeChar(kind));
-  assert(type != T_OBJECT, "primitive type expecteds");
-  Handle result = GraalCompiler::get_JavaType(Universe::typeArrayKlassObj(type), CHECK_NULL);
-  return JNIHandles::make_local(THREAD, result());
-C2V_END
-
 C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv *env, jobject, jlong stub))
   address target_addr = (address) stub;
   if (target_addr != 0x0) {
@@ -644,13 +602,10 @@
   return -1;
 C2V_END
 
-C2V_VMENTRY(jobject, getType, (JNIEnv *env, jobject, jobject javaClass))
-  oop javaClassOop = JNIHandles::resolve(javaClass);
-  if (javaClassOop == NULL) {
-    fatal("argument to CompilerToVM.getType must not be NULL");
-    return NULL;
-  }
-  Handle type = GraalCompiler::get_JavaTypeFromClass(javaClassOop, CHECK_NULL);
+C2V_VMENTRY(jobject, getResolvedType, (JNIEnv *env, jobject, jobject javaClass))
+  oop java_mirror = JNIHandles::resolve(javaClass);
+  assert(java_mirror != NULL, "argument to CompilerToVM.getResolvedType must not be NULL");
+  Handle type = GraalCompiler::get_JavaTypeFromClass(java_mirror, CHECK_NULL);
   return JNIHandles::make_local(THREAD, type());
 C2V_END
 
@@ -973,75 +928,73 @@
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
 
+#define RESOLVED_TYPE         "Lcom/oracle/graal/api/meta/ResolvedJavaType;"
 #define TYPE                  "Lcom/oracle/graal/api/meta/JavaType;"
-#define RESOLVED_TYPE         "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaType;"
 #define METHOD                "Lcom/oracle/graal/api/meta/JavaMethod;"
-#define RESOLVED_METHOD       "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;"
-#define REFLECT_METHOD        "Ljava/lang/reflect/Method;"
-#define SIGNATURE             "Lcom/oracle/graal/api/meta/Signature;"
 #define FIELD                 "Lcom/oracle/graal/api/meta/JavaField;"
-#define RESOLVED_FIELD        "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaField;"
-#define REFLECT_FIELD         "Ljava/lang/reflect/Field;"
+#define SIGNATURE             "Lcom/oracle/graal/api/meta/Signature;"
 #define CONSTANT_POOL         "Lcom/oracle/graal/api/meta/ConstantPool;"
+#define CONSTANT              "Lcom/oracle/graal/api/meta/Constant;"
+#define KIND                  "Lcom/oracle/graal/api/meta/Kind;"
+#define RUNTIME_CALL          "Lcom/oracle/graal/api/code/RuntimeCall;"
 #define EXCEPTION_HANDLERS    "[Lcom/oracle/graal/api/meta/ExceptionHandler;"
+#define REFLECT_METHOD        "Ljava/lang/reflect/Method;"
+#define REFLECT_FIELD         "Ljava/lang/reflect/Field;"
+#define STRING                "Ljava/lang/String;"
+#define OBJECT                "Ljava/lang/Object;"
+#define CLASS                 "Ljava/lang/Class;"
+#define STACK_TRACE_ELEMENT   "Ljava/lang/StackTraceElement;"
+#define HS_RESOLVED_TYPE      "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaType;"
+#define HS_RESOLVED_METHOD    "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;"
+#define HS_RESOLVED_FIELD     "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaField;"
 #define HS_COMP_RESULT        "Lcom/oracle/graal/hotspot/HotSpotCompilationResult;"
-#define CONFIG                "Lcom/oracle/graal/hotspot/HotSpotVMConfig;"
+#define HS_CONFIG             "Lcom/oracle/graal/hotspot/HotSpotVMConfig;"
 #define HS_METHOD             "Lcom/oracle/graal/hotspot/meta/HotSpotMethod;"
 #define HS_INSTALLED_CODE     "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;"
 #define HS_CODE_INFO          "Lcom/oracle/graal/hotspot/meta/HotSpotCodeInfo;"
 #define METHOD_DATA           "Lcom/oracle/graal/hotspot/meta/HotSpotMethodData;"
-#define CONSTANT              "Lcom/oracle/graal/api/meta/Constant;"
-#define KIND                  "Lcom/oracle/graal/api/meta/Kind;"
-#define RUNTIME_CALL          "Lcom/oracle/graal/api/code/RuntimeCall;"
-#define STRING                "Ljava/lang/String;"
-#define OBJECT                "Ljava/lang/Object;"
-#define CLASS                 "Ljava/lang/Class;"
-#define STACK_TRACE_ELEMENT   "Ljava/lang/StackTraceElement;"
 #define METASPACE_METHOD      "J"
 #define METASPACE_METHOD_DATA "J"
 #define NMETHOD               "J"
 
 JNINativeMethod CompilerToVM_methods[] = {
-  {CC"initializeBytecode",            CC"("METASPACE_METHOD"[B)[B",                                  FN_PTR(initializeBytecode)},
-  {CC"getSignature",                  CC"("METASPACE_METHOD")"STRING,                                FN_PTR(getSignature)},
-  {CC"initializeExceptionHandlers",   CC"("METASPACE_METHOD EXCEPTION_HANDLERS")"EXCEPTION_HANDLERS, FN_PTR(initializeExceptionHandlers)},
-  {CC"hasBalancedMonitors",           CC"("METASPACE_METHOD")Z",                                     FN_PTR(hasBalancedMonitors)},
-  {CC"getUniqueConcreteMethod",       CC"("METASPACE_METHOD"["RESOLVED_TYPE")"METASPACE_METHOD,      FN_PTR(getUniqueConcreteMethod)},
-  {CC"getStackTraceElement",          CC"("METASPACE_METHOD"I)"STACK_TRACE_ELEMENT,                  FN_PTR(getStackTraceElement)},
-  {CC"initializeMethod",              CC"("METASPACE_METHOD RESOLVED_METHOD")V",                     FN_PTR(initializeMethod)},
-  {CC"initializeMethodData",          CC"("METASPACE_METHOD_DATA METHOD_DATA")V",                    FN_PTR(initializeMethodData)},
-  {CC"getInvocationCount",            CC"("METASPACE_METHOD")I",                                     FN_PTR(getInvocationCount)},
-  {CC"getCompiledCodeSize",           CC"("METASPACE_METHOD")I",                                     FN_PTR(getCompiledCodeSize)},
-  {CC"getVtableEntryOffset",          CC"("METASPACE_METHOD")I",                                     FN_PTR(getVtableEntryOffset)},
-  {CC"lookupType",                    CC"("STRING RESOLVED_TYPE"Z)"TYPE,                             FN_PTR(lookupType)},
-  {CC"lookupConstantInPool",          CC"("RESOLVED_TYPE"I)"OBJECT,                                  FN_PTR(lookupConstantInPool)},
-  {CC"lookupMethodInPool",            CC"("RESOLVED_TYPE"IB)"METHOD,                                 FN_PTR(lookupMethodInPool)},
-  {CC"lookupTypeInPool",              CC"("RESOLVED_TYPE"I)"TYPE,                                    FN_PTR(lookupTypeInPool)},
-  {CC"lookupReferencedTypeInPool",    CC"("RESOLVED_TYPE"IB)V",                                      FN_PTR(lookupReferencedTypeInPool)},
-  {CC"lookupFieldInPool",             CC"("RESOLVED_TYPE"IB)"FIELD,                                  FN_PTR(lookupFieldInPool)},
-  {CC"resolveMethod",                 CC"("RESOLVED_TYPE STRING STRING")"METHOD,                     FN_PTR(resolveMethod)},
-  {CC"isSubtypeOf",                   CC"("RESOLVED_TYPE TYPE")Z",                                   FN_PTR(isSubtypeOf)},
-  {CC"getLeastCommonAncestor",        CC"("RESOLVED_TYPE RESOLVED_TYPE")"TYPE,                       FN_PTR(getLeastCommonAncestor)},
-  {CC"getComponentType",              CC"("RESOLVED_TYPE")"TYPE,                                     FN_PTR(getComponentType)},
-  {CC"getUniqueConcreteSubtype",      CC"("RESOLVED_TYPE")"TYPE,                                     FN_PTR(getUniqueConcreteSubtype)},
-  {CC"getSuperType",                  CC"("RESOLVED_TYPE")"TYPE,                                     FN_PTR(getSuperType)},
-  {CC"getPrototypeMarkWord",          CC"("RESOLVED_TYPE")J",                                        FN_PTR(getPrototypeMarkWord)},
-  {CC"getArrayOf",                    CC"("RESOLVED_TYPE")"TYPE,                                     FN_PTR(getArrayOf)},
-  {CC"getInstanceFields",             CC"("RESOLVED_TYPE")["RESOLVED_FIELD,                          FN_PTR(getInstanceFields)},
-  {CC"isTypeInitialized",             CC"("RESOLVED_TYPE")Z",                                        FN_PTR(isTypeInitialized)},
-  {CC"initializeType",                CC"("RESOLVED_TYPE")V",                                        FN_PTR(initializeType)},
-  {CC"getPrimitiveArrayType",         CC"("KIND")"TYPE,                                              FN_PTR(getPrimitiveArrayType)},
-  {CC"getMaxCallTargetOffset",        CC"(J)J",                                                      FN_PTR(getMaxCallTargetOffset)},
-  {CC"getType",                       CC"("CLASS")"TYPE,                                             FN_PTR(getType)},
-  {CC"getMetaspaceMethod",            CC"("REFLECT_METHOD"["RESOLVED_TYPE")"METASPACE_METHOD,        FN_PTR(getMetaspaceMethod)},
-  {CC"getJavaField",                  CC"("REFLECT_FIELD")"RESOLVED_FIELD,                           FN_PTR(getJavaField)},
-  {CC"initializeConfiguration",       CC"("CONFIG")V",                                               FN_PTR(initializeConfiguration)},
+  {CC"initializeBytecode",            CC"("METASPACE_METHOD"[B)[B",                                     FN_PTR(initializeBytecode)},
+  {CC"getSignature",                  CC"("METASPACE_METHOD")"STRING,                                   FN_PTR(getSignature)},
+  {CC"initializeExceptionHandlers",   CC"("METASPACE_METHOD EXCEPTION_HANDLERS")"EXCEPTION_HANDLERS,    FN_PTR(initializeExceptionHandlers)},
+  {CC"hasBalancedMonitors",           CC"("METASPACE_METHOD")Z",                                        FN_PTR(hasBalancedMonitors)},
+  {CC"getUniqueConcreteMethod",       CC"("METASPACE_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD,      FN_PTR(getUniqueConcreteMethod)},
+  {CC"getStackTraceElement",          CC"("METASPACE_METHOD"I)"STACK_TRACE_ELEMENT,                     FN_PTR(getStackTraceElement)},
+  {CC"initializeMethod",              CC"("METASPACE_METHOD HS_RESOLVED_METHOD")V",                     FN_PTR(initializeMethod)},
+  {CC"initializeMethodData",          CC"("METASPACE_METHOD_DATA METHOD_DATA")V",                       FN_PTR(initializeMethodData)},
+  {CC"isMethodCompilable",            CC"("METASPACE_METHOD")Z",                                        FN_PTR(isMethodCompilable)},
+  {CC"getInvocationCount",            CC"("METASPACE_METHOD")I",                                        FN_PTR(getInvocationCount)},
+  {CC"getCompiledCodeSize",           CC"("METASPACE_METHOD")I",                                        FN_PTR(getCompiledCodeSize)},
+  {CC"getVtableEntryOffset",          CC"("METASPACE_METHOD")I",                                        FN_PTR(getVtableEntryOffset)},
+  {CC"lookupType",                    CC"("STRING HS_RESOLVED_TYPE"Z)"TYPE,                             FN_PTR(lookupType)},
+  {CC"lookupConstantInPool",          CC"("HS_RESOLVED_TYPE"I)"OBJECT,                                  FN_PTR(lookupConstantInPool)},
+  {CC"lookupMethodInPool",            CC"("HS_RESOLVED_TYPE"IB)"METHOD,                                 FN_PTR(lookupMethodInPool)},
+  {CC"lookupTypeInPool",              CC"("HS_RESOLVED_TYPE"I)"TYPE,                                    FN_PTR(lookupTypeInPool)},
+  {CC"lookupReferencedTypeInPool",    CC"("HS_RESOLVED_TYPE"IB)V",                                      FN_PTR(lookupReferencedTypeInPool)},
+  {CC"lookupFieldInPool",             CC"("HS_RESOLVED_TYPE"IB)"FIELD,                                  FN_PTR(lookupFieldInPool)},
+  {CC"resolveMethod",                 CC"("HS_RESOLVED_TYPE STRING STRING")"METHOD,                     FN_PTR(resolveMethod)},
+  {CC"isSubtypeOf",                   CC"("HS_RESOLVED_TYPE TYPE")Z",                                   FN_PTR(isSubtypeOf)},
+  {CC"getLeastCommonAncestor",        CC"("HS_RESOLVED_TYPE HS_RESOLVED_TYPE")"TYPE,                    FN_PTR(getLeastCommonAncestor)},
+  {CC"getUniqueConcreteSubtype",      CC"("HS_RESOLVED_TYPE")"TYPE,                                     FN_PTR(getUniqueConcreteSubtype)},
+  {CC"getPrototypeMarkWord",          CC"("HS_RESOLVED_TYPE")J",                                        FN_PTR(getPrototypeMarkWord)},
+  {CC"getInstanceFields",             CC"("HS_RESOLVED_TYPE")["HS_RESOLVED_FIELD,                       FN_PTR(getInstanceFields)},
+  {CC"isTypeInitialized",             CC"("HS_RESOLVED_TYPE")Z",                                        FN_PTR(isTypeInitialized)},
+  {CC"initializeType",                CC"("HS_RESOLVED_TYPE")V",                                        FN_PTR(initializeType)},
+  {CC"getMaxCallTargetOffset",        CC"(J)J",                                                         FN_PTR(getMaxCallTargetOffset)},
+  {CC"getResolvedType",               CC"("CLASS")"RESOLVED_TYPE,                                       FN_PTR(getResolvedType)},
+  {CC"getMetaspaceMethod",            CC"("REFLECT_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD,        FN_PTR(getMetaspaceMethod)},
+  {CC"getJavaField",                  CC"("REFLECT_FIELD")"HS_RESOLVED_FIELD,                           FN_PTR(getJavaField)},
+  {CC"initializeConfiguration",       CC"("HS_CONFIG")V",                                               FN_PTR(initializeConfiguration)},
   {CC"installCode",                   CC"("HS_COMP_RESULT HS_INSTALLED_CODE HS_CODE_INFO")"HS_INSTALLED_CODE, FN_PTR(installCode)},
-  {CC"disassembleNative",             CC"([BJ)"STRING,                                               FN_PTR(disassembleNative)},
-  {CC"executeCompiledMethod",         CC"("METASPACE_METHOD NMETHOD OBJECT OBJECT OBJECT")"OBJECT,   FN_PTR(executeCompiledMethod)},
-  {CC"executeCompiledMethodVarargs",  CC"("METASPACE_METHOD NMETHOD "["OBJECT")"OBJECT,              FN_PTR(executeCompiledMethodVarargs)},
-  {CC"getDeoptedLeafGraphIds",        CC"()[J",                                                      FN_PTR(getDeoptedLeafGraphIds)},
-  {CC"decodePC",                      CC"(J)"STRING,                                                 FN_PTR(decodePC)},
+  {CC"disassembleNative",             CC"([BJ)"STRING,                                                  FN_PTR(disassembleNative)},
+  {CC"executeCompiledMethod",         CC"("METASPACE_METHOD NMETHOD OBJECT OBJECT OBJECT")"OBJECT,      FN_PTR(executeCompiledMethod)},
+  {CC"executeCompiledMethodVarargs",  CC"("METASPACE_METHOD NMETHOD "["OBJECT")"OBJECT,                 FN_PTR(executeCompiledMethodVarargs)},
+  {CC"getDeoptedLeafGraphIds",        CC"()[J",                                                         FN_PTR(getDeoptedLeafGraphIds)},
+  {CC"decodePC",                      CC"(J)"STRING,                                                    FN_PTR(decodePC)},
 };
 
 int CompilerToVM_methods_count() {
--- a/src/share/vm/graal/graalJavaAccess.hpp	Mon Nov 12 23:37:12 2012 +0100
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Wed Nov 14 11:28:02 2012 +0100
@@ -58,7 +58,6 @@
     long_field(HotSpotResolvedJavaMethod, metaspaceMethod)                                                                                                     \
     int_field(HotSpotResolvedJavaMethod, codeSize)                                                                                                             \
     int_field(HotSpotResolvedJavaMethod, exceptionHandlerCount)                                                                                                \
-    boolean_field(HotSpotResolvedJavaMethod, canBeInlined)                                                                                                     \
   end_class                                                                                                                                                    \
   start_class(HotSpotMethodData)                                                                                                                               \
     long_field(HotSpotMethodData, metaspaceMethodData)                                                                                                         \
@@ -85,6 +84,7 @@
     oop_field(HotSpotCompilationResult, comp, "Lcom/oracle/graal/api/code/CompilationResult;")                                                                 \
     oop_field(HotSpotCompilationResult, method, "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;")                                                   \
     oop_field(HotSpotCompilationResult, name, "Ljava/lang/String;")                                                                                            \
+    int_field(HotSpotCompilationResult, entryBCI)                                                                                                              \
     oop_field(HotSpotCompilationResult, sites, "[Lcom/oracle/graal/api/code/CompilationResult$Site;")                                                          \
     oop_field(HotSpotCompilationResult, exceptionHandlers, "[Lcom/oracle/graal/api/code/CompilationResult$ExceptionHandler;")                                  \
   end_class                                                                                                                                                    \
--- a/src/share/vm/oops/instanceKlass.cpp	Mon Nov 12 23:37:12 2012 +0100
+++ b/src/share/vm/oops/instanceKlass.cpp	Wed Nov 14 11:28:02 2012 +0100
@@ -2153,8 +2153,8 @@
 }
 
 void InstanceKlass::clean_method_data(BoolObjectClosure* is_alive) {
-#ifdef COMPILER2
-  // Currently only used by C2.
+#if defined(COMPILER2) || defined(GRAAL)
+   // Currently only used by C2.
   for (int m = 0; m < methods()->length(); m++) {
     MethodData* mdo = methods()->at(m)->method_data();
     if (mdo != NULL) {
--- a/src/share/vm/oops/method.cpp	Mon Nov 12 23:37:12 2012 +0100
+++ b/src/share/vm/oops/method.cpp	Wed Nov 14 11:28:02 2012 +0100
@@ -779,13 +779,6 @@
       set_not_c2_osr_compilable();
   }
   CompilationPolicy::policy()->disable_compilation(this);
-
-#ifdef GRAAL
-  oop graal_mirror = this->graal_mirror();
-  if (graal_mirror != NULL) {
-    HotSpotResolvedJavaMethod::set_canBeInlined(graal_mirror, false);
-  }
-#endif
 }
 
 // Revert to using the interpreter and clear out the nmethod
--- a/src/share/vm/oops/method.hpp	Mon Nov 12 23:37:12 2012 +0100
+++ b/src/share/vm/oops/method.hpp	Wed Nov 14 11:28:02 2012 +0100
@@ -133,7 +133,6 @@
   InvocationCounter _backedge_counter;           // Incremented before each backedge taken - used to trigger frequencey-based optimizations
 
 #ifdef GRAAL
-  oop               _graal_mirror;               // com/oracle/graal/hotspot/HotSpotResolvedJavaMethod mirroring this method
   jlong             _graal_invocation_time;
   int               _graal_priority;
 #endif
@@ -380,10 +379,6 @@
   int backedge_count();
 
 #ifdef GRAAL
-  // graal mirror
-  oop graal_mirror() const               { return _graal_mirror; }
-  void set_graal_mirror(oop m)           { oop_store((oop*) &_graal_mirror, m); }
-
   void set_graal_invocation_time(jlong time) { _graal_invocation_time = time; }
   jlong graal_invocation_time()          { return _graal_invocation_time; }
 
@@ -842,9 +837,6 @@
   // Inlined elements
   address* native_function_addr() const          { assert(is_native(), "must be native"); return (address*) (this+1); }
   address* signature_handler_addr() const        { return native_function_addr() + 1; }
-#ifdef GRAAL
-  oop*  adr_graal_mirror() const                 { return (oop*)&_graal_mirror;    }
-#endif
 };
 
 
--- a/src/share/vm/runtime/reflectionUtils.cpp	Mon Nov 12 23:37:12 2012 +0100
+++ b/src/share/vm/runtime/reflectionUtils.cpp	Wed Nov 14 11:28:02 2012 +0100
@@ -78,12 +78,6 @@
     offset = sun_reflect_UnsafeStaticFieldAccessorImpl::base_offset();
     _filtered_fields->append(new FilteredField(SystemDictionary::reflect_UnsafeStaticFieldAccessorImpl_klass(), offset));
   }
-#ifdef GRAAL
-  compute_offset(offset, SystemDictionary::HotSpotResolvedJavaMethod_klass(), "javaMirror", "Ljava/lang/Object;", false);
-  _filtered_fields->append(new FilteredField(SystemDictionary::HotSpotResolvedJavaMethod_klass(), offset));
-  compute_offset(offset, SystemDictionary::HotSpotMethodData_klass(), "hotspotMirror", "Ljava/lang/Object;", false);
-  _filtered_fields->append(new FilteredField(SystemDictionary::HotSpotMethodData_klass(), offset));
-#endif
 }
 
 int FilteredFieldStream::field_count() {