changeset 13261:0ffe9e4bb364

don't go through VM to create HotSpotResolvedObjectType (part 1)
author twisti
date Sun, 08 Dec 2013 13:27:52 -0800
parents f795de8d8b71
children f13f6dc290c8
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotSymbol.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/meta/HotSpotConstantPool.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalCompilerToVM.cpp src/share/vm/graal/graalJavaAccess.hpp src/share/vm/runtime/vmStructs.cpp
diffstat 13 files changed, 198 insertions(+), 142 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotSymbol.java	Sun Dec 08 11:21:49 2013 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotSymbol.java	Sun Dec 08 13:27:52 2013 -0800
@@ -23,20 +23,22 @@
 package com.oracle.graal.hotspot;
 
 import static com.oracle.graal.graph.UnsafeAccess.*;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import java.io.*;
 
 import com.oracle.graal.graph.*;
 
 /**
- * Represents the VM type {@code Symbol}.
+ * Represents a metaspace {@code Symbol}.
  */
 public class HotSpotSymbol {
 
-    private final long address;
+    private final long metaspaceSymbol;
 
-    public HotSpotSymbol(long address) {
-        this.address = address;
+    public HotSpotSymbol(long metaspaceSymbol) {
+        assert metaspaceSymbol != 0;
+        this.metaspaceSymbol = metaspaceSymbol;
     }
 
     /**
@@ -73,12 +75,10 @@
     }
 
     private int getLength() {
-        HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig();
-        return unsafe.getShort(address + config.symbolLengthOffset);
+        return unsafe.getShort(metaspaceSymbol + runtime().getConfig().symbolLengthOffset);
     }
 
     private byte getByteAt(int index) {
-        HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig();
-        return unsafe.getByte(address + config.symbolBodyOffset + index);
+        return unsafe.getByte(metaspaceSymbol + runtime().getConfig().symbolBodyOffset + index);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Sun Dec 08 11:21:49 2013 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Sun Dec 08 13:27:52 2013 -0800
@@ -887,6 +887,10 @@
     @HotSpotVMConstant(name = "JVM_CONSTANT_UnresolvedClass") @Stable public int jvmConstantUnresolvedClass;
     @HotSpotVMConstant(name = "JVM_CONSTANT_UnresolvedClassInError") @Stable public int jvmConstantUnresolvedClassInError;
     @HotSpotVMConstant(name = "JVM_CONSTANT_String") @Stable public int jvmConstantString;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Fieldref") @Stable public int jvmConstantFieldref;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_Methodref") @Stable public int jvmConstantMethodref;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_InterfaceMethodref") @Stable public int jvmConstantInterfaceMethodref;
+    @HotSpotVMConstant(name = "JVM_CONSTANT_NameAndType") @Stable public int jvmConstantNameAndType;
     @HotSpotVMConstant(name = "JVM_CONSTANT_MethodHandle") @Stable public int jvmConstantMethodHandle;
     @HotSpotVMConstant(name = "JVM_CONSTANT_MethodHandleInError") @Stable public int jvmConstantMethodHandleInError;
     @HotSpotVMConstant(name = "JVM_CONSTANT_MethodType") @Stable public int jvmConstantMethodType;
@@ -987,6 +991,25 @@
     @HotSpotVMField(name = "Klass::_layout_helper", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassLayoutHelperOffset;
     @HotSpotVMField(name = "Klass::_layout_helper", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassInstanceSizeOffset;
 
+    @HotSpotVMConstant(name = "Klass::_lh_neutral_value") @Stable public int klassLayoutHelperNeutralValue;
+    @HotSpotVMConstant(name = "Klass::_lh_instance_slow_path_bit") @Stable public int klassLayoutHelperInstanceSlowPathBit;
+    @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_shift") @Stable public int layoutHelperLog2ElementSizeShift;
+    @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_mask") @Stable public int layoutHelperLog2ElementSizeMask;
+    @HotSpotVMConstant(name = "Klass::_lh_element_type_shift") @Stable public int layoutHelperElementTypeShift;
+    @HotSpotVMConstant(name = "Klass::_lh_element_type_mask") @Stable public int layoutHelperElementTypeMask;
+    @HotSpotVMConstant(name = "Klass::_lh_header_size_shift") @Stable public int layoutHelperHeaderSizeShift;
+    @HotSpotVMConstant(name = "Klass::_lh_header_size_mask") @Stable public int layoutHelperHeaderSizeMask;
+    @HotSpotVMConstant(name = "Klass::_lh_array_tag_shift") @Stable public int layoutHelperArrayTagShift;
+    @HotSpotVMConstant(name = "Klass::_lh_array_tag_type_value") @Stable public int layoutHelperArrayTagTypeValue;
+    @HotSpotVMConstant(name = "Klass::_lh_array_tag_obj_value") @Stable public int layoutHelperArrayTagObjectValue;
+
+    /**
+     * This filters out the bit that differentiates a type array from an object array.
+     */
+    public int layoutHelperElementTypePrimitiveInPlace() {
+        return (layoutHelperArrayTagTypeValue & ~layoutHelperArrayTagObjectValue) << layoutHelperArrayTagShift;
+    }
+
     /**
      * Bit pattern in the klass layout helper that can be used to identify arrays.
      */
@@ -1063,24 +1086,6 @@
     @HotSpotVMFlag(name = "TLABStats") @Stable public boolean tlabStats;
     @Stable public boolean inlineContiguousAllocationSupported;
 
-    @HotSpotVMField(name = "Klass::_layout_helper", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int layoutHelperOffset;
-    @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_shift") @Stable public int layoutHelperLog2ElementSizeShift;
-    @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_mask") @Stable public int layoutHelperLog2ElementSizeMask;
-    @HotSpotVMConstant(name = "Klass::_lh_element_type_shift") @Stable public int layoutHelperElementTypeShift;
-    @HotSpotVMConstant(name = "Klass::_lh_element_type_mask") @Stable public int layoutHelperElementTypeMask;
-    @HotSpotVMConstant(name = "Klass::_lh_header_size_shift") @Stable public int layoutHelperHeaderSizeShift;
-    @HotSpotVMConstant(name = "Klass::_lh_header_size_mask") @Stable public int layoutHelperHeaderSizeMask;
-    @HotSpotVMConstant(name = "Klass::_lh_array_tag_shift") @Stable public int layoutHelperArrayTagShift;
-    @HotSpotVMConstant(name = "Klass::_lh_array_tag_type_value") @Stable public int layoutHelperArrayTagTypeValue;
-    @HotSpotVMConstant(name = "Klass::_lh_array_tag_obj_value") @Stable public int layoutHelperArrayTagObjectValue;
-
-    /**
-     * This filters out the bit that differentiates a type array from an object array.
-     */
-    public int layoutHelperElementTypePrimitiveInPlace() {
-        return (layoutHelperArrayTagTypeValue & ~layoutHelperArrayTagObjectValue) << layoutHelperArrayTagShift;
-    }
-
     /**
      * The DataLayout header size is the same as the cell size.
      */
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Sun Dec 08 11:21:49 2013 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Sun Dec 08 13:27:52 2013 -0800
@@ -197,8 +197,6 @@
 
     JavaMethod resolveMethod(HotSpotResolvedObjectType klass, String name, String signature);
 
-    ResolvedJavaType getResolvedType(Class<?> javaClass);
-
     HotSpotResolvedJavaField[] getInstanceFields(HotSpotResolvedObjectType klass);
 
     HotSpotResolvedJavaMethod[] getMethods(HotSpotResolvedObjectType klass);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Sun Dec 08 11:21:49 2013 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Sun Dec 08 13:27:52 2013 -0800
@@ -103,9 +103,6 @@
     public native void initializeMethod(long metaspaceMethod, HotSpotResolvedJavaMethod method);
 
     @Override
-    public native ResolvedJavaType getResolvedType(Class<?> javaClass);
-
-    @Override
     public native HotSpotResolvedJavaField[] getInstanceFields(HotSpotResolvedObjectType klass);
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Sun Dec 08 11:21:49 2013 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Sun Dec 08 13:27:52 2013 -0800
@@ -67,9 +67,6 @@
      * @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 sizeOrSpecies the size of an instance of the type, or
-     *            {@link HotSpotResolvedObjectType#INTERFACE_SPECIES_VALUE} or
-     *            {@link HotSpotResolvedObjectType#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
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Sun Dec 08 11:21:49 2013 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Sun Dec 08 13:27:52 2013 -0800
@@ -125,7 +125,7 @@
      * @param index constant pool index
      */
     private void assertBounds(int index) {
-        assert 0 <= index && index < length() : "index " + index + " not between 0 or " + length();
+        assert 0 <= index && index < length() : "index " + index + " not between 0 and " + length();
     }
 
     /**
@@ -135,7 +135,63 @@
      * @param tag expected tag
      */
     private void assertTag(int index, int tag) {
-        assert getTagAt(index) == tag : "constant pool tag at index " + index + " is " + getTagAt(index) + " but expected " + tag;
+        assert getTagAt(index) == tag : "constant pool tag at index " + index + " is " + getNameForTag(getTagAt(index)) + " but expected " + getNameForTag(tag);
+    }
+
+    private static String getNameForTag(int tag) {
+        HotSpotVMConfig config = runtime().getConfig();
+        if (tag == config.jvmConstantUtf8) {
+            return "JVM_CONSTANT_Utf8";
+        }
+        if (tag == config.jvmConstantInteger) {
+            return "JVM_CONSTANT_Integer";
+        }
+        if (tag == config.jvmConstantLong) {
+            return "JVM_CONSTANT_Long";
+        }
+        if (tag == config.jvmConstantFloat) {
+            return "JVM_CONSTANT_Float";
+        }
+        if (tag == config.jvmConstantDouble) {
+            return "JVM_CONSTANT_Double";
+        }
+        if (tag == config.jvmConstantClass) {
+            return "JVM_CONSTANT_Class";
+        }
+        if (tag == config.jvmConstantUnresolvedClass) {
+            return "JVM_CONSTANT_UnresolvedClass";
+        }
+        if (tag == config.jvmConstantUnresolvedClassInError) {
+            return "JVM_CONSTANT_UnresolvedClassInError";
+        }
+        if (tag == config.jvmConstantString) {
+            return "JVM_CONSTANT_String";
+        }
+        if (tag == config.jvmConstantFieldref) {
+            return "JVM_CONSTANT_Fieldref";
+        }
+        if (tag == config.jvmConstantMethodref) {
+            return "JVM_CONSTANT_Methodref";
+        }
+        if (tag == config.jvmConstantInterfaceMethodref) {
+            return "JVM_CONSTANT_InterfaceMethodref";
+        }
+        if (tag == config.jvmConstantNameAndType) {
+            return "JVM_CONSTANT_NameAndType";
+        }
+        if (tag == config.jvmConstantMethodHandle) {
+            return "JVM_CONSTANT_MethodHandle";
+        }
+        if (tag == config.jvmConstantMethodHandleInError) {
+            return "JVM_CONSTANT_MethodHandleInError";
+        }
+        if (tag == config.jvmConstantMethodType) {
+            return "JVM_CONSTANT_MethodType";
+        }
+        if (tag == config.jvmConstantMethodTypeInError) {
+            return "JVM_CONSTANT_MethodTypeInError";
+        }
+        return "unknown constant tag " + tag;
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Sun Dec 08 11:21:49 2013 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Sun Dec 08 13:27:52 2013 -0800
@@ -44,39 +44,15 @@
     private static final long serialVersionUID = 3481514353553840471L;
 
     /**
-     * Value for the {@code sizeOrSpecies} parameter in
-     * {@link HotSpotResolvedObjectType#HotSpotResolvedObjectType} denoting that the new type
-     * represents an interface class.
+     * The Java class this type represents.
      */
-    public static final int INTERFACE_SPECIES_VALUE = Integer.MIN_VALUE;
-
-    /**
-     * Value for the {@code sizeOrSpecies} parameter in
-     * {@link HotSpotResolvedObjectType#HotSpotResolvedObjectType} 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 Class<?> javaClass;
 
     /**
      * Used for implemented a lazy binding from a {@link Node} type to a {@link NodeClass} value.
      */
     private NodeClass nodeClass;
 
-    /**
-     * The instance size (in bytes) for an instance type,
-     * {@link HotSpotResolvedObjectType#INTERFACE_SPECIES_VALUE} denoting an interface type or
-     * {@link HotSpotResolvedObjectType#ARRAY_SPECIES_VALUE} denoting an array type.
-     */
-    private final int sizeOrSpecies;
-
     private HashMap<Long, ResolvedJavaField> fieldCache;
     private HashMap<Long, HotSpotResolvedJavaMethod> methodCache;
     private HotSpotResolvedJavaField[] instanceFields;
@@ -119,49 +95,80 @@
         ResolvedJavaType type = (ResolvedJavaType) unsafe.getObject(javaClass, (long) runtime.getConfig().graalMirrorInClassOffset);
         if (type == null) {
             assert !javaClass.isPrimitive() : "primitive type " + javaClass + " should have its mirror initialized";
-            type = runtime.getCompilerToVM().getResolvedType(javaClass);
+            type = new HotSpotResolvedObjectType(javaClass);
+
+            // Install the Graal mirror in the Class object.
+            final long offset = runtime().getConfig().graalMirrorInClassOffset;
+            if (!unsafe.compareAndSwapObject(javaClass, offset, null, type)) {
+                // lost the race - return the existing value instead
+                type = (HotSpotResolvedObjectType) unsafe.getObject(javaClass, offset);
+            }
+
             assert type != null;
         }
         return type;
     }
 
-    /**
-     * @param sizeOrSpecies the size of an instance of the type, or
-     *            {@link HotSpotResolvedObjectType#INTERFACE_SPECIES_VALUE} or
-     *            {@link HotSpotResolvedObjectType#ARRAY_SPECIES_VALUE}
-     */
     public HotSpotResolvedObjectType(long metaspaceKlass, String name, String simpleName, Class javaMirror, int sizeOrSpecies) {
         super(name);
-        this.metaspaceKlass = metaspaceKlass;
-        this.javaMirror = javaMirror;
-        this.simpleName = simpleName;
-        this.sizeOrSpecies = sizeOrSpecies;
-        assert name.charAt(0) != '[' || sizeOrSpecies == ARRAY_SPECIES_VALUE : name + " " + Long.toHexString(sizeOrSpecies);
-        assert javaMirror.isArray() == isArray();
-        assert javaMirror.isInterface() == isInterface();
+        assert HotSpotGraalRuntime.unsafeReadWord(javaMirror, runtime().getConfig().klassOffset) == metaspaceKlass;
+        this.javaClass = javaMirror;
+        assert name.charAt(0) != '[' || isArray() : name + " " + simpleName + " " + Long.toHexString(sizeOrSpecies);
+    }
+
+    /**
+     * Creates the Graal mirror for a {@link Class} object.
+     * 
+     * <p>
+     * <b>NOTE</b>: Creating a Graal mirror does not install the mirror in the {@link Class} object.
+     * </p>
+     * 
+     * @param javaClass the Class to create the mirror for
+     */
+    public HotSpotResolvedObjectType(Class<?> javaClass) {
+        super(getSignatureName(javaClass));
+        this.javaClass = javaClass;
+        assert getName().charAt(0) != '[' || isArray() : getName();
+    }
+
+    /**
+     * Returns the name of this type as it would appear in a signature.
+     */
+    private static String getSignatureName(Class<?> javaClass) {
+        if (javaClass.isArray()) {
+            return javaClass.getName().replace('.', '/');
+        }
+        return "L" + javaClass.getName().replace('.', '/') + ";";
+    }
+
+    /**
+     * Gets the address of the C++ Klass object for this type.
+     */
+    private long metaspaceKlass() {
+        return HotSpotGraalRuntime.unsafeReadWord(javaClass, runtime().getConfig().klassOffset);
     }
 
     @Override
     public int getModifiers() {
-        return javaMirror.getModifiers();
+        return javaClass.getModifiers();
     }
 
     public int getAccessFlags() {
         HotSpotVMConfig config = runtime().getConfig();
-        return unsafe.getInt(metaspaceKlass + config.klassAccessFlagsOffset);
+        return unsafe.getInt(metaspaceKlass() + config.klassAccessFlagsOffset);
     }
 
     @Override
     public ResolvedJavaType getArrayClass() {
         if (arrayOfType == null) {
-            arrayOfType = fromClass(Array.newInstance(javaMirror, 0).getClass());
+            arrayOfType = fromClass(Array.newInstance(javaClass, 0).getClass());
         }
         return arrayOfType;
     }
 
     @Override
     public ResolvedJavaType getComponentType() {
-        Class javaComponentType = javaMirror.getComponentType();
+        Class javaComponentType = javaClass.getComponentType();
         return javaComponentType == null ? null : fromClass(javaComponentType);
     }
 
@@ -175,13 +182,13 @@
         } else {
             HotSpotResolvedObjectType type = this;
             while (isAbstract(type.getModifiers())) {
-                long subklass = unsafeReadWord(type.metaspaceKlass + config.subklassOffset);
+                long subklass = unsafeReadWord(type.metaspaceKlass() + config.subklassOffset);
                 if (subklass == 0 || unsafeReadWord(subklass + config.nextSiblingOffset) != 0) {
                     return null;
                 }
                 type = (HotSpotResolvedObjectType) fromMetaspaceKlass(subklass);
             }
-            if (isAbstract(type.getModifiers()) || type.isInterface() || unsafeReadWord(type.metaspaceKlass + config.subklassOffset) != 0) {
+            if (isAbstract(type.getModifiers()) || type.isInterface() || unsafeReadWord(type.metaspaceKlass() + config.subklassOffset) != 0) {
                 return null;
             }
             return type;
@@ -190,14 +197,14 @@
 
     @Override
     public HotSpotResolvedObjectType getSuperclass() {
-        Class javaSuperclass = javaMirror.getSuperclass();
+        Class javaSuperclass = javaClass.getSuperclass();
         return javaSuperclass == null ? null : (HotSpotResolvedObjectType) fromClass(javaSuperclass);
     }
 
     @Override
     public ResolvedJavaType[] getInterfaces() {
         if (interfaces == null) {
-            Class[] javaInterfaces = javaMirror.getInterfaces();
+            Class[] javaInterfaces = javaClass.getInterfaces();
             ResolvedJavaType[] result = new ResolvedJavaType[javaInterfaces.length];
             for (int i = 0; i < javaInterfaces.length; i++) {
                 result[i] = fromClass(javaInterfaces[i]);
@@ -210,7 +217,7 @@
     public HotSpotResolvedObjectType getSupertype() {
         if (isArray()) {
             ResolvedJavaType componentType = getComponentType();
-            if (javaMirror == Object[].class || componentType.isPrimitive()) {
+            if (javaClass == Object[].class || componentType.isPrimitive()) {
                 return (HotSpotResolvedObjectType) fromClass(Object.class);
             }
             return (HotSpotResolvedObjectType) ((HotSpotResolvedObjectType) componentType).getSupertype().getArrayClass();
@@ -253,12 +260,11 @@
     public Constant getEncoding(Representation r) {
         switch (r) {
             case JavaClass:
-                return Constant.forObject(javaMirror);
+                return Constant.forObject(javaClass);
             case ObjectHub:
                 return klass();
             default:
-                assert false : "Should not reach here.";
-                return null;
+                throw GraalInternalError.shouldNotReachHere("unexpected representation " + r);
         }
     }
 
@@ -281,7 +287,7 @@
 
     @Override
     public boolean isArray() {
-        return sizeOrSpecies == ARRAY_SPECIES_VALUE;
+        return javaClass.isArray();
     }
 
     @Override
@@ -303,13 +309,13 @@
      * @return state field value of this type
      */
     private int getState() {
-        return unsafe.getByte(metaspaceKlass + runtime().getConfig().klassStateOffset) & 0xFF;
+        return unsafe.getByte(metaspaceKlass() + runtime().getConfig().klassStateOffset) & 0xFF;
     }
 
     @Override
     public void initialize() {
         if (!isInitialized()) {
-            unsafe.ensureClassInitialized(javaMirror);
+            unsafe.ensureClassInitialized(javaClass);
             assert isInitialized();
         }
     }
@@ -317,7 +323,7 @@
     @Override
     public boolean isInstance(Constant obj) {
         if (obj.getKind() == Kind.Object && !obj.isNull()) {
-            return javaMirror.isInstance(obj.asObject());
+            return javaClass.isInstance(obj.asObject());
         }
         return false;
     }
@@ -329,7 +335,7 @@
 
     @Override
     public boolean isInterface() {
-        return sizeOrSpecies == INTERFACE_SPECIES_VALUE;
+        return javaClass.isInterface();
     }
 
     @Override
@@ -337,7 +343,7 @@
         assert other != null;
         if (other instanceof HotSpotResolvedObjectType) {
             HotSpotResolvedObjectType otherType = (HotSpotResolvedObjectType) other;
-            return javaMirror.isAssignableFrom(otherType.javaMirror);
+            return javaClass.isAssignableFrom(otherType.javaClass);
         }
         return false;
     }
@@ -359,6 +365,12 @@
 
     @Override
     public String toString() {
+        String simpleName;
+        if (isArray() || isInterface()) {
+            simpleName = getName();
+        } else {
+            simpleName = getName().substring(1, getName().length() - 1);
+        }
         return "HotSpotType<" + simpleName + ", resolved>";
     }
 
@@ -378,7 +390,18 @@
     public int instanceSize() {
         assert !isArray();
         assert !isInterface();
-        return sizeOrSpecies;
+
+        HotSpotVMConfig config = runtime().getConfig();
+        final int layoutHelper = unsafe.getInt(metaspaceKlass() + config.klassLayoutHelperOffset);
+        assert layoutHelper > config.klassLayoutHelperNeutralValue : "must be instance";
+
+        // See: Klass::layout_helper_size_in_bytes
+        int size = layoutHelper & ~config.klassLayoutHelperInstanceSlowPathBit;
+
+        // See: Klass::layout_helper_needs_slow_path
+        boolean needsSlowPath = (layoutHelper & config.klassLayoutHelperInstanceSlowPathBit) != 0;
+
+        return needsSlowPath ? -size : size;
     }
 
     public synchronized HotSpotResolvedJavaMethod createMethod(long metaspaceMethod) {
@@ -440,7 +463,7 @@
             } else {
                 HotSpotResolvedJavaField[] myFields = runtime().getCompilerToVM().getInstanceFields(this);
                 Arrays.sort(myFields, new OffsetComparator());
-                if (javaMirror != Object.class) {
+                if (javaClass != 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);
@@ -469,13 +492,13 @@
 
     @Override
     public Class<?> mirror() {
-        return javaMirror;
+        return javaClass;
     }
 
     @Override
     public String getSourceFileName() {
         HotSpotVMConfig config = runtime().getConfig();
-        final int sourceFileNameIndex = unsafe.getChar(metaspaceKlass + config.klassSourceFileNameIndexOffset);
+        final int sourceFileNameIndex = unsafe.getChar(metaspaceKlass() + config.klassSourceFileNameIndexOffset);
         if (sourceFileNameIndex == 0) {
             return null;
         }
@@ -484,7 +507,7 @@
 
     @Override
     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-        return javaMirror.getAnnotation(annotationClass);
+        return javaClass.getAnnotation(annotationClass);
     }
 
     @Override
@@ -496,14 +519,7 @@
      * Gets the address of the C++ Klass object for this type.
      */
     public Constant klass() {
-        return Constant.forIntegerKind(runtime().getTarget().wordKind, metaspaceKlass, this);
-    }
-
-    /**
-     * Gets the address of the C++ Klass object for this type.
-     */
-    private long metaspaceKlass() {
-        return metaspaceKlass;
+        return Constant.forIntegerKind(runtime().getTarget().wordKind, metaspaceKlass(), this);
     }
 
     public boolean isPrimaryType() {
@@ -512,7 +528,7 @@
 
     public int superCheckOffset() {
         HotSpotVMConfig config = runtime().getConfig();
-        return unsafe.getInt(metaspaceKlass + config.superCheckOffsetOffset);
+        return unsafe.getInt(metaspaceKlass() + config.superCheckOffsetOffset);
     }
 
     public long prototypeMarkWord() {
@@ -520,7 +536,7 @@
         if (isArray()) {
             return config.arrayPrototypeMarkWord();
         } else {
-            return unsafeReadWord(metaspaceKlass + config.prototypeMarkWordOffset);
+            return unsafeReadWord(metaspaceKlass() + config.prototypeMarkWordOffset);
         }
     }
 
@@ -559,7 +575,7 @@
 
     @Override
     public ResolvedJavaMethod[] getDeclaredConstructors() {
-        Constructor[] constructors = javaMirror.getDeclaredConstructors();
+        Constructor[] constructors = javaClass.getDeclaredConstructors();
         ResolvedJavaMethod[] result = new ResolvedJavaMethod[constructors.length];
         for (int i = 0; i < constructors.length; i++) {
             result[i] = runtime().getHostProviders().getMetaAccess().lookupJavaConstructor(constructors[i]);
@@ -570,7 +586,7 @@
 
     @Override
     public ResolvedJavaMethod[] getDeclaredMethods() {
-        Method[] methods = javaMirror.getDeclaredMethods();
+        Method[] methods = javaClass.getDeclaredMethods();
         ResolvedJavaMethod[] result = new ResolvedJavaMethod[methods.length];
         for (int i = 0; i < methods.length; i++) {
             result[i] = runtime().getHostProviders().getMetaAccess().lookupJavaMethod(methods[i]);
@@ -591,7 +607,7 @@
 
     @Override
     public Constant newArray(int length) {
-        return Constant.forObject(Array.newInstance(javaMirror, length));
+        return Constant.forObject(Array.newInstance(javaClass, length));
     }
 
     /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Sun Dec 08 11:21:49 2013 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Sun Dec 08 13:27:52 2013 -0800
@@ -229,7 +229,7 @@
     }
 
     @Fold
-    private static int klassLayoutHelperOffset() {
+    public static int klassLayoutHelperOffset() {
         return config().klassLayoutHelperOffset;
     }
 
@@ -613,11 +613,6 @@
     }
 
     @Fold
-    public static int layoutHelperOffset() {
-        return config().layoutHelperOffset;
-    }
-
-    @Fold
     public static int layoutHelperHeaderSizeShift() {
         return config().layoutHelperHeaderSizeShift;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Sun Dec 08 11:21:49 2013 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Sun Dec 08 13:27:52 2013 -0800
@@ -89,7 +89,7 @@
      */
     @Snippet
     private static Object newArray(Word hub, int length, @ConstantParameter Word intArrayHub, @ConstantParameter Register threadRegister) {
-        int layoutHelper = hub.readInt(layoutHelperOffset(), LocationIdentity.FINAL_LOCATION);
+        int layoutHelper = hub.readInt(klassLayoutHelperOffset(), LocationIdentity.FINAL_LOCATION);
         int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask();
         int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask();
         int elementKind = (layoutHelper >> layoutHelperElementTypeShift()) & layoutHelperElementTypeMask();
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Sun Dec 08 11:21:49 2013 -0800
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Sun Dec 08 13:27:52 2013 -0800
@@ -143,7 +143,7 @@
     jlong prim = Constant::primitive(constant);
     if (obj != NULL) {
       if (obj->is_a(HotSpotResolvedObjectType::klass())) {
-        Klass* klass = (Klass*) (address) HotSpotResolvedObjectType::metaspaceKlass(obj);
+        Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(obj));
         assert((Klass*) prim == klass, err_msg("%s @ %p != %p", klass->name()->as_C_string(), klass, prim));
         int index = oop_recorder->find_index(klass);
         TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), klass->name()->as_C_string());
@@ -247,7 +247,7 @@
   } else if (value->is_a(VirtualObject::klass())) {
     oop type = VirtualObject::type(value);
     int id = VirtualObject::id(value);
-    oop javaMirror = HotSpotResolvedObjectType::javaMirror(type);
+    oop javaMirror = HotSpotResolvedObjectType::javaClass(type);
     Klass* klass = java_lang_Class::as_Klass(javaMirror);
     bool isLongArray = klass == Universe::longArrayKlassObj();
 
@@ -549,15 +549,15 @@
 
 void CodeInstaller::assumption_NoFinalizableSubclass(Handle assumption) {
   Handle receiverType_handle = Assumptions_NoFinalizableSubclass::receiverType(assumption());
-  Klass* receiverType = asKlass(HotSpotResolvedObjectType::metaspaceKlass(receiverType_handle));
+  Klass* receiverType = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(receiverType_handle));
   _dependencies->assert_has_no_finalizable_subclasses(receiverType);
 }
 
 void CodeInstaller::assumption_ConcreteSubtype(Handle assumption) {
   Handle context_handle = Assumptions_ConcreteSubtype::context(assumption());
   Handle subtype_handle = Assumptions_ConcreteSubtype::subtype(assumption());
-  Klass* context = asKlass(HotSpotResolvedObjectType::metaspaceKlass(context_handle));
-  Klass* subtype = asKlass(HotSpotResolvedObjectType::metaspaceKlass(subtype_handle));
+  Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(context_handle));
+  Klass* subtype = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(subtype_handle));
 
   _dependencies->assert_leaf_type(subtype);
   if (context != subtype) {
@@ -571,7 +571,7 @@
   Handle context_handle = Assumptions_ConcreteMethod::context(assumption());
 
   methodHandle impl = getMethodFromHotSpotMethod(impl_handle());
-  Klass* context = asKlass(HotSpotResolvedObjectType::metaspaceKlass(context_handle));
+  Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(context_handle));
 
   _dependencies->assert_unique_concrete_method(context, impl());
 }
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Sun Dec 08 11:21:49 2013 -0800
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Sun Dec 08 13:27:52 2013 -0800
@@ -157,7 +157,7 @@
       ConstantPool* cp = InstanceKlass::cast(method->method_holder())->constants();
       KlassHandle loading_klass = method->method_holder();
       Handle catch_class = GraalCompiler::get_JavaType(cp, catch_class_index, loading_klass, CHECK_NULL);
-      if (catch_class->klass() == HotSpotResolvedObjectType::klass() && java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(catch_class)) == SystemDictionary::Throwable_klass()) {
+      if (catch_class->klass() == HotSpotResolvedObjectType::klass() && java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(catch_class)) == SystemDictionary::Throwable_klass()) {
         ExceptionHandler::set_catchType(entry, NULL);
         ExceptionHandler::set_catchTypeCPI(entry, 0);
       } else {
@@ -264,7 +264,7 @@
 C2V_END
 
 C2V_VMENTRY(jobject, getUniqueImplementor, (JNIEnv *, jobject, jobject interface_type))
-  InstanceKlass* klass = (InstanceKlass*) asKlass(HotSpotResolvedObjectType::metaspaceKlass(interface_type));
+  InstanceKlass* klass = (InstanceKlass*) java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(interface_type));
   assert(klass->is_interface(), "must be");
   if (klass->nof_implementors() == 1) {
     InstanceKlass* implementor = (InstanceKlass*) klass->implementor();
@@ -309,8 +309,8 @@
   Handle classloader;
   Handle protectionDomain;
   if (JNIHandles::resolve(accessingClass) != NULL) {
-    classloader = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(accessingClass))->class_loader();
-    protectionDomain = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(accessingClass))->protection_domain();
+    classloader = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(accessingClass))->class_loader();
+    protectionDomain = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(accessingClass))->protection_domain();
   }
 
   if (eagerResolve) {
@@ -458,7 +458,7 @@
 C2V_VMENTRY(jobject, resolveMethod, (JNIEnv *, jobject, jobject resolved_type, jstring name, jstring signature))
 
   assert(JNIHandles::resolve(resolved_type) != NULL, "");
-  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(resolved_type));
+  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(resolved_type));
   Symbol* name_symbol = java_lang_String::as_symbol(JNIHandles::resolve(name), THREAD);
   Symbol* signature_symbol = java_lang_String::as_symbol(JNIHandles::resolve(signature), THREAD);
   methodHandle method = klass->lookup_method(name_symbol, signature_symbol);
@@ -474,7 +474,7 @@
 C2V_END
 
 C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jobject hotspot_klass))
-  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(hotspot_klass));
+  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(hotspot_klass));
   assert(klass != NULL, "method must not be called for primitive types");
   return Dependencies::find_finalizable_subclass(klass) != NULL;
 C2V_END
@@ -482,7 +482,7 @@
 C2V_VMENTRY(jobject, getInstanceFields, (JNIEnv *, jobject, jobject klass))
   ResourceMark rm;
 
-  instanceKlassHandle k = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(klass));
+  instanceKlassHandle k = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(klass));
   GrowableArray<Handle> fields(k->java_fields_count());
 
   for (AllFieldStream fs(k()); !fs.done(); fs.next()) {
@@ -505,7 +505,7 @@
 C2V_VMENTRY(jobject, getMethods, (JNIEnv *, jobject, jobject klass))
   ResourceMark rm;
 
-  instanceKlassHandle k(THREAD, java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaMirror(klass)));
+  instanceKlassHandle k(THREAD, java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(klass)));
   Array<Method*>* methods = k->methods();
   int methods_length = methods->length();
 
@@ -533,13 +533,6 @@
   return -1;
 C2V_END
 
-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
-
 
 // helpers used to set fields in the HotSpotVMConfig object
 jfieldID getFieldID(JNIEnv* env, jobject obj, const char* name, const char* sig) {
@@ -1010,7 +1003,6 @@
   {CC"getMethods",                    CC"("HS_RESOLVED_TYPE")["HS_RESOLVED_METHOD,                      FN_PTR(getMethods)},
   {CC"hasFinalizableSubclass",        CC"("HS_RESOLVED_TYPE")Z",                                        FN_PTR(hasFinalizableSubclass)},
   {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"getMetaspaceConstructor",       CC"("REFLECT_CONSTRUCTOR"["HS_RESOLVED_TYPE")"METASPACE_METHOD,   FN_PTR(getMetaspaceConstructor)},
   {CC"getJavaField",                  CC"("REFLECT_FIELD")"HS_RESOLVED_FIELD,                           FN_PTR(getJavaField)},
--- a/src/share/vm/graal/graalJavaAccess.hpp	Sun Dec 08 11:21:49 2013 -0800
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Sun Dec 08 13:27:52 2013 -0800
@@ -49,8 +49,7 @@
 
 #define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, static_oop_field)                \
   start_class(HotSpotResolvedObjectType)                                                                                                                       \
-    long_field(HotSpotResolvedObjectType, metaspaceKlass)                                                                                                      \
-    oop_field(HotSpotResolvedObjectType, javaMirror, "Ljava/lang/Class;")                                                                                      \
+    oop_field(HotSpotResolvedObjectType, javaClass, "Ljava/lang/Class;")                                                                                      \
   end_class                                                                                                                                                    \
   start_class(HotSpotResolvedJavaMethod)                                                                                                                       \
     oop_field(HotSpotResolvedJavaMethod, name, "Ljava/lang/String;")                                                                                           \
--- a/src/share/vm/runtime/vmStructs.cpp	Sun Dec 08 11:21:49 2013 -0800
+++ b/src/share/vm/runtime/vmStructs.cpp	Sun Dec 08 13:27:52 2013 -0800
@@ -2369,6 +2369,7 @@
   /******************************/                                        \
                                                                           \
   declare_constant(Klass::_primary_super_limit)                           \
+  declare_constant(Klass::_lh_neutral_value)                              \
   declare_constant(Klass::_lh_instance_slow_path_bit)                     \
   declare_constant(Klass::_lh_log2_element_size_shift)                    \
   declare_constant(Klass::_lh_log2_element_size_mask)                     \