changeset 18223:17c98fad6980

converted HotSpotResolvedObjectType to an interface
author Doug Simon <doug.simon@oracle.com>
date Mon, 03 Nov 2014 17:03:19 +0100
parents a8cff27ca2e1
children e04712c8928a
files graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedObjectTypeTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.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/HotSpotConstantReflectionProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.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/HotSpotMethodHandleAccessProvider.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/HotSpotResolvedJavaMethodImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedJavaType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.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/replacements/ReflectionGetCallerClassNode.java src/share/vm/classfile/systemDictionary.hpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalJavaAccess.hpp src/share/vm/runtime/deoptimization.cpp
diffstat 30 files changed, 995 insertions(+), 901 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Mon Nov 03 17:03:19 2014 +0100
@@ -47,11 +47,11 @@
 
 /**
  * use
- * 
+ *
  * <pre>
  * mx unittest AheadOfTimeCompilationTest @-XX:CompileCommand='print,*AheadOfTimeCompilationTest.*'
  * </pre>
- * 
+ *
  * to print disassembly.
  */
 public class AheadOfTimeCompilationTest extends GraalCompilerTest {
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java	Mon Nov 03 17:03:19 2014 +0100
@@ -23,7 +23,7 @@
 package com.oracle.graal.hotspot.test;
 
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType.*;
+import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectTypeImpl.*;
 
 import java.lang.reflect.*;
 
@@ -47,7 +47,7 @@
     @Test
     public void testModifiersForInternal() {
         for (Class<?> c : classesWithInternalFields) {
-            HotSpotResolvedObjectType type = HotSpotResolvedObjectType.fromObjectClass(c);
+            HotSpotResolvedObjectType type = HotSpotResolvedObjectTypeImpl.fromObjectClass(c);
             for (ResolvedJavaField field : type.getInstanceFields(false)) {
                 if (field.isInternal()) {
                     Assert.assertEquals(0, ~getReflectionFieldModifiers() & field.getModifiers());
@@ -57,13 +57,13 @@
     }
 
     /**
-     * Tests that {@link HotSpotResolvedObjectType#createField(String, JavaType, long, int)} always
-     * returns the same object for an internal field.
+     * Tests that {@link HotSpotResolvedObjectTypeImpl#createField(String, JavaType, long, int)}
+     * always returns the same object for an internal field.
      */
     @Test
     public void testCachingForInternalFields() {
         for (Class<?> c : classesWithInternalFields) {
-            HotSpotResolvedObjectType type = HotSpotResolvedObjectType.fromObjectClass(c);
+            HotSpotResolvedObjectTypeImpl type = HotSpotResolvedObjectTypeImpl.fromObjectClass(c);
             for (ResolvedJavaField field : type.getInstanceFields(false)) {
                 if (field.isInternal()) {
                     HotSpotResolvedJavaField expected = (HotSpotResolvedJavaField) field;
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedObjectTypeTest.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedObjectTypeTest.java	Mon Nov 03 17:03:19 2014 +0100
@@ -27,13 +27,13 @@
 import com.oracle.graal.hotspot.meta.*;
 
 /**
- * Tests {@link HotSpotResolvedObjectType} functionality.
+ * Tests {@link HotSpotResolvedJavaMethod} functionality.
  */
 public class HotSpotResolvedObjectTypeTest {
 
     @Test
     public void testGetSourceFileName() throws Throwable {
-        Assert.assertEquals("Object.java", HotSpotResolvedObjectType.fromObjectClass(Object.class).getSourceFileName());
-        Assert.assertEquals("HotSpotResolvedObjectTypeTest.java", HotSpotResolvedObjectType.fromObjectClass(this.getClass()).getSourceFileName());
+        Assert.assertEquals("Object.java", HotSpotResolvedObjectTypeImpl.fromObjectClass(Object.class).getSourceFileName());
+        Assert.assertEquals("HotSpotResolvedObjectTypeTest.java", HotSpotResolvedObjectTypeImpl.fromObjectClass(this.getClass()).getSourceFileName());
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Mon Nov 03 17:03:19 2014 +0100
@@ -25,7 +25,6 @@
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.debug.internal.MemUseTrackerImpl.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType.*;
 import static com.oracle.graal.nodes.StructuredGraph.*;
 
 import java.io.*;
@@ -277,7 +276,7 @@
 
                         // Pre-load all classes in the constant pool.
                         try {
-                            HotSpotResolvedObjectType objectType = fromObjectClass(javaClass);
+                            HotSpotResolvedObjectType objectType = HotSpotResolvedObjectTypeImpl.fromObjectClass(javaClass);
                             ConstantPool constantPool = objectType.constantPool();
                             for (int cpi = 1; cpi < constantPool.length(); cpi++) {
                                 constantPool.loadReferencedType(cpi, Bytecodes.LDC);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Mon Nov 03 17:03:19 2014 +0100
@@ -257,7 +257,7 @@
 
     /**
      * Graal mirrors are stored as a {@link ClassValue} associated with the {@link Class} of the
-     * type. This data structure stores both {@link HotSpotResolvedObjectType} and
+     * type. This data structure stores both {@link HotSpotResolvedJavaMethod} and
      * {@link HotSpotResolvedPrimitiveType} types.
      */
     private final ClassValue<ResolvedJavaType> graalMirrors = new ClassValue<ResolvedJavaType>() {
@@ -267,7 +267,7 @@
                 Kind kind = Kind.fromJavaClass(javaClass);
                 return new HotSpotResolvedPrimitiveType(kind);
             } else {
-                return new HotSpotResolvedObjectType(javaClass);
+                return new HotSpotResolvedObjectTypeImpl(javaClass);
             }
         }
     };
@@ -398,13 +398,14 @@
         }
 
         // Resolve non-primitive types in the VM.
-        final long metaspaceKlass = compilerToVm.lookupType(name, accessingType.mirror(), resolve);
+        HotSpotResolvedObjectTypeImpl hsAccessingType = (HotSpotResolvedObjectTypeImpl) accessingType;
+        final long metaspaceKlass = compilerToVm.lookupType(name, hsAccessingType.mirror(), resolve);
 
         if (metaspaceKlass == 0L) {
             assert resolve == false;
             return HotSpotUnresolvedJavaType.create(name);
         }
-        return HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass);
+        return HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass);
     }
 
     public HotSpotProviders getHostProviders() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Mon Nov 03 17:03:19 2014 +0100
@@ -1169,7 +1169,7 @@
     @HotSpotVMConstant(name = "JVM_ACC_SYNTHETIC") @Stable public int syntheticFlag;
 
     /**
-     * @see HotSpotResolvedObjectType#createField
+     * @see HotSpotResolvedObjectTypeImpl#createField
      */
     @HotSpotVMConstant(name = "JVM_RECOGNIZED_FIELD_MODIFIERS") @Stable public int recognizedFieldModifiers;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Mon Nov 03 17:03:19 2014 +0100
@@ -125,13 +125,13 @@
     }
 
     /**
-     * Gets the holder for this constant pool as {@link HotSpotResolvedObjectType}.
+     * Gets the holder for this constant pool as {@link HotSpotResolvedObjectTypeImpl}.
      *
      * @return holder for this constant pool
      */
     private HotSpotResolvedObjectType getHolder() {
         final long metaspaceKlass = unsafe.getAddress(metaspaceConstantPool + runtime().getConfig().constantPoolHolderOffset);
-        return HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass);
+        return HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass);
     }
 
     /**
@@ -447,7 +447,7 @@
             return HotSpotUnresolvedJavaType.create("L" + name + ";");
         } else {
             assert (metaspacePointer & config.compilerToVMKlassTag) == 0;
-            return HotSpotResolvedObjectType.fromMetaspaceKlass(metaspacePointer);
+            return HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspacePointer);
         }
     }
 
@@ -462,7 +462,7 @@
             String name = getNameRefAt(index);
             String signature = getSignatureRefAt(index);
             if (opcode == Bytecodes.INVOKEDYNAMIC) {
-                HotSpotResolvedObjectType holder = HotSpotResolvedObjectType.fromObjectClass(MethodHandle.class);
+                HotSpotResolvedObjectTypeImpl holder = HotSpotResolvedObjectTypeImpl.fromObjectClass(MethodHandle.class);
                 return new HotSpotMethodUnresolved(name, signature, holder);
             } else {
                 final int klassIndex = getKlassRefIndexAt(index);
@@ -492,7 +492,7 @@
         final int holderIndex = getKlassRefIndexAt(index);
         JavaType holder = lookupType(holderIndex, opcode);
 
-        if (holder instanceof HotSpotResolvedObjectType) {
+        if (holder instanceof HotSpotResolvedObjectTypeImpl) {
             long[] info = new long[2];
             long metaspaceKlass;
             try {
@@ -504,7 +504,7 @@
                  */
                 return new HotSpotUnresolvedField(holder, name, type);
             }
-            HotSpotResolvedObjectType resolvedHolder = HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass);
+            HotSpotResolvedObjectTypeImpl resolvedHolder = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass);
             final int flags = (int) info[0];
             final long offset = info[1];
             return resolvedHolder.createField(name, type, offset, flags);
@@ -554,7 +554,7 @@
             case UnresolvedClass:
             case UnresolvedClassInError:
                 final long metaspaceKlass = runtime().getCompilerToVM().constantPoolKlassAt(metaspaceConstantPool, index);
-                HotSpotResolvedObjectType type = HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass);
+                HotSpotResolvedObjectTypeImpl type = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass);
                 Class<?> klass = type.mirror();
                 if (!klass.isPrimitive() && !klass.isArray()) {
                     unsafe.ensureClassInitialized(klass);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Mon Nov 03 17:03:19 2014 +0100
@@ -107,8 +107,8 @@
                     o = unsafe.getObject(base, displacement);
                 } else if (baseConstant instanceof HotSpotMetaspaceConstant) {
                     Object metaspaceObject = HotSpotMetaspaceConstant.getMetaspaceObject(baseConstant);
-                    if (metaspaceObject instanceof HotSpotResolvedObjectType && initialDisplacement == runtime.getConfig().classMirrorOffset) {
-                        o = ((HotSpotResolvedObjectType) metaspaceObject).mirror();
+                    if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl && initialDisplacement == runtime.getConfig().classMirrorOffset) {
+                        o = ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror();
                     } else {
                         throw GraalInternalError.shouldNotReachHere();
                     }
@@ -166,10 +166,10 @@
                 assert bits == 32 && kind == Kind.Int;
                 long klassPointer = config().getKlassEncoding().uncompress((int) rawValue);
                 assert klassPointer == runtime.getCompilerToVM().readUnsafeKlassPointer(base);
-                return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(klassPointer), true);
+                return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(klassPointer), true);
             } else {
                 assert bits == 64 && kind == Kind.Long;
-                return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(rawValue), false);
+                return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(rawValue), false);
             }
         } else {
             switch (kind) {
@@ -231,7 +231,7 @@
         }
         if (constant instanceof HotSpotMetaspaceConstant) {
             Object obj = HotSpotMetaspaceConstant.getMetaspaceObject(constant);
-            if (obj instanceof HotSpotResolvedObjectType) {
+            if (obj instanceof HotSpotResolvedObjectTypeImpl) {
                 return (ResolvedJavaType) obj;
             }
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Mon Nov 03 17:03:19 2014 +0100
@@ -24,7 +24,7 @@
 
 import static com.oracle.graal.compiler.common.UnsafeAccess.*;
 import static com.oracle.graal.hotspot.meta.HotSpotResolvedJavaType.*;
-import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType.*;
+import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectTypeImpl.*;
 
 import java.lang.reflect.*;
 
@@ -52,7 +52,7 @@
         return fromClass(clazz);
     }
 
-    public HotSpotResolvedObjectType lookupJavaType(JavaConstant constant) {
+    public HotSpotResolvedObjectTypeImpl lookupJavaType(JavaConstant constant) {
         if (constant.isNull() || !(constant instanceof HotSpotObjectConstant)) {
             return null;
         }
@@ -115,11 +115,11 @@
         final int modifiers = reflectionField.getModifiers();
         final long offset = Modifier.isStatic(modifiers) ? unsafe.staticFieldOffset(reflectionField) : unsafe.objectFieldOffset(reflectionField);
 
-        HotSpotResolvedObjectType holder = fromObjectClass(fieldHolder);
+        HotSpotResolvedObjectTypeImpl holder = fromObjectClass(fieldHolder);
         HotSpotResolvedJavaType type = fromClass(fieldType);
 
         if (offset != -1) {
-            HotSpotResolvedObjectType resolved = holder;
+            HotSpotResolvedObjectTypeImpl resolved = holder;
             return resolved.createField(name, type, offset, modifiers);
         } else {
             throw GraalInternalError.shouldNotReachHere("unresolved field " + reflectionField);
@@ -295,7 +295,7 @@
     @Override
     public long getMemorySize(JavaConstant constant) {
         if (constant.getKind() == Kind.Object) {
-            HotSpotResolvedObjectType lookupJavaType = this.lookupJavaType(constant);
+            HotSpotResolvedObjectTypeImpl lookupJavaType = this.lookupJavaType(constant);
 
             if (lookupJavaType == null) {
                 return 0;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Mon Nov 03 17:03:19 2014 +0100
@@ -492,7 +492,7 @@
             outer: for (int i = 0; i < typeProfileWidth; i++) {
                 long receiverKlass = data.readWord(position, getTypeOffset(i));
                 if (receiverKlass != 0) {
-                    HotSpotResolvedObjectType klass = HotSpotResolvedObjectType.fromMetaspaceKlass(receiverKlass);
+                    HotSpotResolvedObjectTypeImpl klass = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(receiverKlass);
                     long count = data.readUnsignedInt(position, getTypeCountOffset(i));
                     /*
                      * Because of races in the profile collection machinery it's possible for a
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodHandleAccessProvider.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodHandleAccessProvider.java	Mon Nov 03 17:03:19 2014 +0100
@@ -24,7 +24,7 @@
 
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.meta.HotSpotResolvedJavaType.*;
-import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType.*;
+import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectTypeImpl.*;
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
@@ -65,7 +65,7 @@
 
         private static ResolvedJavaMethod findMethodInClass(String className, String methodName) throws ClassNotFoundException {
             Class<?> clazz = Class.forName(className);
-            HotSpotResolvedObjectType type = fromObjectClass(clazz);
+            HotSpotResolvedObjectTypeImpl type = fromObjectClass(clazz);
             ResolvedJavaMethod result = null;
             for (ResolvedJavaMethod method : type.getDeclaredMethods()) {
                 if (method.getName().equals(methodName)) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Mon Nov 03 17:03:19 2014 +0100
@@ -24,7 +24,7 @@
 
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType.*;
+import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectTypeImpl.*;
 
 import java.lang.annotation.*;
 import java.lang.reflect.*;
@@ -45,7 +45,7 @@
 public class HotSpotResolvedJavaField extends CompilerObject implements ResolvedJavaField {
 
     private static final long serialVersionUID = 7692985878836955683L;
-    private final HotSpotResolvedObjectType holder;
+    private final HotSpotResolvedObjectTypeImpl holder;
     private final String name;
     private JavaType type;
     private final int offset;
@@ -55,7 +55,7 @@
      */
     private final int modifiers;
 
-    public HotSpotResolvedJavaField(HotSpotResolvedObjectType holder, String name, JavaType type, long offset, int modifiers) {
+    public HotSpotResolvedJavaField(HotSpotResolvedObjectTypeImpl holder, String name, JavaType type, long offset, int modifiers) {
         this.holder = holder;
         this.name = name;
         this.type = type;
@@ -255,7 +255,7 @@
         if (isStatic()) {
             return false;
         }
-        return getDeclaringClass().isAssignableFrom(HotSpotResolvedObjectType.fromObjectClass(object.getClass()));
+        return getDeclaringClass().isAssignableFrom(HotSpotResolvedObjectTypeImpl.fromObjectClass(object.getClass()));
     }
 
     @Override
@@ -292,7 +292,7 @@
     }
 
     @Override
-    public HotSpotResolvedObjectType getDeclaringClass() {
+    public HotSpotResolvedObjectTypeImpl getDeclaringClass() {
         return holder;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Nov 03 17:03:19 2014 +0100
@@ -39,7 +39,7 @@
      */
     boolean isCallerSensitive();
 
-    HotSpotResolvedObjectType getDeclaringClass();
+    HotSpotResolvedObjectTypeImpl getDeclaringClass();
 
     /**
      * Returns true if this method has a {@code ForceInline} annotation.
@@ -70,7 +70,7 @@
 
     boolean hasBalancedMonitors();
 
-    ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectType receiver);
+    ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectTypeImpl receiver);
 
     /**
      * Returns whether this method has compiled code.
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java	Mon Nov 03 17:03:19 2014 +0100
@@ -51,7 +51,7 @@
      */
     private final long metaspaceMethod;
 
-    private final HotSpotResolvedObjectType holder;
+    private final HotSpotResolvedObjectTypeImpl holder;
     private final HotSpotConstantPool constantPool;
     private final HotSpotSignature signature;
     private HotSpotMethodData methodData;
@@ -65,12 +65,12 @@
      * @return the {@link ResolvedJavaType} corresponding to the holder of the
      *         {@code metaspaceMethod}
      */
-    public static HotSpotResolvedObjectType getHolder(long metaspaceMethod) {
+    public static HotSpotResolvedObjectTypeImpl getHolder(long metaspaceMethod) {
         HotSpotVMConfig config = runtime().getConfig();
         final long metaspaceConstMethod = unsafe.getAddress(metaspaceMethod + config.methodConstMethodOffset);
         final long metaspaceConstantPool = unsafe.getAddress(metaspaceConstMethod + config.constMethodConstantsOffset);
         final long metaspaceKlass = unsafe.getAddress(metaspaceConstantPool + config.constantPoolHolderOffset);
-        return HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass);
+        return HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass);
     }
 
     /**
@@ -80,11 +80,11 @@
      * @return the {@link ResolvedJavaMethod} corresponding to {@code metaspaceMethod}
      */
     public static HotSpotResolvedJavaMethod fromMetaspace(long metaspaceMethod) {
-        HotSpotResolvedObjectType holder = getHolder(metaspaceMethod);
+        HotSpotResolvedObjectTypeImpl holder = getHolder(metaspaceMethod);
         return holder.createMethod(metaspaceMethod);
     }
 
-    public HotSpotResolvedJavaMethodImpl(HotSpotResolvedObjectType holder, long metaspaceMethod) {
+    public HotSpotResolvedJavaMethodImpl(HotSpotResolvedObjectTypeImpl holder, long metaspaceMethod) {
         // It would be too much work to get the method name here so we fill it in later.
         super(null);
         this.metaspaceMethod = metaspaceMethod;
@@ -152,7 +152,7 @@
     }
 
     @Override
-    public HotSpotResolvedObjectType getDeclaringClass() {
+    public HotSpotResolvedObjectTypeImpl getDeclaringClass() {
         return holder;
     }
 
@@ -233,8 +233,8 @@
                 catchType = constantPool.lookupType(catchTypeIndex, opcode);
 
                 // Check for Throwable which catches everything.
-                if (catchType instanceof HotSpotResolvedObjectType) {
-                    HotSpotResolvedObjectType resolvedType = (HotSpotResolvedObjectType) catchType;
+                if (catchType instanceof HotSpotResolvedObjectTypeImpl) {
+                    HotSpotResolvedObjectTypeImpl resolvedType = (HotSpotResolvedObjectTypeImpl) catchType;
                     if (resolvedType.mirror() == Throwable.class) {
                         catchTypeIndex = 0;
                         catchType = null;
@@ -350,7 +350,7 @@
         return runtime().getCompilerToVM().getStackTraceElement(metaspaceMethod, bci);
     }
 
-    public ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectType receiver) {
+    public ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectTypeImpl receiver) {
         if (receiver.isInterface()) {
             // Cannot trust interfaces. Because of:
             // interface I { void foo(); }
@@ -622,21 +622,21 @@
     public int vtableEntryOffset(ResolvedJavaType resolved) {
         guarantee(isInVirtualMethodTable(resolved), "%s does not have a vtable entry", this);
         HotSpotVMConfig config = runtime().getConfig();
-        final int vtableIndex = getVtableIndex((HotSpotResolvedObjectType) resolved);
+        final int vtableIndex = getVtableIndex((HotSpotResolvedObjectTypeImpl) resolved);
         return config.instanceKlassVtableStartOffset + vtableIndex * config.vtableEntrySize + config.vtableEntryMethodOffset;
     }
 
     @Override
     public boolean isInVirtualMethodTable(ResolvedJavaType resolved) {
-        if (resolved instanceof HotSpotResolvedObjectType) {
-            HotSpotResolvedObjectType hotspotResolved = (HotSpotResolvedObjectType) resolved;
+        if (resolved instanceof HotSpotResolvedObjectTypeImpl) {
+            HotSpotResolvedObjectTypeImpl hotspotResolved = (HotSpotResolvedObjectTypeImpl) resolved;
             int vtableIndex = getVtableIndex(hotspotResolved);
             return vtableIndex >= 0 && vtableIndex < hotspotResolved.getVtableLength();
         }
         return false;
     }
 
-    private int getVtableIndex(HotSpotResolvedObjectType resolved) {
+    private int getVtableIndex(HotSpotResolvedObjectTypeImpl resolved) {
         if (!holder.isLinked()) {
             return runtime().getConfig().invalidVtableIndex;
         }
@@ -663,7 +663,7 @@
     }
 
     private int getVtableIndexForInterface(ResolvedJavaType resolved) {
-        HotSpotResolvedObjectType hotspotType = (HotSpotResolvedObjectType) resolved;
+        HotSpotResolvedObjectTypeImpl hotspotType = (HotSpotResolvedObjectTypeImpl) resolved;
         return runtime().getCompilerToVM().getVtableIndexForInterface(hotspotType.getMetaspaceKlass(), getMetaspaceMethod());
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Mon Nov 03 17:03:19 2014 +0100
@@ -22,721 +22,51 @@
  */
 package com.oracle.graal.hotspot.meta;
 
-import static com.oracle.graal.compiler.common.UnsafeAccess.*;
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-import static java.util.Objects.*;
-
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-import java.net.*;
-import java.util.*;
-
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.hotspot.*;
 
 /**
  * Implementation of {@link JavaType} for resolved non-primitive HotSpot classes.
  */
-public final class HotSpotResolvedObjectType extends HotSpotResolvedJavaType {
-
-    private static final long serialVersionUID = 3481514353553840471L;
-
-    /**
-     * The Java class this type represents.
-     */
-    private final Class<?> javaClass;
-
-    private HashMap<Long, HotSpotResolvedJavaField> fieldCache;
-    private HashMap<Long, HotSpotResolvedJavaMethod> methodCache;
-    private HotSpotResolvedJavaField[] instanceFields;
-    private HotSpotResolvedObjectType[] interfaces;
-    private ConstantPool constantPool;
-    private HotSpotResolvedObjectType arrayOfType;
+public interface HotSpotResolvedObjectType extends ResolvedJavaType {
 
-    /**
-     * Gets the Graal mirror for a {@link Class} object.
-     *
-     * @return the {@link HotSpotResolvedJavaType} corresponding to {@code javaClass}
-     */
-    public static HotSpotResolvedObjectType fromObjectClass(Class<?> javaClass) {
-        return (HotSpotResolvedObjectType) runtime().fromClass(javaClass);
-    }
-
-    /**
-     * Gets the Graal mirror from a HotSpot metaspace Klass native object.
-     *
-     * @param metaspaceKlass a metaspace Klass object boxed in a {@link JavaConstant}
-     * @return the {@link HotSpotResolvedObjectType} corresponding to {@code klassConstant}
-     */
-    public static HotSpotResolvedObjectType fromMetaspaceKlass(JavaConstant metaspaceKlass) {
-        assert metaspaceKlass.getKind() == Kind.Long;
-        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 HotSpotResolvedObjectType fromMetaspaceKlass(long metaspaceKlass) {
-        assert metaspaceKlass != 0;
-        Class<?> javaClass = runtime().getCompilerToVM().getJavaMirror(metaspaceKlass);
-        assert javaClass != null;
-        return fromObjectClass(javaClass);
-    }
+    HotSpotResolvedObjectType getArrayClass();
 
-    /**
-     * Creates the Graal mirror for a {@link Class} object.
-     *
-     * <p>
-     * <b>NOTE</b>: Creating an instance of this class does not install the mirror for the
-     * {@link Class} type. Use {@link #fromObjectClass(Class)},
-     * {@link #fromMetaspaceKlass(JavaConstant)} or {@link #fromMetaspaceKlass(long)} instead.
-     * </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 metaspace Klass for this type.
-     */
-    public long getMetaspaceKlass() {
-        return HotSpotGraalRuntime.unsafeReadWord(javaClass, runtime().getConfig().klassOffset);
-    }
+    ResolvedJavaType getComponentType();
 
-    @Override
-    public int getModifiers() {
-        return mirror().getModifiers();
-    }
-
-    public int getAccessFlags() {
-        HotSpotVMConfig config = runtime().getConfig();
-        return unsafe.getInt(getMetaspaceKlass() + config.klassAccessFlagsOffset);
-    }
+    HotSpotResolvedObjectType findUniqueConcreteSubtype();
 
-    @Override
-    public ResolvedJavaType getArrayClass() {
-        if (arrayOfType == null) {
-            arrayOfType = fromObjectClass(Array.newInstance(mirror(), 0).getClass());
-        }
-        return arrayOfType;
-    }
-
-    @Override
-    public ResolvedJavaType getComponentType() {
-        Class<?> javaComponentType = mirror().getComponentType();
-        return javaComponentType == null ? null : fromClass(javaComponentType);
-    }
-
-    @Override
-    public ResolvedJavaType findUniqueConcreteSubtype() {
-        HotSpotVMConfig config = runtime().getConfig();
-        if (isArray()) {
-            return getElementalType().isFinal() ? this : null;
-        } else if (isInterface()) {
-            HotSpotResolvedObjectType type = getSingleImplementor();
-            if (type == null) {
-                return null;
-            }
+    HotSpotResolvedObjectType getSuperclass();
 
-            /*
-             * If the implementor field contains itself that indicates that the interface has more
-             * than one implementors (see: InstanceKlass::add_implementor). The isInterface check
-             * takes care of this fact since this class is an interface.
-             */
-            if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) {
-                return null;
-            }
-            return type;
-        } else {
-            HotSpotResolvedObjectType type = this;
-            while (type.isAbstract()) {
-                long subklass = type.getSubklass();
-                if (subklass == 0 || unsafeReadWord(subklass + config.nextSiblingOffset) != 0) {
-                    return null;
-                }
-                type = fromMetaspaceKlass(subklass);
-            }
-            if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) {
-                return null;
-            }
-            return type;
-        }
-    }
-
-    /**
-     * Returns if type {@code type} is a leaf class. This is the case if the
-     * {@code Klass::_subklass} field of the underlying class is zero.
-     *
-     * @return true if the type is a leaf class
-     */
-    private boolean isLeafClass() {
-        return getSubklass() == 0;
-    }
+    HotSpotResolvedObjectType[] getInterfaces();
 
-    /**
-     * Returns the {@code Klass::_subklass} field of the underlying metaspace klass for the given
-     * type {@code type}.
-     *
-     * @return value of the subklass field as metaspace klass pointer
-     */
-    private long getSubklass() {
-        return unsafeReadWord(getMetaspaceKlass() + runtime().getConfig().subklassOffset);
-    }
-
-    @Override
-    public HotSpotResolvedObjectType getSuperclass() {
-        Class<?> javaSuperclass = mirror().getSuperclass();
-        return javaSuperclass == null ? null : (HotSpotResolvedObjectType) fromObjectClass(javaSuperclass);
-    }
-
-    @Override
-    public HotSpotResolvedObjectType[] getInterfaces() {
-        if (interfaces == null) {
-            Class<?>[] javaInterfaces = mirror().getInterfaces();
-            HotSpotResolvedObjectType[] result = new HotSpotResolvedObjectType[javaInterfaces.length];
-            for (int i = 0; i < javaInterfaces.length; i++) {
-                result[i] = fromObjectClass(javaInterfaces[i]);
-            }
-            interfaces = result;
-        }
-        return interfaces;
-    }
-
-    @Override
-    public HotSpotResolvedObjectType getSingleImplementor() {
-        if (!isInterface()) {
-            throw new GraalInternalError("Cannot call getImplementor() on a non-interface type: " + this);
-        }
-        final long implementorMetaspaceKlass = runtime().getCompilerToVM().getKlassImplementor(getMetaspaceKlass());
+    HotSpotResolvedObjectType getSupertype();
 
-        // No implementor.
-        if (implementorMetaspaceKlass == 0) {
-            return null;
-        }
-
-        return fromMetaspaceKlass(implementorMetaspaceKlass);
-    }
-
-    public HotSpotResolvedObjectType getSupertype() {
-        if (isArray()) {
-            ResolvedJavaType componentType = getComponentType();
-            if (mirror() == Object[].class || componentType.isPrimitive()) {
-                return fromObjectClass(Object.class);
-            }
-            return (HotSpotResolvedObjectType) ((HotSpotResolvedObjectType) componentType).getSupertype().getArrayClass();
-        }
-        if (isInterface()) {
-            return fromObjectClass(Object.class);
-        }
-        return getSuperclass();
-    }
+    HotSpotResolvedObjectType findLeastCommonAncestor(ResolvedJavaType otherType);
 
-    @Override
-    public ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType) {
-        if (otherType.isPrimitive()) {
-            return null;
-        } else {
-            HotSpotResolvedObjectType t1 = this;
-            HotSpotResolvedObjectType t2 = (HotSpotResolvedObjectType) otherType;
-            while (true) {
-                if (t1.isAssignableFrom(t2)) {
-                    return t1;
-                }
-                if (t2.isAssignableFrom(t1)) {
-                    return t2;
-                }
-                t1 = t1.getSupertype();
-                t2 = t2.getSupertype();
-            }
-        }
-    }
+    HotSpotResolvedObjectType asExactType();
 
-    @Override
-    public ResolvedJavaType asExactType() {
-        if (isArray()) {
-            return getComponentType().asExactType() != null ? this : null;
-        }
-        return isFinal() ? this : null;
-    }
-
-    @Override
-    public JavaConstant getEncoding(Representation r) {
-        switch (r) {
-            case JavaClass:
-                return HotSpotObjectConstant.forObject(mirror());
-            case ObjectHub:
-                return klass();
-            default:
-                throw GraalInternalError.shouldNotReachHere("unexpected representation " + r);
-        }
-    }
-
-    @Override
-    public boolean hasFinalizableSubclass() {
-        assert !isArray();
-        return runtime().getCompilerToVM().hasFinalizableSubclass(getMetaspaceKlass());
-    }
-
-    @Override
-    public boolean hasFinalizer() {
-        HotSpotVMConfig config = runtime().getConfig();
-        return (getAccessFlags() & config.klassHasFinalizerFlag) != 0;
-    }
-
-    @Override
-    public boolean isPrimitive() {
+    default boolean isPrimitive() {
         return false;
     }
 
-    @Override
-    public boolean isArray() {
-        return mirror().isArray();
-    }
-
-    @Override
-    public boolean isInitialized() {
-        return isArray() ? true : getInitState() == runtime().getConfig().instanceKlassStateFullyInitialized;
-    }
-
-    @Override
-    public boolean isLinked() {
-        return isArray() ? true : getInitState() >= runtime().getConfig().instanceKlassStateLinked;
-    }
-
-    /**
-     * Returns the value of the state field {@code InstanceKlass::_init_state} of the metaspace
-     * klass.
-     *
-     * @return state field value of this type
-     */
-    private int getInitState() {
-        assert !isArray() : "_init_state only exists in InstanceKlass";
-        return unsafe.getByte(getMetaspaceKlass() + runtime().getConfig().instanceKlassInitStateOffset) & 0xFF;
-    }
-
-    @Override
-    public void initialize() {
-        if (!isInitialized()) {
-            unsafe.ensureClassInitialized(mirror());
-            assert isInitialized();
-        }
-    }
-
-    @Override
-    public boolean isInstance(JavaConstant obj) {
-        if (obj.getKind() == Kind.Object && !obj.isNull()) {
-            return mirror().isInstance(HotSpotObjectConstant.asObject(obj));
-        }
-        return false;
-    }
-
-    @Override
-    public boolean isInstanceClass() {
-        return !isArray() && !isInterface();
-    }
-
-    @Override
-    public boolean isInterface() {
-        return mirror().isInterface();
-    }
-
-    @Override
-    public boolean isAssignableFrom(ResolvedJavaType other) {
-        assert other != null;
-        if (other instanceof HotSpotResolvedObjectType) {
-            HotSpotResolvedObjectType otherType = (HotSpotResolvedObjectType) other;
-            return mirror().isAssignableFrom(otherType.mirror());
-        }
-        return false;
-    }
-
-    @Override
-    public boolean isJavaLangObject() {
-        return javaClass.equals(Object.class);
-    }
-
-    @Override
-    public Kind getKind() {
+    default Kind getKind() {
         return Kind.Object;
     }
 
-    @Override
-    public ResolvedJavaMethod resolveConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) {
-        ResolvedJavaMethod resolvedMethod = resolveMethod(method, callerType, true);
-        if (resolvedMethod == null || resolvedMethod.isAbstract()) {
-            return null;
-        }
-        return resolvedMethod;
-    }
-
-    @Override
-    public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType, boolean includeAbstract) {
-        if (!includeAbstract) {
-            return resolveConcreteMethod(method, callerType);
-        }
-        assert !callerType.isArray();
-        if (!method.isAbstract() && method.getDeclaringClass().equals(this) && method.isPublic()) {
-            return method;
-        }
-        if (!method.getDeclaringClass().isAssignableFrom(this)) {
-            return null;
-        }
-        HotSpotResolvedJavaMethodImpl hotSpotMethod = (HotSpotResolvedJavaMethodImpl) method;
-        HotSpotResolvedObjectType hotSpotCallerType = (HotSpotResolvedObjectType) callerType;
-        final long resolvedMetaspaceMethod = runtime().getCompilerToVM().resolveMethod(getMetaspaceKlass(), hotSpotMethod.getMetaspaceMethod(), hotSpotCallerType.getMetaspaceKlass());
-        if (resolvedMetaspaceMethod == 0) {
-            return null;
-        }
-        return HotSpotResolvedJavaMethodImpl.fromMetaspace(resolvedMetaspaceMethod);
-    }
-
-    public ConstantPool constantPool() {
-        if (constantPool == null) {
-            final long metaspaceConstantPool = unsafe.getAddress(getMetaspaceKlass() + runtime().getConfig().instanceKlassConstantsOffset);
-            constantPool = new HotSpotConstantPool(metaspaceConstantPool);
-        }
-        return constantPool;
-    }
+    ConstantPool constantPool();
 
     /**
      * 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). Must not
      * be called if this is an array or interface type.
      */
-    public int instanceSize() {
-        assert !isArray();
-        assert !isInterface();
-
-        HotSpotVMConfig config = runtime().getConfig();
-        final int layoutHelper = unsafe.getInt(getMetaspaceKlass() + 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) {
-        HotSpotResolvedJavaMethod method = null;
-        if (methodCache == null) {
-            methodCache = new HashMap<>(8);
-        } else {
-            method = methodCache.get(metaspaceMethod);
-        }
-        if (method == null) {
-            method = new HotSpotResolvedJavaMethodImpl(this, metaspaceMethod);
-            methodCache.put(metaspaceMethod, method);
-        }
-        return method;
-    }
+    int instanceSize();
 
-    public int getVtableLength() {
-        HotSpotVMConfig config = runtime().getConfig();
-        if (isInterface() || isArray()) {
-            /* Everything has the core vtable of java.lang.Object */
-            return config.baseVtableLength;
-        }
-        int result = unsafe.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) / (config.vtableEntrySize / config.heapWordSize);
-        assert result >= config.baseVtableLength : unsafe.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) + " " + config.vtableEntrySize;
-        return result;
-    }
-
-    /**
-     * Gets the mask used to filter out HotSpot internal flags for fields when a {@link Field}
-     * object is created. This is the value of {@code JVM_RECOGNIZED_FIELD_MODIFIERS} in
-     * {@code jvm.h}, <b>not</b> {@link Modifier#fieldModifiers()}.
-     */
-    public static int getReflectionFieldModifiers() {
-        return runtime().getConfig().recognizedFieldModifiers;
-    }
-
-    public synchronized HotSpotResolvedJavaField createField(String fieldName, JavaType type, long offset, int rawFlags) {
-        HotSpotResolvedJavaField result = null;
-
-        final int flags = rawFlags & getReflectionFieldModifiers();
-
-        final long id = offset + ((long) flags << 32);
-
-        // (thomaswue) Must cache the fields, because the local load elimination only works if the
-        // objects from two field lookups are identical.
-        if (fieldCache == null) {
-            fieldCache = new HashMap<>(8);
-        } else {
-            result = fieldCache.get(id);
-        }
-
-        if (result == null) {
-            result = new HotSpotResolvedJavaField(this, fieldName, type, offset, rawFlags);
-            fieldCache.put(id, result);
-        } else {
-            assert result.getName().equals(fieldName);
-            // assert result.getType().equals(type);
-            assert result.offset() == offset;
-            assert result.getModifiers() == flags;
-        }
-
-        return result;
-    }
+    int getVtableLength();
 
     @Override
-    public ResolvedJavaMethod findUniqueConcreteMethod(ResolvedJavaMethod method) {
-        HotSpotResolvedJavaMethod hmethod = (HotSpotResolvedJavaMethod) method;
-        HotSpotResolvedObjectType declaredHolder = hmethod.getDeclaringClass();
-        /*
-         * Sometimes the receiver type in the graph hasn't stabilized to a subtype of declared
-         * holder, usually because of phis, so make sure that the type is related to the declared
-         * type before using it for lookup. Unlinked types should also be ignored because we can't
-         * resolve the proper method to invoke. Generally unlinked types in invokes should result in
-         * a deopt instead since they can't really be used if they aren't linked yet.
-         */
-        if (!declaredHolder.isAssignableFrom(this) || this.isArray() || this.equals(declaredHolder) || !isLinked() || isInterface()) {
-            return hmethod.uniqueConcreteMethod(declaredHolder);
-        }
-        /*
-         * The holder may be a subtype of the decaredHolder so make sure to resolve the method to
-         * the correct method for the subtype.
-         */
-        HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) resolveMethod(hmethod, this, true);
-        if (resolvedMethod == null) {
-            // The type isn't known to implement the method.
-            return null;
-        }
-
-        return resolvedMethod.uniqueConcreteMethod(this);
-    }
-
-    /**
-     * This class represents the field information for one field contained in the fields array of an
-     * {@code InstanceKlass}. The implementation is similar to the native {@code FieldInfo} class.
-     */
-    private class FieldInfo {
-        /**
-         * Native pointer into the array of Java shorts.
-         */
-        private final long metaspaceData;
-
-        /**
-         * Creates a field info for the field in the fields array at index {@code index}.
-         *
-         * @param index index to the fields array
-         */
-        public FieldInfo(int index) {
-            HotSpotVMConfig config = runtime().getConfig();
-            // Get Klass::_fields
-            final long metaspaceFields = unsafe.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset);
-            assert config.fieldInfoFieldSlots == 6 : "revisit the field parsing code";
-            metaspaceData = metaspaceFields + config.arrayU2DataOffset + config.fieldInfoFieldSlots * Short.BYTES * index;
-        }
-
-        private int getAccessFlags() {
-            return readFieldSlot(runtime().getConfig().fieldInfoAccessFlagsOffset);
-        }
-
-        private int getNameIndex() {
-            return readFieldSlot(runtime().getConfig().fieldInfoNameIndexOffset);
-        }
-
-        private int getSignatureIndex() {
-            return readFieldSlot(runtime().getConfig().fieldInfoSignatureIndexOffset);
-        }
-
-        public int getOffset() {
-            HotSpotVMConfig config = runtime().getConfig();
-            final int lowPacked = readFieldSlot(config.fieldInfoLowPackedOffset);
-            final int highPacked = readFieldSlot(config.fieldInfoHighPackedOffset);
-            final int offset = ((highPacked << Short.SIZE) | lowPacked) >> config.fieldInfoTagSize;
-            return offset;
-        }
-
-        /**
-         * Helper method to read an entry (slot) from the field array. Currently field info is laid
-         * on top an array of Java shorts.
-         */
-        private int readFieldSlot(int index) {
-            return unsafe.getChar(metaspaceData + Short.BYTES * index);
-        }
-
-        /**
-         * Returns the name of this field as a {@link String}. If the field is an internal field the
-         * name index is pointing into the vmSymbols table.
-         */
-        public String getName() {
-            final int nameIndex = getNameIndex();
-            return isInternal() ? HotSpotVmSymbols.symbolAt(nameIndex) : constantPool().lookupUtf8(nameIndex);
-        }
-
-        /**
-         * Returns the signature of this field as {@link String}. If the field is an internal field
-         * the signature index is pointing into the vmSymbols table.
-         */
-        public String getSignature() {
-            final int signatureIndex = getSignatureIndex();
-            return isInternal() ? HotSpotVmSymbols.symbolAt(signatureIndex) : constantPool().lookupUtf8(signatureIndex);
-        }
-
-        public JavaType getType() {
-            String signature = getSignature();
-            return runtime().lookupType(signature, HotSpotResolvedObjectType.this, false);
-        }
-
-        private boolean isInternal() {
-            return (getAccessFlags() & runtime().getConfig().jvmAccFieldInternal) != 0;
-        }
-
-        public boolean isStatic() {
-            return Modifier.isStatic(getAccessFlags());
-        }
-
-        public boolean hasGenericSignature() {
-            return (getAccessFlags() & runtime().getConfig().jvmAccFieldHasGenericSignature) != 0;
-        }
-    }
-
-    private static class OffsetComparator implements java.util.Comparator<HotSpotResolvedJavaField> {
-        @Override
-        public int compare(HotSpotResolvedJavaField o1, HotSpotResolvedJavaField o2) {
-            return o1.offset() - o2.offset();
-        }
-    }
-
-    @Override
-    public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) {
-        if (instanceFields == null) {
-            if (isArray() || isInterface()) {
-                instanceFields = new HotSpotResolvedJavaField[0];
-            } else {
-                final int fieldCount = getFieldCount();
-                ArrayList<HotSpotResolvedJavaField> fieldsArray = new ArrayList<>(fieldCount);
-
-                for (int i = 0; i < fieldCount; i++) {
-                    FieldInfo field = new FieldInfo(i);
-
-                    // We are only interested in instance fields.
-                    if (!field.isStatic()) {
-                        HotSpotResolvedJavaField resolvedJavaField = createField(field.getName(), field.getType(), field.getOffset(), field.getAccessFlags());
-                        fieldsArray.add(resolvedJavaField);
-                    }
-                }
-
-                fieldsArray.sort(new OffsetComparator());
-
-                HotSpotResolvedJavaField[] myFields = fieldsArray.toArray(new HotSpotResolvedJavaField[0]);
-
-                if (mirror() != 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;
-                }
-
-            }
-        }
-        if (!includeSuperclasses) {
-            int myFieldsStart = 0;
-            while (myFieldsStart < instanceFields.length && !instanceFields[myFieldsStart].getDeclaringClass().equals(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
-    public ResolvedJavaField[] getStaticFields() {
-        if (isArray()) {
-            return new HotSpotResolvedJavaField[0];
-        } else {
-            final int fieldCount = getFieldCount();
-            ArrayList<HotSpotResolvedJavaField> fieldsArray = new ArrayList<>(fieldCount);
-
-            for (int i = 0; i < fieldCount; i++) {
-                FieldInfo field = new FieldInfo(i);
-
-                // We are only interested in static fields.
-                if (field.isStatic()) {
-                    HotSpotResolvedJavaField resolvedJavaField = createField(field.getName(), field.getType(), field.getOffset(), field.getAccessFlags());
-                    fieldsArray.add(resolvedJavaField);
-                }
-            }
-
-            fieldsArray.sort(new OffsetComparator());
-            return fieldsArray.toArray(new HotSpotResolvedJavaField[fieldsArray.size()]);
-        }
-    }
-
-    /**
-     * Returns the actual field count of this class's internal {@code InstanceKlass::_fields} array
-     * by walking the array and discounting the generic signature slots at the end of the array.
-     *
-     * <p>
-     * See {@code FieldStreamBase::init_generic_signature_start_slot}
-     */
-    private int getFieldCount() {
-        HotSpotVMConfig config = runtime().getConfig();
-        final long metaspaceFields = unsafe.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset);
-        int metaspaceFieldsLength = unsafe.getInt(metaspaceFields + config.arrayU1LengthOffset);
-        int fieldCount = 0;
-
-        for (int i = 0, index = 0; i < metaspaceFieldsLength; i += config.fieldInfoFieldSlots, index++) {
-            FieldInfo field = new FieldInfo(index);
-            if (field.hasGenericSignature()) {
-                metaspaceFieldsLength--;
-            }
-            fieldCount++;
-        }
-        return fieldCount;
-    }
-
-    @Override
-    public Class<?> mirror() {
-        return javaClass;
-    }
-
-    @Override
-    public String getSourceFileName() {
-        HotSpotVMConfig config = runtime().getConfig();
-        final int sourceFileNameIndex = unsafe.getChar(getMetaspaceKlass() + config.instanceKlassSourceFileNameIndexOffset);
-        if (sourceFileNameIndex == 0) {
-            return null;
-        }
-        return constantPool().lookupUtf8(sourceFileNameIndex);
-    }
-
-    @Override
-    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-        return mirror().getAnnotation(annotationClass);
-    }
+    ResolvedJavaMethod findUniqueConcreteMethod(ResolvedJavaMethod method);
 
     /**
      * Performs a fast-path check that this type is resolved in the context of a given accessing
@@ -745,135 +75,20 @@
      * {@linkplain HotSpotGraalRuntime#lookupType(String, HotSpotResolvedObjectType, boolean)
      * re-resolving} the type.
      */
-    public boolean isDefinitelyResolvedWithRespectTo(ResolvedJavaType accessingClass) {
-        assert accessingClass != null;
-        ResolvedJavaType elementType = getElementalType();
-        if (elementType.isPrimitive()) {
-            // Primitive type resolution is context free.
-            return true;
-        }
-        if (elementType.getName().startsWith("Ljava/")) {
-            // Classes in a java.* package can only be defined by the
-            // boot class loader. This is enforced by ClassLoader.preDefineClass()
-            assert mirror().getClassLoader() == null;
-            return true;
-        }
-        ClassLoader thisCl = mirror().getClassLoader();
-        ClassLoader accessingClassCl = ((HotSpotResolvedObjectType) accessingClass).mirror().getClassLoader();
-        return thisCl == accessingClassCl;
-    }
-
-    @Override
-    public ResolvedJavaType resolve(ResolvedJavaType accessingClass) {
-        if (isDefinitelyResolvedWithRespectTo(requireNonNull(accessingClass))) {
-            return this;
-        }
-        HotSpotResolvedObjectType accessingType = (HotSpotResolvedObjectType) accessingClass;
-        return (ResolvedJavaType) runtime().lookupType(getName(), accessingType, true);
-    }
+    boolean isDefinitelyResolvedWithRespectTo(ResolvedJavaType accessingClass);
 
     /**
      * Gets the metaspace Klass boxed in a {@link JavaConstant}.
      */
-    public JavaConstant klass() {
-        return HotSpotMetaspaceConstant.forMetaspaceObject(runtime().getTarget().wordKind, getMetaspaceKlass(), this, false);
-    }
-
-    public boolean isPrimaryType() {
-        return runtime().getConfig().secondarySuperCacheOffset != superCheckOffset();
-    }
-
-    public int superCheckOffset() {
-        HotSpotVMConfig config = runtime().getConfig();
-        return unsafe.getInt(getMetaspaceKlass() + config.superCheckOffsetOffset);
-    }
-
-    public long prototypeMarkWord() {
-        HotSpotVMConfig config = runtime().getConfig();
-        if (isArray()) {
-            return config.arrayPrototypeMarkWord();
-        } else {
-            return unsafeReadWord(getMetaspaceKlass() + config.prototypeMarkWordOffset);
-        }
-    }
+    JavaConstant klass();
 
-    @Override
-    public ResolvedJavaField findInstanceFieldWithOffset(long offset) {
-        ResolvedJavaField[] declaredFields = getInstanceFields(true);
-        for (ResolvedJavaField field : declaredFields) {
-            if (((HotSpotResolvedJavaField) field).offset() == offset) {
-                return field;
-            }
-        }
-        return null;
-    }
+    boolean isPrimaryType();
 
-    @Override
-    public URL getClassFilePath() {
-        Class<?> cls = mirror();
-        return cls.getResource(MetaUtil.getSimpleName(cls, true).replace('.', '$') + ".class");
-    }
-
-    @Override
-    public boolean isLocal() {
-        return mirror().isLocalClass();
-    }
-
-    @Override
-    public boolean isMember() {
-        return mirror().isMemberClass();
-    }
+    int superCheckOffset();
 
-    @Override
-    public HotSpotResolvedObjectType getEnclosingType() {
-        final Class<?> encl = mirror().getEnclosingClass();
-        return encl == null ? null : fromObjectClass(encl);
-    }
-
-    @Override
-    public ResolvedJavaMethod[] getDeclaredConstructors() {
-        Constructor<?>[] constructors = mirror().getDeclaredConstructors();
-        ResolvedJavaMethod[] result = new ResolvedJavaMethod[constructors.length];
-        for (int i = 0; i < constructors.length; i++) {
-            result[i] = runtime().getHostProviders().getMetaAccess().lookupJavaConstructor(constructors[i]);
-            assert result[i].isConstructor();
-        }
-        return result;
-    }
+    long prototypeMarkWord();
 
-    @Override
-    public ResolvedJavaMethod[] getDeclaredMethods() {
-        Method[] methods = mirror().getDeclaredMethods();
-        ResolvedJavaMethod[] result = new ResolvedJavaMethod[methods.length];
-        for (int i = 0; i < methods.length; i++) {
-            result[i] = runtime().getHostProviders().getMetaAccess().lookupJavaMethod(methods[i]);
-            assert !result[i].isConstructor();
-        }
-        return result;
-    }
+    HotSpotResolvedObjectType getEnclosingType();
 
-    public ResolvedJavaMethod getClassInitializer() {
-        final long metaspaceMethod = runtime().getCompilerToVM().getClassInitializer(getMetaspaceKlass());
-        if (metaspaceMethod != 0L) {
-            return createMethod(metaspaceMethod);
-        }
-        return null;
-    }
-
-    @Override
-    public JavaConstant newArray(int length) {
-        return HotSpotObjectConstant.forObject(Array.newInstance(mirror(), length));
-    }
-
-    @Override
-    public String toString() {
-        return "HotSpotType<" + getName() + ", resolved>";
-    }
-
-    private static final HotSpotResolvedObjectType trustedInterfaceType = fromObjectClass(TrustedInterface.class);
-
-    @Override
-    public boolean isTrustedInterfaceType() {
-        return trustedInterfaceType.isAssignableFrom(this);
-    }
+    ResolvedJavaMethod getClassInitializer();
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl.java	Mon Nov 03 17:03:19 2014 +0100
@@ -0,0 +1,879 @@
+/*
+ * Copyright (c) 2011, 2014, 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 static com.oracle.graal.compiler.common.UnsafeAccess.*;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+import static java.util.Objects.*;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.net.*;
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.hotspot.*;
+
+/**
+ * Implementation of {@link JavaType} for resolved non-primitive HotSpot classes.
+ */
+public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType {
+
+    private static final long serialVersionUID = 3481514353553840471L;
+
+    /**
+     * The Java class this type represents.
+     */
+    private final Class<?> javaClass;
+
+    private HashMap<Long, HotSpotResolvedJavaField> fieldCache;
+    private HashMap<Long, HotSpotResolvedJavaMethod> methodCache;
+    private HotSpotResolvedJavaField[] instanceFields;
+    private HotSpotResolvedObjectTypeImpl[] interfaces;
+    private ConstantPool constantPool;
+    private HotSpotResolvedObjectTypeImpl arrayOfType;
+
+    /**
+     * Gets the Graal mirror for a {@link Class} object.
+     *
+     * @return the {@link HotSpotResolvedJavaType} corresponding to {@code javaClass}
+     */
+    public static HotSpotResolvedObjectTypeImpl fromObjectClass(Class<?> javaClass) {
+        return (HotSpotResolvedObjectTypeImpl) runtime().fromClass(javaClass);
+    }
+
+    /**
+     * Gets the Graal mirror from a HotSpot metaspace Klass native object.
+     *
+     * @param metaspaceKlass a metaspace Klass object boxed in a {@link JavaConstant}
+     * @return the {@link HotSpotResolvedObjectTypeImpl} corresponding to {@code klassConstant}
+     */
+    public static HotSpotResolvedObjectTypeImpl fromMetaspaceKlass(JavaConstant metaspaceKlass) {
+        assert metaspaceKlass.getKind() == Kind.Long;
+        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 HotSpotResolvedObjectTypeImpl fromMetaspaceKlass(long metaspaceKlass) {
+        assert metaspaceKlass != 0;
+        Class<?> javaClass = runtime().getCompilerToVM().getJavaMirror(metaspaceKlass);
+        assert javaClass != null;
+        return fromObjectClass(javaClass);
+    }
+
+    /**
+     * Creates the Graal mirror for a {@link Class} object.
+     *
+     * <p>
+     * <b>NOTE</b>: Creating an instance of this class does not install the mirror for the
+     * {@link Class} type. Use {@link #fromObjectClass(Class)},
+     * {@link #fromMetaspaceKlass(JavaConstant)} or {@link #fromMetaspaceKlass(long)} instead.
+     * </p>
+     *
+     * @param javaClass the Class to create the mirror for
+     */
+    public HotSpotResolvedObjectTypeImpl(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 metaspace Klass for this type.
+     */
+    public long getMetaspaceKlass() {
+        return HotSpotGraalRuntime.unsafeReadWord(javaClass, runtime().getConfig().klassOffset);
+    }
+
+    @Override
+    public int getModifiers() {
+        return mirror().getModifiers();
+    }
+
+    public int getAccessFlags() {
+        HotSpotVMConfig config = runtime().getConfig();
+        return unsafe.getInt(getMetaspaceKlass() + config.klassAccessFlagsOffset);
+    }
+
+    @Override
+    public HotSpotResolvedObjectType getArrayClass() {
+        if (arrayOfType == null) {
+            arrayOfType = fromObjectClass(Array.newInstance(mirror(), 0).getClass());
+        }
+        return arrayOfType;
+    }
+
+    @Override
+    public ResolvedJavaType getComponentType() {
+        Class<?> javaComponentType = mirror().getComponentType();
+        return javaComponentType == null ? null : fromClass(javaComponentType);
+    }
+
+    @Override
+    public HotSpotResolvedObjectType findUniqueConcreteSubtype() {
+        HotSpotVMConfig config = runtime().getConfig();
+        if (isArray()) {
+            return getElementalType().isFinal() ? this : null;
+        } else if (isInterface()) {
+            HotSpotResolvedObjectTypeImpl type = getSingleImplementor();
+            if (type == null) {
+                return null;
+            }
+
+            /*
+             * If the implementor field contains itself that indicates that the interface has more
+             * than one implementors (see: InstanceKlass::add_implementor). The isInterface check
+             * takes care of this fact since this class is an interface.
+             */
+            if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) {
+                return null;
+            }
+            return type;
+        } else {
+            HotSpotResolvedObjectTypeImpl type = this;
+            while (type.isAbstract()) {
+                long subklass = type.getSubklass();
+                if (subklass == 0 || unsafeReadWord(subklass + config.nextSiblingOffset) != 0) {
+                    return null;
+                }
+                type = fromMetaspaceKlass(subklass);
+            }
+            if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) {
+                return null;
+            }
+            return type;
+        }
+    }
+
+    /**
+     * Returns if type {@code type} is a leaf class. This is the case if the
+     * {@code Klass::_subklass} field of the underlying class is zero.
+     *
+     * @return true if the type is a leaf class
+     */
+    private boolean isLeafClass() {
+        return getSubklass() == 0;
+    }
+
+    /**
+     * Returns the {@code Klass::_subklass} field of the underlying metaspace klass for the given
+     * type {@code type}.
+     *
+     * @return value of the subklass field as metaspace klass pointer
+     */
+    private long getSubklass() {
+        return unsafeReadWord(getMetaspaceKlass() + runtime().getConfig().subklassOffset);
+    }
+
+    @Override
+    public HotSpotResolvedObjectTypeImpl getSuperclass() {
+        Class<?> javaSuperclass = mirror().getSuperclass();
+        return javaSuperclass == null ? null : (HotSpotResolvedObjectTypeImpl) fromObjectClass(javaSuperclass);
+    }
+
+    @Override
+    public HotSpotResolvedObjectTypeImpl[] getInterfaces() {
+        if (interfaces == null) {
+            Class<?>[] javaInterfaces = mirror().getInterfaces();
+            HotSpotResolvedObjectTypeImpl[] result = new HotSpotResolvedObjectTypeImpl[javaInterfaces.length];
+            for (int i = 0; i < javaInterfaces.length; i++) {
+                result[i] = fromObjectClass(javaInterfaces[i]);
+            }
+            interfaces = result;
+        }
+        return interfaces;
+    }
+
+    @Override
+    public HotSpotResolvedObjectTypeImpl getSingleImplementor() {
+        if (!isInterface()) {
+            throw new GraalInternalError("Cannot call getImplementor() on a non-interface type: " + this);
+        }
+        final long implementorMetaspaceKlass = runtime().getCompilerToVM().getKlassImplementor(getMetaspaceKlass());
+
+        // No implementor.
+        if (implementorMetaspaceKlass == 0) {
+            return null;
+        }
+
+        return fromMetaspaceKlass(implementorMetaspaceKlass);
+    }
+
+    public HotSpotResolvedObjectTypeImpl getSupertype() {
+        if (isArray()) {
+            ResolvedJavaType componentType = getComponentType();
+            if (mirror() == Object[].class || componentType.isPrimitive()) {
+                return fromObjectClass(Object.class);
+            }
+            return (HotSpotResolvedObjectTypeImpl) ((HotSpotResolvedObjectTypeImpl) componentType).getSupertype().getArrayClass();
+        }
+        if (isInterface()) {
+            return fromObjectClass(Object.class);
+        }
+        return getSuperclass();
+    }
+
+    @Override
+    public HotSpotResolvedObjectType findLeastCommonAncestor(ResolvedJavaType otherType) {
+        if (otherType.isPrimitive()) {
+            return null;
+        } else {
+            HotSpotResolvedObjectTypeImpl t1 = this;
+            HotSpotResolvedObjectTypeImpl t2 = (HotSpotResolvedObjectTypeImpl) otherType;
+            while (true) {
+                if (t1.isAssignableFrom(t2)) {
+                    return t1;
+                }
+                if (t2.isAssignableFrom(t1)) {
+                    return t2;
+                }
+                t1 = t1.getSupertype();
+                t2 = t2.getSupertype();
+            }
+        }
+    }
+
+    @Override
+    public HotSpotResolvedObjectType asExactType() {
+        if (isArray()) {
+            return getComponentType().asExactType() != null ? this : null;
+        }
+        return isFinal() ? this : null;
+    }
+
+    @Override
+    public JavaConstant getEncoding(Representation r) {
+        switch (r) {
+            case JavaClass:
+                return HotSpotObjectConstant.forObject(mirror());
+            case ObjectHub:
+                return klass();
+            default:
+                throw GraalInternalError.shouldNotReachHere("unexpected representation " + r);
+        }
+    }
+
+    @Override
+    public boolean hasFinalizableSubclass() {
+        assert !isArray();
+        return runtime().getCompilerToVM().hasFinalizableSubclass(getMetaspaceKlass());
+    }
+
+    @Override
+    public boolean hasFinalizer() {
+        HotSpotVMConfig config = runtime().getConfig();
+        return (getAccessFlags() & config.klassHasFinalizerFlag) != 0;
+    }
+
+    @Override
+    public boolean isPrimitive() {
+        return false;
+    }
+
+    @Override
+    public boolean isArray() {
+        return mirror().isArray();
+    }
+
+    @Override
+    public boolean isInitialized() {
+        return isArray() ? true : getInitState() == runtime().getConfig().instanceKlassStateFullyInitialized;
+    }
+
+    @Override
+    public boolean isLinked() {
+        return isArray() ? true : getInitState() >= runtime().getConfig().instanceKlassStateLinked;
+    }
+
+    /**
+     * Returns the value of the state field {@code InstanceKlass::_init_state} of the metaspace
+     * klass.
+     *
+     * @return state field value of this type
+     */
+    private int getInitState() {
+        assert !isArray() : "_init_state only exists in InstanceKlass";
+        return unsafe.getByte(getMetaspaceKlass() + runtime().getConfig().instanceKlassInitStateOffset) & 0xFF;
+    }
+
+    @Override
+    public void initialize() {
+        if (!isInitialized()) {
+            unsafe.ensureClassInitialized(mirror());
+            assert isInitialized();
+        }
+    }
+
+    @Override
+    public boolean isInstance(JavaConstant obj) {
+        if (obj.getKind() == Kind.Object && !obj.isNull()) {
+            return mirror().isInstance(HotSpotObjectConstant.asObject(obj));
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isInstanceClass() {
+        return !isArray() && !isInterface();
+    }
+
+    @Override
+    public boolean isInterface() {
+        return mirror().isInterface();
+    }
+
+    @Override
+    public boolean isAssignableFrom(ResolvedJavaType other) {
+        assert other != null;
+        if (other instanceof HotSpotResolvedObjectTypeImpl) {
+            HotSpotResolvedObjectTypeImpl otherType = (HotSpotResolvedObjectTypeImpl) other;
+            return mirror().isAssignableFrom(otherType.mirror());
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isJavaLangObject() {
+        return javaClass.equals(Object.class);
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.Object;
+    }
+
+    @Override
+    public ResolvedJavaMethod resolveConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) {
+        ResolvedJavaMethod resolvedMethod = resolveMethod(method, callerType, true);
+        if (resolvedMethod == null || resolvedMethod.isAbstract()) {
+            return null;
+        }
+        return resolvedMethod;
+    }
+
+    @Override
+    public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType, boolean includeAbstract) {
+        if (!includeAbstract) {
+            return resolveConcreteMethod(method, callerType);
+        }
+        assert !callerType.isArray();
+        if (!method.isAbstract() && method.getDeclaringClass().equals(this) && method.isPublic()) {
+            return method;
+        }
+        if (!method.getDeclaringClass().isAssignableFrom(this)) {
+            return null;
+        }
+        HotSpotResolvedJavaMethodImpl hotSpotMethod = (HotSpotResolvedJavaMethodImpl) method;
+        HotSpotResolvedObjectTypeImpl hotSpotCallerType = (HotSpotResolvedObjectTypeImpl) callerType;
+        final long resolvedMetaspaceMethod = runtime().getCompilerToVM().resolveMethod(getMetaspaceKlass(), hotSpotMethod.getMetaspaceMethod(), hotSpotCallerType.getMetaspaceKlass());
+        if (resolvedMetaspaceMethod == 0) {
+            return null;
+        }
+        return HotSpotResolvedJavaMethodImpl.fromMetaspace(resolvedMetaspaceMethod);
+    }
+
+    public ConstantPool constantPool() {
+        if (constantPool == null) {
+            final long metaspaceConstantPool = unsafe.getAddress(getMetaspaceKlass() + runtime().getConfig().instanceKlassConstantsOffset);
+            constantPool = new HotSpotConstantPool(metaspaceConstantPool);
+        }
+        return constantPool;
+    }
+
+    /**
+     * 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). Must not
+     * be called if this is an array or interface type.
+     */
+    public int instanceSize() {
+        assert !isArray();
+        assert !isInterface();
+
+        HotSpotVMConfig config = runtime().getConfig();
+        final int layoutHelper = unsafe.getInt(getMetaspaceKlass() + 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) {
+        HotSpotResolvedJavaMethod method = null;
+        if (methodCache == null) {
+            methodCache = new HashMap<>(8);
+        } else {
+            method = methodCache.get(metaspaceMethod);
+        }
+        if (method == null) {
+            method = new HotSpotResolvedJavaMethodImpl(this, metaspaceMethod);
+            methodCache.put(metaspaceMethod, method);
+        }
+        return method;
+    }
+
+    public int getVtableLength() {
+        HotSpotVMConfig config = runtime().getConfig();
+        if (isInterface() || isArray()) {
+            /* Everything has the core vtable of java.lang.Object */
+            return config.baseVtableLength;
+        }
+        int result = unsafe.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) / (config.vtableEntrySize / config.heapWordSize);
+        assert result >= config.baseVtableLength : unsafe.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) + " " + config.vtableEntrySize;
+        return result;
+    }
+
+    /**
+     * Gets the mask used to filter out HotSpot internal flags for fields when a {@link Field}
+     * object is created. This is the value of {@code JVM_RECOGNIZED_FIELD_MODIFIERS} in
+     * {@code jvm.h}, <b>not</b> {@link Modifier#fieldModifiers()}.
+     */
+    public static int getReflectionFieldModifiers() {
+        return runtime().getConfig().recognizedFieldModifiers;
+    }
+
+    public synchronized HotSpotResolvedJavaField createField(String fieldName, JavaType type, long offset, int rawFlags) {
+        HotSpotResolvedJavaField result = null;
+
+        final int flags = rawFlags & getReflectionFieldModifiers();
+
+        final long id = offset + ((long) flags << 32);
+
+        // (thomaswue) Must cache the fields, because the local load elimination only works if the
+        // objects from two field lookups are identical.
+        if (fieldCache == null) {
+            fieldCache = new HashMap<>(8);
+        } else {
+            result = fieldCache.get(id);
+        }
+
+        if (result == null) {
+            result = new HotSpotResolvedJavaField(this, fieldName, type, offset, rawFlags);
+            fieldCache.put(id, result);
+        } else {
+            assert result.getName().equals(fieldName);
+            // assert result.getType().equals(type);
+            assert result.offset() == offset;
+            assert result.getModifiers() == flags;
+        }
+
+        return result;
+    }
+
+    @Override
+    public ResolvedJavaMethod findUniqueConcreteMethod(ResolvedJavaMethod method) {
+        HotSpotResolvedJavaMethod hmethod = (HotSpotResolvedJavaMethod) method;
+        HotSpotResolvedObjectTypeImpl declaredHolder = hmethod.getDeclaringClass();
+        /*
+         * Sometimes the receiver type in the graph hasn't stabilized to a subtype of declared
+         * holder, usually because of phis, so make sure that the type is related to the declared
+         * type before using it for lookup. Unlinked types should also be ignored because we can't
+         * resolve the proper method to invoke. Generally unlinked types in invokes should result in
+         * a deopt instead since they can't really be used if they aren't linked yet.
+         */
+        if (!declaredHolder.isAssignableFrom(this) || this.isArray() || this.equals(declaredHolder) || !isLinked() || isInterface()) {
+            return hmethod.uniqueConcreteMethod(declaredHolder);
+        }
+        /*
+         * The holder may be a subtype of the decaredHolder so make sure to resolve the method to
+         * the correct method for the subtype.
+         */
+        HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) resolveMethod(hmethod, this, true);
+        if (resolvedMethod == null) {
+            // The type isn't known to implement the method.
+            return null;
+        }
+
+        return resolvedMethod.uniqueConcreteMethod(this);
+    }
+
+    /**
+     * This class represents the field information for one field contained in the fields array of an
+     * {@code InstanceKlass}. The implementation is similar to the native {@code FieldInfo} class.
+     */
+    private class FieldInfo {
+        /**
+         * Native pointer into the array of Java shorts.
+         */
+        private final long metaspaceData;
+
+        /**
+         * Creates a field info for the field in the fields array at index {@code index}.
+         *
+         * @param index index to the fields array
+         */
+        public FieldInfo(int index) {
+            HotSpotVMConfig config = runtime().getConfig();
+            // Get Klass::_fields
+            final long metaspaceFields = unsafe.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset);
+            assert config.fieldInfoFieldSlots == 6 : "revisit the field parsing code";
+            metaspaceData = metaspaceFields + config.arrayU2DataOffset + config.fieldInfoFieldSlots * Short.BYTES * index;
+        }
+
+        private int getAccessFlags() {
+            return readFieldSlot(runtime().getConfig().fieldInfoAccessFlagsOffset);
+        }
+
+        private int getNameIndex() {
+            return readFieldSlot(runtime().getConfig().fieldInfoNameIndexOffset);
+        }
+
+        private int getSignatureIndex() {
+            return readFieldSlot(runtime().getConfig().fieldInfoSignatureIndexOffset);
+        }
+
+        public int getOffset() {
+            HotSpotVMConfig config = runtime().getConfig();
+            final int lowPacked = readFieldSlot(config.fieldInfoLowPackedOffset);
+            final int highPacked = readFieldSlot(config.fieldInfoHighPackedOffset);
+            final int offset = ((highPacked << Short.SIZE) | lowPacked) >> config.fieldInfoTagSize;
+            return offset;
+        }
+
+        /**
+         * Helper method to read an entry (slot) from the field array. Currently field info is laid
+         * on top an array of Java shorts.
+         */
+        private int readFieldSlot(int index) {
+            return unsafe.getChar(metaspaceData + Short.BYTES * index);
+        }
+
+        /**
+         * Returns the name of this field as a {@link String}. If the field is an internal field the
+         * name index is pointing into the vmSymbols table.
+         */
+        public String getName() {
+            final int nameIndex = getNameIndex();
+            return isInternal() ? HotSpotVmSymbols.symbolAt(nameIndex) : constantPool().lookupUtf8(nameIndex);
+        }
+
+        /**
+         * Returns the signature of this field as {@link String}. If the field is an internal field
+         * the signature index is pointing into the vmSymbols table.
+         */
+        public String getSignature() {
+            final int signatureIndex = getSignatureIndex();
+            return isInternal() ? HotSpotVmSymbols.symbolAt(signatureIndex) : constantPool().lookupUtf8(signatureIndex);
+        }
+
+        public JavaType getType() {
+            String signature = getSignature();
+            return runtime().lookupType(signature, HotSpotResolvedObjectTypeImpl.this, false);
+        }
+
+        private boolean isInternal() {
+            return (getAccessFlags() & runtime().getConfig().jvmAccFieldInternal) != 0;
+        }
+
+        public boolean isStatic() {
+            return Modifier.isStatic(getAccessFlags());
+        }
+
+        public boolean hasGenericSignature() {
+            return (getAccessFlags() & runtime().getConfig().jvmAccFieldHasGenericSignature) != 0;
+        }
+    }
+
+    private static class OffsetComparator implements java.util.Comparator<HotSpotResolvedJavaField> {
+        @Override
+        public int compare(HotSpotResolvedJavaField o1, HotSpotResolvedJavaField o2) {
+            return o1.offset() - o2.offset();
+        }
+    }
+
+    @Override
+    public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) {
+        if (instanceFields == null) {
+            if (isArray() || isInterface()) {
+                instanceFields = new HotSpotResolvedJavaField[0];
+            } else {
+                final int fieldCount = getFieldCount();
+                ArrayList<HotSpotResolvedJavaField> fieldsArray = new ArrayList<>(fieldCount);
+
+                for (int i = 0; i < fieldCount; i++) {
+                    FieldInfo field = new FieldInfo(i);
+
+                    // We are only interested in instance fields.
+                    if (!field.isStatic()) {
+                        HotSpotResolvedJavaField resolvedJavaField = createField(field.getName(), field.getType(), field.getOffset(), field.getAccessFlags());
+                        fieldsArray.add(resolvedJavaField);
+                    }
+                }
+
+                fieldsArray.sort(new OffsetComparator());
+
+                HotSpotResolvedJavaField[] myFields = fieldsArray.toArray(new HotSpotResolvedJavaField[0]);
+
+                if (mirror() != 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;
+                }
+
+            }
+        }
+        if (!includeSuperclasses) {
+            int myFieldsStart = 0;
+            while (myFieldsStart < instanceFields.length && !instanceFields[myFieldsStart].getDeclaringClass().equals(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
+    public ResolvedJavaField[] getStaticFields() {
+        if (isArray()) {
+            return new HotSpotResolvedJavaField[0];
+        } else {
+            final int fieldCount = getFieldCount();
+            ArrayList<HotSpotResolvedJavaField> fieldsArray = new ArrayList<>(fieldCount);
+
+            for (int i = 0; i < fieldCount; i++) {
+                FieldInfo field = new FieldInfo(i);
+
+                // We are only interested in static fields.
+                if (field.isStatic()) {
+                    HotSpotResolvedJavaField resolvedJavaField = createField(field.getName(), field.getType(), field.getOffset(), field.getAccessFlags());
+                    fieldsArray.add(resolvedJavaField);
+                }
+            }
+
+            fieldsArray.sort(new OffsetComparator());
+            return fieldsArray.toArray(new HotSpotResolvedJavaField[fieldsArray.size()]);
+        }
+    }
+
+    /**
+     * Returns the actual field count of this class's internal {@code InstanceKlass::_fields} array
+     * by walking the array and discounting the generic signature slots at the end of the array.
+     *
+     * <p>
+     * See {@code FieldStreamBase::init_generic_signature_start_slot}
+     */
+    private int getFieldCount() {
+        HotSpotVMConfig config = runtime().getConfig();
+        final long metaspaceFields = unsafe.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset);
+        int metaspaceFieldsLength = unsafe.getInt(metaspaceFields + config.arrayU1LengthOffset);
+        int fieldCount = 0;
+
+        for (int i = 0, index = 0; i < metaspaceFieldsLength; i += config.fieldInfoFieldSlots, index++) {
+            FieldInfo field = new FieldInfo(index);
+            if (field.hasGenericSignature()) {
+                metaspaceFieldsLength--;
+            }
+            fieldCount++;
+        }
+        return fieldCount;
+    }
+
+    @Override
+    public Class<?> mirror() {
+        return javaClass;
+    }
+
+    @Override
+    public String getSourceFileName() {
+        HotSpotVMConfig config = runtime().getConfig();
+        final int sourceFileNameIndex = unsafe.getChar(getMetaspaceKlass() + config.instanceKlassSourceFileNameIndexOffset);
+        if (sourceFileNameIndex == 0) {
+            return null;
+        }
+        return constantPool().lookupUtf8(sourceFileNameIndex);
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        return mirror().getAnnotation(annotationClass);
+    }
+
+    /**
+     * Performs a fast-path check that this type is resolved in the context of a given accessing
+     * class. A negative result does not mean this type is not resolved with respect to
+     * {@code accessingClass}. That can only be determined by
+     * {@linkplain HotSpotGraalRuntime#lookupType(String, HotSpotResolvedObjectType, boolean)
+     * re-resolving} the type.
+     */
+    public boolean isDefinitelyResolvedWithRespectTo(ResolvedJavaType accessingClass) {
+        assert accessingClass != null;
+        ResolvedJavaType elementType = getElementalType();
+        if (elementType.isPrimitive()) {
+            // Primitive type resolution is context free.
+            return true;
+        }
+        if (elementType.getName().startsWith("Ljava/")) {
+            // Classes in a java.* package can only be defined by the
+            // boot class loader. This is enforced by ClassLoader.preDefineClass()
+            assert mirror().getClassLoader() == null;
+            return true;
+        }
+        ClassLoader thisCl = mirror().getClassLoader();
+        ClassLoader accessingClassCl = ((HotSpotResolvedObjectTypeImpl) accessingClass).mirror().getClassLoader();
+        return thisCl == accessingClassCl;
+    }
+
+    @Override
+    public ResolvedJavaType resolve(ResolvedJavaType accessingClass) {
+        if (isDefinitelyResolvedWithRespectTo(requireNonNull(accessingClass))) {
+            return this;
+        }
+        HotSpotResolvedObjectTypeImpl accessingType = (HotSpotResolvedObjectTypeImpl) accessingClass;
+        return (ResolvedJavaType) runtime().lookupType(getName(), accessingType, true);
+    }
+
+    /**
+     * Gets the metaspace Klass boxed in a {@link JavaConstant}.
+     */
+    public JavaConstant klass() {
+        return HotSpotMetaspaceConstant.forMetaspaceObject(runtime().getTarget().wordKind, getMetaspaceKlass(), this, false);
+    }
+
+    public boolean isPrimaryType() {
+        return runtime().getConfig().secondarySuperCacheOffset != superCheckOffset();
+    }
+
+    public int superCheckOffset() {
+        HotSpotVMConfig config = runtime().getConfig();
+        return unsafe.getInt(getMetaspaceKlass() + config.superCheckOffsetOffset);
+    }
+
+    public long prototypeMarkWord() {
+        HotSpotVMConfig config = runtime().getConfig();
+        if (isArray()) {
+            return config.arrayPrototypeMarkWord();
+        } else {
+            return unsafeReadWord(getMetaspaceKlass() + config.prototypeMarkWordOffset);
+        }
+    }
+
+    @Override
+    public ResolvedJavaField findInstanceFieldWithOffset(long offset) {
+        ResolvedJavaField[] declaredFields = getInstanceFields(true);
+        for (ResolvedJavaField field : declaredFields) {
+            if (((HotSpotResolvedJavaField) field).offset() == offset) {
+                return field;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public URL getClassFilePath() {
+        Class<?> cls = mirror();
+        return cls.getResource(MetaUtil.getSimpleName(cls, true).replace('.', '$') + ".class");
+    }
+
+    @Override
+    public boolean isLocal() {
+        return mirror().isLocalClass();
+    }
+
+    @Override
+    public boolean isMember() {
+        return mirror().isMemberClass();
+    }
+
+    @Override
+    public HotSpotResolvedObjectTypeImpl getEnclosingType() {
+        final Class<?> encl = mirror().getEnclosingClass();
+        return encl == null ? null : fromObjectClass(encl);
+    }
+
+    @Override
+    public ResolvedJavaMethod[] getDeclaredConstructors() {
+        Constructor<?>[] constructors = mirror().getDeclaredConstructors();
+        ResolvedJavaMethod[] result = new ResolvedJavaMethod[constructors.length];
+        for (int i = 0; i < constructors.length; i++) {
+            result[i] = runtime().getHostProviders().getMetaAccess().lookupJavaConstructor(constructors[i]);
+            assert result[i].isConstructor();
+        }
+        return result;
+    }
+
+    @Override
+    public ResolvedJavaMethod[] getDeclaredMethods() {
+        Method[] methods = mirror().getDeclaredMethods();
+        ResolvedJavaMethod[] result = new ResolvedJavaMethod[methods.length];
+        for (int i = 0; i < methods.length; i++) {
+            result[i] = runtime().getHostProviders().getMetaAccess().lookupJavaMethod(methods[i]);
+            assert !result[i].isConstructor();
+        }
+        return result;
+    }
+
+    public ResolvedJavaMethod getClassInitializer() {
+        final long metaspaceMethod = runtime().getCompilerToVM().getClassInitializer(getMetaspaceKlass());
+        if (metaspaceMethod != 0L) {
+            return createMethod(metaspaceMethod);
+        }
+        return null;
+    }
+
+    @Override
+    public JavaConstant newArray(int length) {
+        return HotSpotObjectConstant.forObject(Array.newInstance(mirror(), length));
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotType<" + getName() + ", resolved>";
+    }
+
+    private static final HotSpotResolvedObjectTypeImpl trustedInterfaceType = fromObjectClass(TrustedInterface.class);
+
+    @Override
+    public boolean isTrustedInterfaceType() {
+        return trustedInterfaceType.isAssignableFrom(this);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Mon Nov 03 17:03:19 2014 +0100
@@ -42,7 +42,7 @@
     /**
      * Gets the Graal mirror for a {@link Kind}.
      *
-     * @return the {@link HotSpotResolvedObjectType} corresponding to {@code kind}
+     * @return the {@link HotSpotResolvedObjectTypeImpl} corresponding to {@code kind}
      */
     public static ResolvedJavaType fromKind(Kind kind) {
         Class<?> javaClass = kind.toJavaClass();
@@ -71,12 +71,12 @@
     }
 
     @Override
-    public HotSpotResolvedObjectType getArrayClass() {
+    public HotSpotResolvedObjectTypeImpl getArrayClass() {
         if (kind == Kind.Void) {
             return null;
         }
         Class<?> javaArrayMirror = Array.newInstance(mirror(), 0).getClass();
-        return HotSpotResolvedObjectType.fromObjectClass(javaArrayMirror);
+        return HotSpotResolvedObjectTypeImpl.fromObjectClass(javaArrayMirror);
     }
 
     public ResolvedJavaType getElementalType() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Mon Nov 03 17:03:19 2014 +0100
@@ -133,8 +133,8 @@
             return false;
         }
 
-        if (type instanceof HotSpotResolvedObjectType) {
-            return ((HotSpotResolvedObjectType) type).isDefinitelyResolvedWithRespectTo(accessingClass);
+        if (type instanceof HotSpotResolvedObjectTypeImpl) {
+            return ((HotSpotResolvedObjectTypeImpl) type).isDefinitelyResolvedWithRespectTo(accessingClass);
         }
         return true;
     }
@@ -160,7 +160,7 @@
 
         ResolvedJavaType type = parameterTypes[index];
         if (!checkValidCache(type, accessingClass)) {
-            type = (ResolvedJavaType) runtime().lookupType(parameters.get(index), (HotSpotResolvedObjectType) accessingClass, true);
+            type = (ResolvedJavaType) runtime().lookupType(parameters.get(index), (HotSpotResolvedObjectTypeImpl) accessingClass, true);
             parameterTypes[index] = type;
         }
         return type;
@@ -185,7 +185,7 @@
             return getUnresolvedOrPrimitiveType(returnType);
         }
         if (!checkValidCache(returnTypeCache, accessingClass)) {
-            returnTypeCache = (ResolvedJavaType) runtime().lookupType(returnType, (HotSpotResolvedObjectType) accessingClass, true);
+            returnTypeCache = (ResolvedJavaType) runtime().lookupType(returnType, (HotSpotResolvedObjectTypeImpl) accessingClass, true);
         }
         return returnTypeCache;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedJavaType.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedJavaType.java	Mon Nov 03 17:03:19 2014 +0100
@@ -85,6 +85,6 @@
 
     @Override
     public ResolvedJavaType resolve(ResolvedJavaType accessingClass) {
-        return (ResolvedJavaType) runtime().lookupType(getName(), (HotSpotResolvedObjectType) accessingClass, true);
+        return (ResolvedJavaType) runtime().lookupType(getName(), (HotSpotResolvedObjectTypeImpl) accessingClass, true);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java	Mon Nov 03 17:03:19 2014 +0100
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
@@ -65,9 +65,8 @@
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forJavaClass, ValueNode forObject) {
         if (forJavaClass.isConstant()) {
-            Class<?> c = (Class<?>) HotSpotObjectConstant.asObject(forJavaClass.asJavaConstant());
-            if (c != null && !c.isPrimitive()) {
-                HotSpotResolvedObjectType type = HotSpotResolvedObjectType.fromObjectClass(c);
+            ResolvedJavaType type = tool.getConstantReflection().asJavaType(forJavaClass.asJavaConstant());
+            if (type != null && !type.isPrimitive()) {
                 return CheckCastNode.create(type, forObject, null, false);
             }
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java	Mon Nov 03 17:03:19 2014 +0100
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
@@ -61,16 +61,16 @@
         ValueNode javaClass = getJavaClass();
         if (javaClass.isConstant()) {
             ValueNode object = getObject();
-            Class<?> c = (Class<?>) HotSpotObjectConstant.asObject(javaClass.asJavaConstant());
-            if (c != null) {
-                if (c.isPrimitive()) {
+            ConstantReflectionProvider constantReflection = tool.getConstantReflection();
+            ResolvedJavaType type = constantReflection.asJavaType(javaClass.asJavaConstant());
+            if (type != null) {
+                if (type.isPrimitive()) {
                     return ConstantNode.forBoolean(false);
                 }
                 if (object.isConstant()) {
-                    Object o = HotSpotObjectConstant.asObject(object.asJavaConstant());
-                    return ConstantNode.forBoolean(o != null && c.isInstance(o));
+                    JavaConstant c = object.asJavaConstant();
+                    return ConstantNode.forBoolean(c.isNonNull() && type.isInstance(c));
                 }
-                HotSpotResolvedObjectType type = HotSpotResolvedObjectType.fromObjectClass(c);
                 InstanceOfNode instanceOf = InstanceOfNode.create(type, object, null);
                 return ConditionalNode.create(instanceOf, ConstantNode.forBoolean(true), ConstantNode.forBoolean(false));
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java	Mon Nov 03 17:03:19 2014 +0100
@@ -58,7 +58,7 @@
     @Override
     public boolean inferStamp() {
         if (stamp() == defaultStamp && hub.isConstant()) {
-            updateStamp(StampFactory.exactNonNull(HotSpotResolvedObjectType.fromMetaspaceKlass(hub.asJavaConstant())));
+            updateStamp(StampFactory.exactNonNull(HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(hub.asJavaConstant())));
             return true;
         }
         return false;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java	Mon Nov 03 17:03:19 2014 +0100
@@ -56,7 +56,7 @@
     @Override
     public boolean inferStamp() {
         if (stamp() == defaultStamp && hub.isConstant()) {
-            updateStamp(StampFactory.exactNonNull(HotSpotResolvedObjectType.fromMetaspaceKlass(hub.asJavaConstant())));
+            updateStamp(StampFactory.exactNonNull(HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(hub.asJavaConstant())));
             return true;
         }
         return false;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java	Mon Nov 03 17:03:19 2014 +0100
@@ -60,7 +60,7 @@
     @Override
     public boolean inferStamp() {
         if (stamp() == defaultStamp && hub.isConstant()) {
-            updateStamp(StampFactory.exactNonNull(HotSpotResolvedObjectType.fromMetaspaceKlass(hub.asJavaConstant())));
+            updateStamp(StampFactory.exactNonNull(HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(hub.asJavaConstant())));
             return true;
         }
         return false;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java	Mon Nov 03 16:08:06 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java	Mon Nov 03 17:03:19 2014 +0100
@@ -25,6 +25,7 @@
 import static com.oracle.graal.compiler.GraalCompiler.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.ResolvedJavaType.Representation;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
@@ -100,7 +101,7 @@
                     if (!method.ignoredBySecurityStackWalk()) {
                         // We have reached the desired frame; return the holder class.
                         HotSpotResolvedObjectType callerClass = method.getDeclaringClass();
-                        return ConstantNode.forConstant(HotSpotObjectConstant.forObject(callerClass.mirror()), metaAccess);
+                        return ConstantNode.forConstant(callerClass.getEncoding(Representation.JavaClass), metaAccess);
                     }
                     break;
             }
--- a/src/share/vm/classfile/systemDictionary.hpp	Mon Nov 03 16:08:06 2014 +0100
+++ b/src/share/vm/classfile/systemDictionary.hpp	Mon Nov 03 17:03:19 2014 +0100
@@ -198,7 +198,7 @@
   GRAAL_ONLY(do_klass(HotSpotInstalledCode_klass,            com_oracle_graal_hotspot_meta_HotSpotInstalledCode,           Graal)) \
   GRAAL_ONLY(do_klass(HotSpotNmethod_klass,                  com_oracle_graal_hotspot_meta_HotSpotNmethod,                 Graal)) \
   GRAAL_ONLY(do_klass(HotSpotResolvedJavaMethodImpl_klass,   com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethodImpl,  Graal)) \
-  GRAAL_ONLY(do_klass(HotSpotResolvedObjectType_klass,       com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType,      Graal)) \
+  GRAAL_ONLY(do_klass(HotSpotResolvedObjectTypeImpl_klass,   com_oracle_graal_hotspot_meta_HotSpotResolvedObjectTypeImpl,  Graal)) \
   GRAAL_ONLY(do_klass(HotSpotMonitorValue_klass,             com_oracle_graal_hotspot_meta_HotSpotMonitorValue,            Graal)) \
   GRAAL_ONLY(do_klass(HotSpotCompressedNullConstant_klass,   com_oracle_graal_hotspot_meta_HotSpotCompressedNullConstant,  Graal)) \
   GRAAL_ONLY(do_klass(HotSpotObjectConstant_klass,           com_oracle_graal_hotspot_meta_HotSpotObjectConstant,          Graal)) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Mon Nov 03 16:08:06 2014 +0100
+++ b/src/share/vm/classfile/vmSymbols.hpp	Mon Nov 03 17:03:19 2014 +0100
@@ -305,7 +305,7 @@
   GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotInstalledCode,       "com/oracle/graal/hotspot/meta/HotSpotInstalledCode"))            \
   GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotNmethod,             "com/oracle/graal/hotspot/meta/HotSpotNmethod"))                  \
   GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethodImpl, "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl")) \
-  GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType,  "com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType"))       \
+  GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotResolvedObjectTypeImpl, "com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl")) \
   GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotMonitorValue,        "com/oracle/graal/hotspot/meta/HotSpotMonitorValue"))             \
   GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotCompressedNullConstant, "com/oracle/graal/hotspot/meta/HotSpotCompressedNullConstant")) \
   GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotObjectConstant,      "com/oracle/graal/hotspot/meta/HotSpotObjectConstant"))           \
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Mon Nov 03 16:08:06 2014 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Mon Nov 03 17:03:19 2014 +0100
@@ -166,8 +166,8 @@
 }
 
 static void record_metadata_reference(oop obj, jlong prim, jboolean compressed, OopRecorder* oop_recorder) {
-  if (obj->is_a(HotSpotResolvedObjectType::klass())) {
-    Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(obj));
+  if (obj->is_a(HotSpotResolvedObjectTypeImpl::klass())) {
+    Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj));
     if (compressed) {
       assert(Klass::decode_klass((narrowKlass) prim) == klass, err_msg("%s @ " INTPTR_FORMAT " != " INTPTR_FORMAT, klass->name()->as_C_string(), p2i(klass), prim));
     } else {
@@ -186,7 +186,7 @@
   }
 }
 
-// Records any Metadata values embedded in a Constant (e.g., the value returned by HotSpotResolvedObjectType.klass()).
+// Records any Metadata values embedded in a Constant (e.g., the value returned by HotSpotResolvedObjectTypeImpl.klass()).
 static void record_metadata_in_constant(oop constant, OopRecorder* oop_recorder) {
   if (constant->is_a(HotSpotMetaspaceConstant::klass())) {
     oop obj = HotSpotMetaspaceConstant::metaspaceObject(constant);
@@ -324,7 +324,7 @@
   } else if (value->is_a(VirtualObject::klass())) {
     oop type = VirtualObject::type(value);
     int id = VirtualObject::id(value);
-    oop javaMirror = HotSpotResolvedObjectType::javaClass(type);
+    oop javaMirror = HotSpotResolvedObjectTypeImpl::javaClass(type);
     Klass* klass = java_lang_Class::as_Klass(javaMirror);
     bool isLongArray = klass == Universe::longArrayKlassObj();
 
@@ -653,15 +653,15 @@
 
 void CodeInstaller::assumption_NoFinalizableSubclass(Handle assumption) {
   Handle receiverType_handle = Assumptions_NoFinalizableSubclass::receiverType(assumption());
-  Klass* receiverType = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(receiverType_handle));
+  Klass* receiverType = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::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 = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(context_handle));
-  Klass* subtype = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(subtype_handle));
+  Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(context_handle));
+  Klass* subtype = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(subtype_handle));
 
   if (context != subtype) {
     assert(context->is_abstract(), "");
@@ -676,7 +676,7 @@
   Handle context_handle = Assumptions_ConcreteMethod::context(assumption());
 
   methodHandle impl = getMethodFromHotSpotMethod(impl_handle());
-  Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(context_handle));
+  Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(context_handle));
 
   _dependencies->assert_unique_concrete_method(context, impl());
 }
--- a/src/share/vm/graal/graalJavaAccess.hpp	Mon Nov 03 16:08:06 2014 +0100
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Mon Nov 03 17:03:19 2014 +0100
@@ -48,8 +48,8 @@
  */
 
 #define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, typeArrayOop_field, objArrayOop_field, static_oop_field, static_int_field) \
-  start_class(HotSpotResolvedObjectType)                                                                                                                       \
-    oop_field(HotSpotResolvedObjectType, javaClass, "Ljava/lang/Class;")                                                                                       \
+  start_class(HotSpotResolvedObjectTypeImpl)                                                                                                                       \
+    oop_field(HotSpotResolvedObjectTypeImpl, javaClass, "Ljava/lang/Class;")                                                                                       \
   end_class                                                                                                                                                    \
   start_class(HotSpotResolvedJavaMethodImpl)                                                                                                                       \
     long_field(HotSpotResolvedJavaMethodImpl, metaspaceMethod)                                                                                                     \
--- a/src/share/vm/runtime/deoptimization.cpp	Mon Nov 03 16:08:06 2014 +0100
+++ b/src/share/vm/runtime/deoptimization.cpp	Mon Nov 03 17:03:19 2014 +0100
@@ -915,7 +915,7 @@
 }
 
 // Restore fields of an eliminated instance object using the same field order
-// returned by HotSpotResolvedObjectType.getInstanceFields(true)
+// returned by HotSpotResolvedObjectTypeImpl.getInstanceFields(true)
 static int reassign_fields_by_klass(InstanceKlass* klass, frame* fr, RegisterMap* reg_map, ObjectValue* sv, int svIndex, oop obj) {
   if (klass->superklass() != NULL) {
     svIndex = reassign_fields_by_klass(klass->superklass(), fr, reg_map, sv, svIndex, obj);