changeset 7081:3e61ffb9ce29

Merge.
author Christian Haeubl <haeubl@ssw.jku.at>
date Wed, 28 Nov 2012 09:01:39 +0100
parents 15055bdafbfc (current diff) 113eb675c981 (diff)
children 2b66ba197738 fa3c8913d674
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java src/share/vm/graal/graalCodeInstaller.cpp
diffstat 59 files changed, 1108 insertions(+), 211 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java	Wed Nov 28 09:01:39 2012 +0100
@@ -111,7 +111,7 @@
      * @return true if {@code type} has no subtype(s)
      */
     public static boolean isFinalClass(ResolvedJavaType type) {
-        if (type.isArrayClass()) {
+        if (type.isArray()) {
             return isFinalClass(type.getComponentType());
         }
         return Modifier.isFinal(type.getModifiers());
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java	Wed Nov 28 09:01:39 2012 +0100
@@ -68,7 +68,7 @@
         if (values == null) {
             buf.append("<uninitialized>");
         } else {
-            if (type.isArrayClass()) {
+            if (type.isArray()) {
                 for (int i = 0; i < values.length; i++) {
                     if (i != 0) {
                         buf.append(',');
@@ -112,7 +112,7 @@
 
     private static boolean checkValues(ResolvedJavaType type, Value[] values) {
         if (values != null) {
-            if (!type.isArrayClass()) {
+            if (!type.isArray()) {
                 ResolvedJavaField[] fields = type.getInstanceFields(true);
                 assert fields.length == values.length : type + ": fields=" + Arrays.toString(fields) + ", field values=" + Arrays.toString(values);
                 for (int i = 0; i < values.length; i++) {
--- a/graal/com.oracle.graal.api.interpreter/src/com/oracle/graal/api/interpreter/RuntimeInterpreterInterface.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.api.interpreter/src/com/oracle/graal/api/interpreter/RuntimeInterpreterInterface.java	Wed Nov 28 09:01:39 2012 +0100
@@ -100,4 +100,5 @@
 
     void setArrayObject(Object value, long index, Object array);
 
+    Class<?> getMirror(ResolvedJavaType type);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/NameAndSignature.java	Wed Nov 28 09:01:39 2012 +0100
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta.test;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+
+class NameAndSignature {
+    final String name;
+    final Class returnType;
+    final Class[] parameterTypes;
+
+    public NameAndSignature(Method m) {
+        this.name = m.getName();
+        this.returnType = m.getReturnType();
+        this.parameterTypes = m.getParameterTypes();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof NameAndSignature) {
+            NameAndSignature s = (NameAndSignature) obj;
+            return s.returnType == returnType && name.equals(s.name) && Arrays.equals(s.parameterTypes, parameterTypes);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(name + "(");
+        String sep = "";
+        for (Class p : parameterTypes) {
+            sb.append(sep);
+            sep = ", ";
+            sb.append(p.getName());
+        }
+        return sb.append(')').append(returnType.getName()).toString();
+    }
+
+    public boolean signatureEquals(ResolvedJavaMethod m) {
+        Signature s = m.getSignature();
+        ResolvedJavaType declaringClass = m.getDeclaringClass();
+        if (!s.getReturnType(declaringClass).resolve(declaringClass).isClass(returnType)) {
+            return false;
+        }
+        if (s.getParameterCount(false) != parameterTypes.length) {
+            return false;
+        }
+        for (int i = 0; i < parameterTypes.length; i++) {
+            if (!s.getParameterType(i, declaringClass).resolve(declaringClass).isClass(parameterTypes[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java	Wed Nov 28 09:01:39 2012 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta.test;
+
+import static com.oracle.graal.api.meta.test.TestMetaAccessProvider.*;
+import static org.junit.Assert.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Tests for {@link JavaMethod}.
+ */
+public class TestJavaMethod {
+
+    public TestJavaMethod() {
+    }
+
+    public static final Map<Method, ResolvedJavaMethod> methods = new HashMap<>();
+    public static final Map<Constructor, ResolvedJavaMethod> constructors = new HashMap<>();
+    static {
+        for (Class c : classes) {
+            for (Method m : c.getDeclaredMethods()) {
+                ResolvedJavaMethod method = runtime.lookupJavaMethod(m);
+                methods.put(m, method);
+            }
+            for (Constructor m : c.getDeclaredConstructors()) {
+                constructors.put(m, runtime.lookupJavaConstructor(m));
+            }
+        }
+    }
+
+    @Test
+    public void getNameTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            String expected = e.getKey().getName();
+            String actual = e.getValue().getName();
+            assertEquals(expected, actual);
+        }
+    }
+
+    @Test
+    public void getDeclaringClassTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            Class expected = e.getKey().getDeclaringClass();
+            ResolvedJavaType actual = e.getValue().getDeclaringClass();
+            assertTrue(actual.isClass(expected));
+        }
+    }
+
+    @Test
+    public void getSignatureTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            assertTrue(new NameAndSignature(e.getKey()).signatureEquals(e.getValue()));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java	Wed Nov 28 09:01:39 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta.test;
+
+import static com.oracle.graal.api.meta.test.TestMetaAccessProvider.*;
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Tests for {@link JavaType}.
+ */
+public class TestJavaType {
+
+    public TestJavaType() {
+    }
+
+    @Test
+    public void getKindTest() {
+        for (Class c : classes) {
+            JavaType type = runtime.lookupJavaType(c);
+            Kind expected = Kind.fromJavaClass(c);
+            Kind actual = type.getKind();
+            assertEquals(expected, actual);
+        }
+    }
+}
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java	Wed Nov 28 09:01:39 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,11 +31,32 @@
 
 import org.junit.*;
 
+import sun.misc.Unsafe;
+
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
 
+/**
+ * Tests for {@link MetaAccessProvider}.
+ */
+public class TestMetaAccessProvider {
 
-public class TestMetaAccessProvider {
+    public static final Unsafe unsafe;
+    static {
+        Unsafe theUnsafe = null;
+        try {
+            theUnsafe = Unsafe.getUnsafe();
+        } catch (Exception e) {
+            try {
+                Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
+                theUnsafeField.setAccessible(true);
+                theUnsafe = (Unsafe) theUnsafeField.get(null);
+            } catch (Exception e1) {
+                throw (InternalError) new InternalError("unable to initialize unsafe").initCause(e1);
+            }
+        }
+        unsafe = theUnsafe;
+    }
 
     public TestMetaAccessProvider() {
     }
@@ -165,7 +186,7 @@
             assertNotNull(type);
             assertTrue(type.isClass(c));
             assertEquals(c.getModifiers(), type.getModifiers());
-            if (!type.isArrayClass()) {
+            if (!type.isArray()) {
                 assertEquals(type.getName(), toInternalName(c.getName()));
                 assertEquals(toJavaName(type), c.getName());
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java	Wed Nov 28 09:01:39 2012 +0100
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta.test;
+
+import static com.oracle.graal.api.meta.test.TestJavaMethod.*;
+import static java.lang.reflect.Modifier.*;
+import static org.junit.Assert.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Tests for {@link ResolvedJavaMethod}.
+ */
+public class TestResolvedJavaMethod {
+
+    public TestResolvedJavaMethod() {
+    }
+
+    /**
+     * @see ResolvedJavaMethod#getCode()
+     */
+    @Test
+    public void getCodeTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            byte[] code = m.getCode();
+            assertNotNull(code);
+            if (isAbstract(m.getModifiers())) {
+                assertTrue(code.length == 0);
+            } else if (!isNative(m.getModifiers())) {
+                assertTrue(code.length > 0);
+            }
+        }
+    }
+
+    /**
+     * @see ResolvedJavaMethod#getCodeSize()
+     */
+    @Test
+    public void getCodeSizeTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            int codeSize = m.getCodeSize();
+            if (isAbstract(m.getModifiers())) {
+                assertTrue(codeSize == 0);
+            } else if (!isNative(m.getModifiers())) {
+                assertTrue(codeSize > 0);
+            }
+        }
+    }
+
+    /**
+     * @see ResolvedJavaMethod#getCompiledCodeSize()
+     */
+    @Test
+    public void getCompiledCodeSizeTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            int size = m.getCompiledCodeSize();
+            if (isAbstract(m.getModifiers())) {
+                assertTrue(size == 0);
+            } else {
+                assertTrue(size >= 0);
+            }
+        }
+    }
+
+    @Test
+    public void getCompilationComplexityTest() {
+        // TODO
+    }
+
+    @Test
+    public void getMaxLocalsTest() {
+        // TODO
+    }
+
+    @Test
+    public void getMaxStackSizeTest() {
+        // TODO
+    }
+
+    @Test
+    public void getModifiersTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            int expected = e.getKey().getModifiers() & Modifier.methodModifiers();
+            int actual = m.getModifiers();
+            assertEquals(expected, actual);
+        }
+    }
+
+    /**
+     * @see ResolvedJavaMethod#isClassInitializer()
+     */
+    @Test
+    public void isClassInitializerTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            // Class initializers are hidden from reflection
+            ResolvedJavaMethod m = e.getValue();
+            assertFalse(m.isClassInitializer());
+        }
+        for (Map.Entry<Constructor, ResolvedJavaMethod> e : constructors.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertFalse(m.isClassInitializer());
+        }
+    }
+
+    @Test
+    public void isConstructorTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertFalse(m.isConstructor());
+        }
+        for (Map.Entry<Constructor, ResolvedJavaMethod> e : constructors.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertTrue(m.isConstructor());
+        }
+    }
+
+    @Test
+    public void canBeStaticallyBoundTest() {
+        // TODO
+    }
+
+    @Test
+    public void getExceptionHandlersTest() {
+        // TODO
+    }
+
+    @Test
+    public void asStackTraceElementTest() {
+        // TODO
+    }
+
+    @Test
+    public void getProfilingInfoTest() {
+        // TODO
+    }
+
+    @Test
+    public void getCompilerStorageTest() {
+        // TODO
+    }
+
+    @Test
+    public void getConstantPoolTest() {
+        // TODO
+    }
+
+    @Test
+    public void getAnnotationTest() {
+        // TODO
+    }
+
+    @Test
+    public void getParameterAnnotationsTest() {
+        // TODO
+    }
+
+    @Test
+    public void getGenericParameterTypesTest() {
+        // TODO
+
+    }
+
+    @Test
+    public void canBeInlinedTest() {
+        // TODO
+    }
+}
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java	Wed Nov 28 09:01:39 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,12 +36,31 @@
 
 import com.oracle.graal.api.meta.*;
 
+/**
+ * Tests for {@link ResolvedJavaType}.
+ */
 public class TestResolvedJavaType {
 
     public TestResolvedJavaType() {
     }
 
     @Test
+    public void findInstanceFieldWithOffsetTest() {
+        for (Class c : classes) {
+            ResolvedJavaType type = runtime.lookupJavaType(c);
+            Set<Field> reflectionFields = getInstanceFields(c, true);
+            for (Field f : reflectionFields) {
+                ResolvedJavaField rf = lookupField(type.getInstanceFields(true), f);
+                assertNotNull(rf);
+                long offset = isStatic(f.getModifiers()) ? unsafe.staticFieldOffset(f) : unsafe.objectFieldOffset(f);
+                ResolvedJavaField result = type.findInstanceFieldWithOffset(offset);
+                assertNotNull(result);
+                assertTrue(fieldsEqual(f, result));
+            }
+        }
+    }
+
+    @Test
     public void isInterfaceTest() {
         for (Class c : classes) {
             ResolvedJavaType type = runtime.lookupJavaType(c);
@@ -67,7 +86,7 @@
         for (Class c : classes) {
             ResolvedJavaType type = runtime.lookupJavaType(c);
             boolean expected = c.isArray();
-            boolean actual = type.isArrayClass();
+            boolean actual = type.isArray();
             assertEquals(expected, actual);
         }
     }
@@ -239,23 +258,23 @@
 
     static void checkConcreteSubtype(ResolvedJavaType type, Class expected) {
         ResolvedJavaType subtype = type.findUniqueConcreteSubtype();
-        if (type.isInterface() && subtype == null) {
-            // A runtime may not record the subtype tree for interfaces in which case
-            // findUniqueConcreteSubtype() will return null for interfaces.
-            return;
+        if (subtype == null) {
+            // findUniqueConcreteSubtype() is conservative
+        } else {
+            if (expected == null) {
+                assertNull(subtype);
+            } else {
+                assertTrue(subtype.isClass(expected));
+            }
         }
 
-        if (expected == null) {
-            assertNull(subtype);
-        } else {
-            assertTrue(subtype.isClass(expected));
-        }
-        if (!type.isArrayClass()) {
+        if (!type.isArray()) {
             ResolvedJavaType arrayType = type.getArrayClass();
-            if (subtype == type) {
-                assertEquals(arrayType.findUniqueConcreteSubtype(), arrayType);
+            ResolvedJavaType arraySubtype = arrayType.findUniqueConcreteSubtype();
+            if (arraySubtype != null) {
+                assertEquals(arraySubtype, arrayType);
             } else {
-                assertNull(arrayType.findUniqueConcreteSubtype());
+                // findUniqueConcreteSubtype() method is conservative
             }
         }
     }
@@ -350,44 +369,8 @@
 
     static final Map<Class, VTable> vtables = new HashMap<>();
 
-    static class NameAndSig {
-        final String name;
-        final Class returnType;
-        final Class[] parameterTypes;
-        public NameAndSig(Method m) {
-            this.name = m.getName();
-            this.returnType = m.getReturnType();
-            this.parameterTypes = m.getParameterTypes();
-        }
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof NameAndSig) {
-                NameAndSig s = (NameAndSig) obj;
-                return s.returnType == returnType && name.equals(s.name) && Arrays.equals(s.parameterTypes, parameterTypes);
-            }
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            return name.hashCode();
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder(name + "(");
-            String sep = "";
-            for (Class p : parameterTypes) {
-                sb.append(sep);
-                sep = ", ";
-                sb.append(p.getName());
-            }
-            return sb.append(')').append(returnType.getName()).toString();
-        }
-    }
-
     static class VTable {
-        final Map<NameAndSig, Method> methods = new HashMap<>();
+        final Map<NameAndSignature, Method> methods = new HashMap<>();
     }
 
     static synchronized VTable getVTable(Class c) {
@@ -400,7 +383,7 @@
             }
             for (Method m : c.getDeclaredMethods()) {
                 if (!isStatic(m.getModifiers()) && !isPrivate(m.getModifiers())) {
-                    Method overridden = vtable.methods.put(new NameAndSig(m), m);
+                    Method overridden = vtable.methods.put(new NameAndSignature(m), m);
                     if (overridden != null) {
                         //System.out.println(m + " overrides " + overridden);
                     }
@@ -413,10 +396,10 @@
 
     static Set<Method> findDeclarations(Method impl, Class c) {
         Set<Method> declarations = new HashSet<>();
-        NameAndSig implSig = new NameAndSig(impl);
+        NameAndSignature implSig = new NameAndSignature(impl);
         if (c != null) {
             for (Method m : c.getDeclaredMethods()) {
-                if (new NameAndSig(m).equals(implSig)) {
+                if (new NameAndSignature(m).equals(implSig)) {
                     declarations.add(m);
                     break;
                 }
@@ -475,24 +458,30 @@
         return result;
     }
 
-    public static boolean containsField(ResolvedJavaField[] fields, Field f) {
+    public static boolean fieldsEqual(Field f, ResolvedJavaField rjf) {
+        return rjf.getDeclaringClass().isClass(f.getDeclaringClass()) &&
+               rjf.getName().equals(f.getName()) &&
+               rjf.getType().resolve(rjf.getDeclaringClass()).isClass(f.getType());
+    }
+
+    public static ResolvedJavaField lookupField(ResolvedJavaField[] fields, Field key) {
         for (ResolvedJavaField rf : fields) {
-            if (rf.getName().equals(f.getName()) && rf.getType().resolve(rf.getDeclaringClass()).isClass(f.getType())) {
-                assert f.getModifiers() == rf.getModifiers() : f;
-                return true;
+            if (fieldsEqual(key, rf)) {
+                assert key.getModifiers() == rf.getModifiers() : key;
+                return rf;
             }
         }
-        return false;
+        return null;
     }
 
-    public static boolean containsField(Set<Field> fields, ResolvedJavaField rf) {
+    public static Field lookupField(Set<Field> fields, ResolvedJavaField key) {
         for (Field f : fields) {
-            if (f.getName().equals(rf.getName()) && rf.getType().resolve(rf.getDeclaringClass()).isClass(f.getType())) {
-                assert rf.getModifiers() == f.getModifiers() : rf;
-                return true;
+            if (fieldsEqual(f, key)) {
+                assert key.getModifiers() == f.getModifiers() : key;
+                return f;
             }
         }
-        return false;
+        return null;
     }
 
     private static boolean isHiddenFromReflection(ResolvedJavaField f) {
@@ -513,11 +502,11 @@
                 Set<Field> expected = getInstanceFields(c, includeSuperclasses);
                 ResolvedJavaField[] actual = type.getInstanceFields(includeSuperclasses);
                 for (Field f : expected) {
-                    assertTrue(containsField(actual, f));
+                    assertNotNull(lookupField(actual, f));
                 }
                 for (ResolvedJavaField rf : actual) {
                     if (!isHiddenFromReflection(rf)) {
-                        assertEquals(containsField(expected, rf), !rf.isInternal());
+                        assertEquals(lookupField(expected, rf) != null, !rf.isInternal());
                     }
                 }
 
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Wed Nov 28 09:01:39 2012 +0100
@@ -43,6 +43,11 @@
     ResolvedJavaMethod lookupJavaMethod(Method reflectionMethod);
 
     /**
+     * Provides the {@link ResolvedJavaMethod} for a {@link Constructor} obtained via reflection.
+     */
+    ResolvedJavaMethod lookupJavaConstructor(Constructor reflectionConstructor);
+
+    /**
      * Provides the {@link ResolvedJavaField} for a {@link Field} obtained via reflection.
      */
     ResolvedJavaField lookupJavaField(Field reflectionField);
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Wed Nov 28 09:01:39 2012 +0100
@@ -37,19 +37,63 @@
 public class MetaUtil {
 
     /**
-     * Returns true if the specified typed is exactly the type {@link java.lang.Object}.
+     * Gets the {@link Class} mirror for a given resolved type.
+     *
+     * @param type the type for which the Java mirror is requested
+     * @param loader class loader from which the class must be loaded (null means use the class loader of the {@link MetaUtil} class)
+     * @return the mirror for {@code type}
+     * @throws NoClassDefFoundError if the mirror is not available
      */
-    public static boolean isJavaLangObject(ResolvedJavaType type) {
-        boolean result = type.getSuperclass() == null && !type.isInterface() && type.getKind() == Kind.Object;
-        assert result == type.getName().equals("Ljava/lang/Object;") : type.getName();
-        return result;
+    public static Class getMirrorOrFail(ResolvedJavaType type, ClassLoader loader) throws NoClassDefFoundError {
+        ResolvedJavaType elementalType = getElementalType(type);
+        Class elementalClass;
+        if (elementalType.isPrimitive()) {
+            elementalClass = type.getKind().toJavaClass();
+        } else {
+            try {
+                elementalClass = Class.forName(toJavaName(elementalType), true, loader);
+            } catch (ClassNotFoundException e) {
+                throw (NoClassDefFoundError) new NoClassDefFoundError().initCause(e);
+            }
+        }
+        if (type.isArray()) {
+            ResolvedJavaType t = type;
+            while (t.getComponentType() != null) {
+                elementalClass = Array.newInstance(elementalClass, 0).getClass();
+                t = t.getComponentType();
+            }
+        }
+        assert elementalClass != null : toJavaName(type);
+        return elementalClass;
     }
 
     /**
-     * Determines if a given type represents a primitive type.
+     * Gets the {@link Class} mirror for a given resolved type.
+     *
+     * @param type the type for which the Java mirror is requested
+     * @param loader class loader from which the class must be loaded (null means use the class loader of the {@link MetaUtil} class)
+     * @return the mirror for {@code type} or null if it is not available
      */
-    public static boolean isPrimitive(ResolvedJavaType type) {
-        return type.getSuperclass() == null && !type.isInstanceClass();
+    public static Class getMirror(ResolvedJavaType type, ClassLoader loader) {
+        try {
+            return getMirrorOrFail(type, loader);
+        } catch (NoClassDefFoundError e) {
+            return null;
+        }
+    }
+
+    /**
+     * Gets the elemental type for a given type.
+     * The elemental type of an array type is the corresponding zero dimensional (e.g.,
+     * the elemental type of {@code int[][][]} is {@code int}). A non-array type is its
+     * own elemental type.
+     */
+    public static ResolvedJavaType getElementalType(ResolvedJavaType type) {
+        ResolvedJavaType t = type;
+        while (t.getComponentType() != null) {
+            t = t.getComponentType();
+        }
+        return t;
     }
 
     /**
@@ -429,15 +473,6 @@
         return result;
     }
 
-    public static Class< ? >[] signatureToTypes(Signature signature, ResolvedJavaType accessingClass) {
-        int count = signature.getParameterCount(false);
-        Class< ? >[] result = new Class< ? >[count];
-        for (int i = 0; i < result.length; ++i) {
-            result[i] = signature.getParameterType(i, accessingClass).resolve(accessingClass).toJava();
-        }
-        return result;
-    }
-
     /**
      * Formats some profiling information associated as a string.
      *
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Wed Nov 28 09:01:39 2012 +0100
@@ -101,7 +101,14 @@
      *
      * @return {@code true} if this type is an array class
      */
-    boolean isArrayClass();
+    boolean isArray();
+
+    /**
+     * Checks whether this type is primitive.
+     *
+     * @return {@code true} if this type is primitive
+     */
+    boolean isPrimitive();
 
     /**
      * Returns the Java language modifiers for this type, as an integer. The {@link Modifier} class should be used to
@@ -171,13 +178,21 @@
     ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType);
 
     /**
-     * Gets the unique concrete subclass of this type.
-     *
+     * Attempts to get a unique concrete subclass of this type.
+     * <p>
+     * For an {@linkplain #isArray() array} type A, the unique concrete subclass is A if
+     * the element type of A is primitive or has no subtype. Otherwise there is no unique concrete subclass.
+     * <p>
+     * For a non-array type T, the result is the unique concrete type in the complete hierarchy of T.
+     * <p>
+     * A runtime may decide not to manage or walk a large hierarchy and so the result is conservative.
+     * That is, a non-null result is guaranteed to be the unique concrete class in T's hierarchy
+     * but a null result does not necessarily imply that there is no unique concrete class in T's hierarchy.
      * <p>
      * If the compiler uses the result of this method for its compilation, it must register an assumption because
      * dynamic class loading can invalidate the result of this method.
      *
-     * @return the exact type of this type, if it exists; {@code null} otherwise
+     * @return the unique concrete subclass for this type as described above
      */
     ResolvedJavaType findUniqueConcreteSubtype();
 
@@ -231,7 +246,11 @@
     boolean isClass(Class c);
 
     /**
-     * Returns the {@link java.lang.Class} object representing this type.
+     * Returns the instance field of this class (or one of its super classes) at the given
+     * offset, or {@code null} if there is no such field.
+     *
+     * @param offset the offset of the field to look for
+     * @return the field with the given offset, or {@code null} if there is no such field.
      */
-    Class< ? > toJava();
+    ResolvedJavaField findInstanceFieldWithOffset(long offset);
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Wed Nov 28 09:01:39 2012 +0100
@@ -232,7 +232,7 @@
         //  - has no callee-saved registers
         //  - has no incoming arguments passed on the stack
         //  - has no instructions with debug info
-        boolean canOmitFrame =
+        boolean canOmitFrame = GraalOptions.CanOmitFrame &&
             frameMap.frameSize() == frameMap.initialFrameSize &&
             frameMap.registerConfig.getCalleeSaveLayout().registers.length == 0 &&
             !lir.hasArgInCallerFrame() &&
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeInterpreterInterface.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeInterpreterInterface.java	Wed Nov 28 09:01:39 2012 +0100
@@ -40,6 +40,10 @@
         this.metaProvider = metaProvider;
     }
 
+    public Class< ? > getMirror(ResolvedJavaType type) {
+        return ((HotSpotJavaType) type).mirror();
+    }
+
     public native Object invoke(ResolvedJavaMethod method, Object... args);
 
     public void monitorEnter(Object value) {
@@ -53,7 +57,7 @@
     }
 
     public Object newObject(ResolvedJavaType type) throws InstantiationException {
-        return unsafe.allocateInstance(type.toJava());
+        return unsafe.allocateInstance(getMirror(type));
     }
 
     public Object getFieldObject(Object base, ResolvedJavaField field) {
@@ -286,7 +290,7 @@
             return;
         }
         ResolvedJavaType type = metaProvider.lookupJavaType(array.getClass()).getComponentType();
-        if (!type.toJava().isAssignableFrom(arrayType)) {
+        if (!getMirror(type).isAssignableFrom(arrayType)) {
             throw new ArrayStoreException(arrayType.getName());
         }
     }
@@ -294,7 +298,7 @@
     private void checkArray(Object array, long index) {
         nullCheck(array);
         ResolvedJavaType type = metaProvider.lookupJavaType(array.getClass());
-        if (!type.isArrayClass()) {
+        if (!type.isArray()) {
             throw new ArrayStoreException(array.getClass().getName());
         }
         if (index < 0 || index >= arrayLength(array)) {
@@ -315,10 +319,10 @@
         return ((HotSpotResolvedJavaField) field).offset();
     }
 
-    private static Object resolveBase(Object base, ResolvedJavaField field) {
+    private Object resolveBase(Object base, ResolvedJavaField field) {
         Object accessorBase = base;
         if (accessorBase == null) {
-            accessorBase = field.getDeclaringClass().toJava();
+            accessorBase = getMirror(field.getDeclaringClass());
         }
         return accessorBase;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed Nov 28 09:01:39 2012 +0100
@@ -166,6 +166,7 @@
      * @return the metaspace Method result for {@code reflectionMethod}
      */
     long getMetaspaceMethod(Method reflectionMethod, HotSpotResolvedJavaType[] resultHolder);
+    long getMetaspaceConstructor(Constructor reflectionConstructor, HotSpotResolvedJavaType[] resultHolder);
 
     HotSpotResolvedJavaField getJavaField(Field reflectionField);
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Wed Nov 28 09:01:39 2012 +0100
@@ -38,6 +38,9 @@
     public native long getMetaspaceMethod(Method reflectionMethod, HotSpotResolvedJavaType[] resultHolder);
 
     @Override
+    public native long getMetaspaceConstructor(Constructor reflectionConstructor, HotSpotResolvedJavaType[] resultHolder);
+
+    @Override
     public native HotSpotResolvedJavaField getJavaField(Field reflectionMethod);
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Wed Nov 28 09:01:39 2012 +0100
@@ -45,8 +45,6 @@
 
     JavaMethod createUnresolvedJavaMethod(String name, String signature, JavaType holder);
 
-    Signature createSignature(String signature);
-
     JavaField createJavaField(JavaType holder, String name, JavaType type, int offset, int flags, boolean internal);
 
     ResolvedJavaMethod createResolvedJavaMethod(JavaType holder, long metaspaceMethod);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Wed Nov 28 09:01:39 2012 +0100
@@ -85,7 +85,7 @@
     }
 
     private static void initMirror(HotSpotTypePrimitive type, long offset) {
-        Class< ? > mirror = type.toJava();
+        Class<?> mirror = type.mirror();
         unsafe.putObject(mirror, offset, type);
         assert unsafe.getObject(mirror, offset) == type;
     }
@@ -444,11 +444,6 @@
     }
 
     @Override
-    public Signature createSignature(String signature) {
-        return new HotSpotSignature(signature);
-    }
-
-    @Override
     public JavaField createJavaField(JavaType holder, String name, JavaType type, int offset, int flags, boolean internal) {
         if (offset != -1) {
             HotSpotResolvedJavaType resolved = (HotSpotResolvedJavaType) holder;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotJavaType.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotJavaType.java	Wed Nov 28 09:01:39 2012 +0100
@@ -41,4 +41,6 @@
     public final String getName() {
         return name;
     }
+
+    public abstract Class<?> mirror();
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Wed Nov 28 09:01:39 2012 +0100
@@ -79,7 +79,7 @@
             assert Modifier.isStatic(flags);
             if (constant == null) {
                 if (holder.isInitialized() && !holder.getName().equals(SystemClassName)) {
-                    if (Modifier.isFinal(getModifiers()) || assumeStaticFieldsFinal(holder.toJava())) {
+                    if (Modifier.isFinal(getModifiers()) || assumeStaticFieldsFinal(holder.mirror())) {
                         constant = readValue(receiver);
                     }
                 }
@@ -154,7 +154,7 @@
 
     private Field toJava() {
         try {
-            return holder.toJava().getDeclaredField(name);
+            return holder.mirror().getDeclaredField(name);
         } catch (NoSuchFieldException e) {
             return null;
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Wed Nov 28 09:01:39 2012 +0100
@@ -258,9 +258,19 @@
         return javaMethod == null ? null : javaMethod.getGenericParameterTypes();
     }
 
+    public Class<?>[] signatureToTypes() {
+        Signature sig = getSignature();
+        int count = sig.getParameterCount(false);
+        Class< ? >[] result = new Class< ? >[count];
+        for (int i = 0; i < result.length; ++i) {
+            result[i] = ((HotSpotJavaType) sig.getParameterType(i, holder).resolve(holder)).mirror();
+        }
+        return result;
+    }
+
     private Method toJava() {
         try {
-            return holder.toJava().getDeclaredMethod(name, MetaUtil.signatureToTypes(getSignature(), holder));
+            return holder.mirror().getDeclaredMethod(name, signatureToTypes());
         } catch (NoSuchMethodException e) {
             return null;
         }
@@ -268,7 +278,7 @@
 
     private Constructor toJavaConstructor() {
         try {
-            return holder.toJava().getDeclaredConstructor(MetaUtil.signatureToTypes(getSignature(), holder));
+            return holder.mirror().getDeclaredConstructor(signatureToTypes());
         } catch (NoSuchMethodException e) {
             return null;
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Wed Nov 28 09:01:39 2012 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.hotspot.meta;
 
+import static com.oracle.graal.api.meta.MetaUtil.*;
 import static com.oracle.graal.graph.FieldIntrospection.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static java.lang.reflect.Modifier.*;
@@ -130,7 +131,7 @@
         this.hasFinalizableSubclass = hasFinalizableSubclass;
         this.sizeOrSpecies = sizeOrSpecies;
         assert name.charAt(0) != '[' || sizeOrSpecies == ARRAY_SPECIES_VALUE : name + " " + Long.toHexString(sizeOrSpecies);
-        assert javaMirror.isArray() == isArrayClass();
+        assert javaMirror.isArray() == isArray();
         assert javaMirror.isInterface() == isInterface();
         //System.out.println("0x" + Long.toHexString(metaspaceKlass) + ": " + name);
     }
@@ -159,12 +160,27 @@
         return javaComponentType == null ? null : fromClass(javaComponentType);
     }
 
+    private static boolean hasSubtype(ResolvedJavaType type) {
+        assert !type.isArray() : type;
+        if (type.isPrimitive()) {
+            return false;
+        }
+        HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
+        if (unsafeReadWord(((HotSpotResolvedJavaType) type).metaspaceKlass + config.subklassOffset) != 0) {
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public ResolvedJavaType findUniqueConcreteSubtype() {
-        if (isArrayClass()) {
-            return getComponentType().findUniqueConcreteSubtype() == getComponentType() ? this : null;
+        HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
+        if (isArray()) {
+            if (hasSubtype(getElementalType(this))) {
+                return null;
+            }
+            return this;
         } else {
-            HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
             HotSpotResolvedJavaType type = this;
             while (isAbstract(type.getModifiers())) {
                 long subklass = unsafeReadWord(type.metaspaceKlass + config.subklassOffset);
@@ -176,7 +192,6 @@
             if (unsafeReadWord(type.metaspaceKlass + config.subklassOffset) != 0) {
                 return null;
             }
-            assert !type.isInterface();
             return type;
         }
     }
@@ -201,9 +216,9 @@
     }
 
     public HotSpotResolvedJavaType getSupertype() {
-        if (isArrayClass()) {
+        if (isArray()) {
             ResolvedJavaType componentType = getComponentType();
-            if (javaMirror == Object[].class || componentType instanceof HotSpotTypePrimitive) {
+            if (javaMirror == Object[].class || componentType.isPrimitive()) {
                 return (HotSpotResolvedJavaType) fromClass(Object.class);
             }
             return (HotSpotResolvedJavaType) ((HotSpotResolvedJavaType) componentType).getSupertype().getArrayClass();
@@ -216,7 +231,7 @@
 
     @Override
     public ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType) {
-        if (otherType instanceof HotSpotTypePrimitive) {
+        if (otherType.isPrimitive()) {
             return null;
         } else {
             HotSpotResolvedJavaType t1 = this;
@@ -236,7 +251,7 @@
 
     @Override
     public ResolvedJavaType asExactType() {
-        if (isArrayClass()) {
+        if (isArray()) {
             return getComponentType().asExactType() != null ? this : null;
         }
         return Modifier.isFinal(getModifiers()) ? this : null;
@@ -270,7 +285,12 @@
     }
 
     @Override
-    public boolean isArrayClass() {
+    public boolean isPrimitive() {
+        return false;
+    }
+
+    @Override
+    public boolean isArray() {
         return sizeOrSpecies == ARRAY_SPECIES_VALUE;
     }
 
@@ -300,7 +320,7 @@
 
     @Override
     public boolean isInstanceClass() {
-        return !isArrayClass() && !isInterface();
+        return !isArray() && !isInterface();
     }
 
     @Override
@@ -346,7 +366,7 @@
      * value gives the size). Must not be called if this is an array or interface type.
      */
     public int instanceSize() {
-        assert !isArrayClass();
+        assert !isArray();
         assert !isInterface();
         return sizeOrSpecies;
     }
@@ -396,7 +416,7 @@
     @Override
     public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) {
         if (instanceFields == null) {
-            if (isArrayClass() || isInterface()) {
+            if (isArray() || isInterface()) {
                 instanceFields = new HotSpotResolvedJavaField[0];
             } else {
                 HotSpotResolvedJavaField[] myFields = HotSpotGraalRuntime.getInstance().getCompilerToVM().getInstanceFields(this);
@@ -428,7 +448,7 @@
     }
 
     @Override
-    public Class< ? > toJava() {
+    public Class<?> mirror() {
         return javaMirror;
     }
 
@@ -466,4 +486,15 @@
     public long prototypeMarkWord() {
         return HotSpotGraalRuntime.getInstance().getCompilerToVM().getPrototypeMarkWord(this);
     }
+
+    @Override
+    public ResolvedJavaField findInstanceFieldWithOffset(long offset) {
+        ResolvedJavaField[] declaredFields = getInstanceFields(true);
+        for (ResolvedJavaField field : declaredFields) {
+            if (((HotSpotResolvedJavaField) field).offset() == offset) {
+                return field;
+            }
+        }
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Nov 28 09:01:39 2012 +0100
@@ -460,7 +460,7 @@
             ValueNode expected = cas.expected();
             if (expected.kind() == Kind.Object && !cas.newValue().objectStamp().alwaysNull()) {
                 ResolvedJavaType type = cas.object().objectStamp().type();
-                if (type != null && !type.isArrayClass() && type.toJava() != Object.class) {
+                if (type != null && !type.isArray() && !type.isClass(Object.class)) {
                     // Use a field write barrier since it's not an array store
                     FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(cas.object()));
                     graph.addAfterFixed(cas, writeBarrier);
@@ -491,7 +491,7 @@
                 ResolvedJavaType arrayType = array.objectStamp().type();
                 if (arrayType != null && array.objectStamp().isExactType()) {
                     ResolvedJavaType elementType = arrayType.getComponentType();
-                    if (!MetaUtil.isJavaLangObject(elementType)) {
+                    if (!elementType.isClass(Object.class)) {
                         CheckCastNode checkcast = graph.add(new CheckCastNode(elementType, value, null));
                         graph.addBeforeFixed(storeIndexed, checkcast);
                         value = checkcast;
@@ -533,7 +533,7 @@
             if (write.value().kind() == Kind.Object && !write.value().objectStamp().alwaysNull()) {
                 ResolvedJavaType type = object.objectStamp().type();
                 WriteBarrier writeBarrier;
-                if (type != null && !type.isArrayClass() && type.toJava() != Object.class) {
+                if (type != null && !type.isArray() && !type.isClass(Object.class)) {
                     // Use a field write barrier since it's not an array store
                     writeBarrier = graph.add(new FieldWriteBarrier(object));
                 } else {
@@ -602,13 +602,14 @@
         ResolvedJavaType holder = method.getDeclaringClass();
         String fullName = method.getName() + ((HotSpotSignature) method.getSignature()).asString();
         Kind wordKind = graalRuntime.getTarget().wordKind;
-        if (holder.toJava() == Object.class) {
+        if (holder.isClass(Object.class)) {
             if (fullName.equals("getClass()Ljava/lang/Class;")) {
                 ValueNode obj = (ValueNode) parameters.get(0);
                 ObjectStamp stamp = (ObjectStamp) obj.stamp();
                 if (stamp.nonNull() && stamp.isExactType()) {
                     StructuredGraph graph = new StructuredGraph();
-                    ValueNode result = ConstantNode.forObject(stamp.type().toJava(), this, graph);
+                    HotSpotJavaType type = (HotSpotJavaType) stamp.type();
+                    ValueNode result = ConstantNode.forObject(type.mirror(), this, graph);
                     ReturnNode ret = graph.add(new ReturnNode(result));
                     graph.start().setNext(ret);
                     return graph;
@@ -623,7 +624,7 @@
                 hub.setNext(ret);
                 return graph;
             }
-        } else if (holder.toJava() == Class.class) {
+        } else if (holder.isClass(Class.class)) {
             if (fullName.equals("getModifiers()I")) {
                 StructuredGraph graph = new StructuredGraph();
                 LocalNode receiver = graph.unique(new LocalNode(0, StampFactory.objectNonNull()));
@@ -638,7 +639,7 @@
                 klass.setNext(ret);
                 return graph;
             }
-        } else if (holder.toJava() == Thread.class) {
+        } else if (holder.isClass(Thread.class)) {
             if (fullName.equals("currentThread()Ljava/lang/Thread;")) {
                 StructuredGraph graph = new StructuredGraph();
                 ReturnNode ret = graph.add(new ReturnNode(graph.unique(new CurrentThread(config.threadObjectOffset, this))));
@@ -677,7 +678,14 @@
         return resultHolder[0].createMethod(metaspaceMethod);
     }
 
-    @Override
+    public ResolvedJavaMethod lookupJavaConstructor(Constructor reflectionConstructor) {
+        CompilerToVM c2vm = graalRuntime.getCompilerToVM();
+        HotSpotResolvedJavaType[] resultHolder = {null};
+        long metaspaceMethod = c2vm.getMetaspaceConstructor(reflectionConstructor, resultHolder);
+        assert metaspaceMethod != 0L;
+        return resultHolder[0].createMethod(metaspaceMethod);
+    }
+
     public ResolvedJavaField lookupJavaField(Field reflectionField) {
         return graalRuntime.getCompilerToVM().getJavaField(reflectionField);
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Wed Nov 28 09:01:39 2012 +0100
@@ -117,7 +117,7 @@
         }
         JavaType type = argumentTypes[index];
         if (type == null || !(type instanceof ResolvedJavaType)) {
-            type = HotSpotGraalRuntime.getInstance().lookupType(arguments.get(index), (HotSpotResolvedJavaType) accessingClass, true);
+            type = HotSpotGraalRuntime.getInstance().lookupType(arguments.get(index), (HotSpotResolvedJavaType) accessingClass, false);
             argumentTypes[index] = type;
         }
         return type;
@@ -134,7 +134,7 @@
 
     @Override
     public JavaType getReturnType(ResolvedJavaType accessingClass) {
-        if (returnTypeCache == null) {
+        if (returnTypeCache == null || !(returnTypeCache instanceof ResolvedJavaType)) {
             returnTypeCache = HotSpotGraalRuntime.getInstance().lookupType(returnType, (HotSpotResolvedJavaType) accessingClass, false);
         }
         return returnTypeCache;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java	Wed Nov 28 09:01:39 2012 +0100
@@ -97,11 +97,16 @@
     }
 
     @Override
-    public boolean isArrayClass() {
+    public boolean isArray() {
         return false;
     }
 
     @Override
+    public boolean isPrimitive() {
+        return true;
+    }
+
+    @Override
     public boolean isInitialized() {
         return true;
     }
@@ -123,10 +128,7 @@
 
     @Override
     public boolean isAssignableTo(ResolvedJavaType other) {
-        if (other instanceof HotSpotTypePrimitive) {
-            return other == this;
-        }
-        return false;
+        return other == this;
     }
 
     @Override
@@ -165,11 +167,6 @@
     }
 
     @Override
-    public Class< ? > toJava() {
-        return javaMirror;
-    }
-
-    @Override
     public boolean isClass(Class c) {
         return c == javaMirror;
     }
@@ -182,4 +179,14 @@
     @Override
     public void initialize() {
     }
+
+    @Override
+    public ResolvedJavaField findInstanceFieldWithOffset(long offset) {
+        return null;
+    }
+
+    @Override
+    public Class<?> mirror() {
+        return javaMirror;
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypeUnresolved.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypeUnresolved.java	Wed Nov 28 09:01:39 2012 +0100
@@ -87,4 +87,9 @@
     public ResolvedJavaType resolve(ResolvedJavaType accessingClass) {
         return (ResolvedJavaType) HotSpotGraalRuntime.getInstance().lookupType(getName(), (HotSpotResolvedJavaType) accessingClass, true);
     }
+
+    @Override
+    public Class<?> mirror() {
+        return ((HotSpotJavaType) resolve(null)).mirror();
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java	Wed Nov 28 09:01:39 2012 +0100
@@ -27,7 +27,6 @@
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.snippets.*;
 
@@ -35,7 +34,7 @@
  * Intrinsic for allocating an on-stack array of integers to hold the dimensions
  * of a multianewarray instruction.
  */
-public final class DimensionsNode extends FixedWithNextNode implements LIRGenLowerable, MonitorEnter {
+public final class DimensionsNode extends FixedWithNextNode implements LIRGenLowerable {
 
     private final int rank;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java	Wed Nov 28 09:01:39 2012 +0100
@@ -85,9 +85,9 @@
                 ResolvedJavaType srcType = src.objectStamp().type();
                 ResolvedJavaType destType = dest.objectStamp().type();
                 if (srcType != null
-                                && srcType.isArrayClass()
+                                && srcType.isArray()
                                 && destType != null
-                                && destType.isArrayClass()) {
+                                && destType.isArray()) {
                     Kind componentKind = srcType.getComponentType().getKind();
                     if (srcType.getComponentType() == destType.getComponentType()) {
                         if (componentKind == Kind.Int) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java	Wed Nov 28 09:01:39 2012 +0100
@@ -342,7 +342,7 @@
         public void lower(InitializeObjectNode initializeNode, LoweringTool tool) {
             StructuredGraph graph = (StructuredGraph) initializeNode.graph();
             HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) initializeNode.type();
-            assert !type.isArrayClass();
+            assert !type.isArray();
             ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph);
             int size = type.instanceSize();
             assert (size % wordSize()) == 0;
--- a/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/BytecodeInterpreter.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/BytecodeInterpreter.java	Wed Nov 28 09:01:39 2012 +0100
@@ -89,7 +89,7 @@
 
             @Override
             public Object invoke(InterpreterFrame caller, ResolvedJavaMethod method, Object[] arguments) throws Throwable {
-                setBackTrace(caller, (Throwable) arguments[0], createStackTraceElements(caller));
+                setBackTrace(caller, (Throwable) arguments[0], createStackTraceElements(caller, runtimeInterface));
                 return null;
             }
         });
@@ -942,7 +942,7 @@
             setStackTrace(frame, t, elements);
             setBackTrace(frame, t, null);
         } else {
-            setBackTrace(frame, t, createStackTraceElements(frame));
+            setBackTrace(frame, t, createStackTraceElements(frame, runtimeInterface));
         }
     }
 
@@ -973,7 +973,7 @@
                     catchType = resolveType(frame, Bytecodes.INSTANCEOF, (char) handler.catchTypeCPI());
                 }
 
-                if (catchType == null || catchType.toJava().isInstance(t)) {
+                if (catchType == null || catchType.isInstance(Constant.forObject(t))) {
                     // the first found exception handler is our exception handler
                     return handler;
                 }
@@ -982,6 +982,10 @@
         return null;
     }
 
+    private Class<?> mirror(ResolvedJavaType type) {
+        return runtimeInterface.getMirror(type);
+    }
+
     private InterpreterFrame allocateFrame(InterpreterFrame frame, BytecodeStream bs) {
         try {
             InterpreterFrame nextFrame = this.callFrame;
@@ -1000,7 +1004,7 @@
                     traceOp(frame, "Method monitor enter");
                 }
                 if (Modifier.isStatic(nextFrame.getMethod().getModifiers())) {
-                    runtimeInterface.monitorEnter(nextFrame.getMethod().getDeclaringClass().toJava());
+                    runtimeInterface.monitorEnter(mirror(nextFrame.getMethod().getDeclaringClass()));
                 } else {
                     Object enterObject = nextFrame.getObject(frame.resolveLocalIndex(0));
                     assert enterObject != null;
@@ -1022,7 +1026,7 @@
                 traceOp(frame, "Method monitor exit");
             }
             if (Modifier.isStatic(frame.getMethod().getModifiers())) {
-                runtimeInterface.monitorExit(frame.getMethod().getDeclaringClass().toJava());
+                runtimeInterface.monitorExit(mirror(frame.getMethod().getDeclaringClass()));
             } else {
                 Object exitObject = frame.getObject(frame.resolveLocalIndex(0));
                 if (exitObject != null) {
@@ -1181,7 +1185,7 @@
     }
 
     private void checkCast(InterpreterFrame frame, char cpi) {
-        frame.pushObject(resolveType(frame, Bytecodes.CHECKCAST, cpi).toJava().cast(frame.popObject()));
+        frame.pushObject(mirror(resolveType(frame, Bytecodes.CHECKCAST, cpi)).cast(frame.popObject()));
     }
 
     private ResolvedJavaType resolveType(InterpreterFrame frame, int opcode, char cpi) {
@@ -1236,7 +1240,7 @@
                     assert false : "unspecified case";
             }
         } else if (constant instanceof JavaType) {
-            frame.pushObject(((JavaType) constant).resolve(method.getDeclaringClass()).toJava());
+            frame.pushObject(mirror(((JavaType) constant).resolve(method.getDeclaringClass())));
         } else {
             assert false : "unexpected case";
         }
@@ -1387,12 +1391,12 @@
         for (int i = dimension - 1; i >= 0; i--) {
             dimensions[i] = frame.popInt();
         }
-        return Array.newInstance(type.toJava(), dimensions);
+        return Array.newInstance(mirror(type), dimensions);
     }
 
     private ResolvedJavaType getLastDimensionType(ResolvedJavaType type) {
         ResolvedJavaType result = type;
-        while (result.isArrayClass()) {
+        while (result.isArray()) {
             result = result.getComponentType();
         }
         return result;
@@ -1400,7 +1404,7 @@
 
     private Object allocateArray(InterpreterFrame frame, char cpi) {
         ResolvedJavaType type = resolveType(frame, Bytecodes.ANEWARRAY, cpi);
-        return Array.newInstance(type.toJava(), frame.popInt());
+        return Array.newInstance(runtimeInterface.getMirror(type), frame.popInt());
     }
 
     private Object allocateNativeArray(InterpreterFrame frame, byte cpi) {
@@ -1613,12 +1617,12 @@
         }
     }
 
-    private static StackTraceElement[] createStackTraceElements(InterpreterFrame frame) {
+    private static StackTraceElement[] createStackTraceElements(InterpreterFrame frame, RuntimeInterpreterInterface runtimeInterface) {
         InterpreterFrame tmp = frame;
         List<StackTraceElement> elements = new ArrayList<>();
         boolean first = false; // filter only first stack elements
         while (tmp != null) {
-            if (first || !filterStackElement(tmp)) {
+            if (first || !filterStackElement(tmp, runtimeInterface)) {
                 first = true;
                 elements.add(tmp.getMethod().asStackTraceElement(tmp.getBCI()));
             }
@@ -1627,8 +1631,8 @@
         return elements.toArray(new StackTraceElement[elements.size()]);
     }
 
-    private static boolean filterStackElement(InterpreterFrame frame) {
-        return Throwable.class.isAssignableFrom(frame.getMethod().getDeclaringClass().toJava());
+    private static boolean filterStackElement(InterpreterFrame frame, RuntimeInterpreterInterface runtimeInterface) {
+        return Throwable.class.isAssignableFrom(runtimeInterface.getMirror(frame.getMethod().getDeclaringClass()));
     }
 
     private ResolvedJavaField findThrowableField(InterpreterFrame frame, String name) {
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Wed Nov 28 09:01:39 2012 +0100
@@ -762,7 +762,7 @@
         while (stream.currentBCI() <= block.endBci) {
             switch (stream.currentBC()) {
                 case RETURN:
-                    if (method.isConstructor() && MetaUtil.isJavaLangObject(method.getDeclaringClass())) {
+                    if (method.isConstructor() && method.getDeclaringClass().isClass(Object.class)) {
                         // return from Object.init implicitly registers a finalizer
                         // for the receiver if needed, so keep it alive.
                         loadOne(block, 0);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Nov 28 09:01:39 2012 +0100
@@ -145,7 +145,9 @@
     private BciBlockMapping createBlockMap() {
         BciBlockMapping map = new BciBlockMapping(method);
         map.build();
-        Debug.dump(map, MetaUtil.format("After block building %f %R %H.%n(%P)", method));
+        if (Debug.isDumpEnabled()) {
+            Debug.dump(map, MetaUtil.format("After block building %f %R %H.%n(%P)", method));
+        }
 
         return map;
     }
@@ -1394,7 +1396,7 @@
     }
 
     private void createReturn() {
-        if (method.isConstructor() && MetaUtil.isJavaLangObject(method.getDeclaringClass())) {
+        if (method.isConstructor() && method.getDeclaringClass().isClass(Object.class)) {
             callRegisterFinalizer();
         }
         Kind returnKind = method.getSignature().getReturnKind().getStackKind();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java	Wed Nov 28 09:01:39 2012 +0100
@@ -148,6 +148,6 @@
         if (boxing == null) {
             return false;
         }
-        return method.getDeclaringClass().toJava() == boxing.type && method.getName().equals(boxing.unboxMethod);
+        return method.getDeclaringClass().isClass(boxing.type) && method.getName().equals(boxing.unboxMethod);
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Wed Nov 28 09:01:39 2012 +0100
@@ -26,12 +26,13 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.virtual.*;
 
 /**
  * Load of a value from a location specified as an offset relative to an object.
  * No null check is performed before the load.
  */
-public class UnsafeLoadNode extends FixedWithNextNode implements Lowerable {
+public class UnsafeLoadNode extends FixedWithNextNode implements Lowerable, Virtualizable {
 
     @Input private ValueNode object;
     @Input private ValueNode offset;
@@ -75,6 +76,26 @@
         tool.getRuntime().lower(this, tool);
     }
 
+    @Override
+    public void virtualize(VirtualizerTool tool) {
+        VirtualObjectNode virtual = tool.getVirtualState(object());
+        if (virtual != null) {
+            ValueNode indexValue = tool.getReplacedValue(offset());
+            if (indexValue.isConstant()) {
+                int fieldIndex = virtual.fieldIndexForOffset(indexValue.asConstant().asLong());
+                if (fieldIndex != -1) {
+                    ValueNode result = tool.getVirtualEntry(virtual, fieldIndex);
+                    VirtualObjectNode virtualResult = tool.getVirtualState(result);
+                    if (virtualResult != null) {
+                        tool.replaceWithVirtual(virtualResult);
+                    } else {
+                        tool.replaceWithValue(result);
+                    }
+                }
+            }
+        }
+    }
+
     @NodeIntrinsic
     public static native <T> T load(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind kind);
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Wed Nov 28 09:01:39 2012 +0100
@@ -26,12 +26,13 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.virtual.*;
 
 /**
  * Store of a value at a location specified as an offset relative to an object.
  * No null check is performed before the store.
  */
-public class UnsafeStoreNode extends FixedWithNextNode implements StateSplit, Lowerable {
+public class UnsafeStoreNode extends FixedWithNextNode implements StateSplit, Lowerable, Virtualizable {
 
     @Input private ValueNode object;
     @Input private ValueNode offset;
@@ -96,6 +97,21 @@
         tool.getRuntime().lower(this, tool);
     }
 
+    @Override
+    public void virtualize(VirtualizerTool tool) {
+        VirtualObjectNode virtual = tool.getVirtualState(object());
+        if (virtual != null) {
+            ValueNode indexValue = tool.getReplacedValue(offset());
+            if (indexValue.isConstant()) {
+                int fieldIndex = virtual.fieldIndexForOffset(indexValue.asConstant().asLong());
+                if (fieldIndex != -1) {
+                    tool.setVirtualEntry(virtual, fieldIndex, value());
+                    tool.delete();
+                }
+            }
+        }
+    }
+
     // specialized on value type until boxing/unboxing is sorted out in intrinsification
     @NodeIntrinsic
     public static native void store(Object object, @ConstantNodeParameter int displacement, long offset, Object value, @ConstantNodeParameter Kind kind);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java	Wed Nov 28 09:01:39 2012 +0100
@@ -84,7 +84,7 @@
     @Override
     public ObjectDesc[] getAllocations(long nextVirtualId, MetaAccessProvider metaAccess) {
         if (instanceClass != null) {
-            assert !instanceClass().isArrayClass();
+            assert !instanceClass().isArray();
             ResolvedJavaField[] fields = instanceClass().getInstanceFields(true);
             ValueNode[] state = new ValueNode[fields.length];
             for (int i = 0; i < state.length; i++) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Wed Nov 28 09:01:39 2012 +0100
@@ -54,7 +54,7 @@
         super(StampFactory.exactNonNull(type));
         this.type = type;
         this.dimensions = new NodeInputList<>(this, dimensions);
-        assert dimensions.length > 0 && type.isArrayClass();
+        assert dimensions.length > 0 && type.isArray();
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/BoxedVirtualObjectNode.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/BoxedVirtualObjectNode.java	Wed Nov 28 09:01:39 2012 +0100
@@ -58,4 +58,10 @@
         assert index == 0;
         return "value";
     }
+
+    @Override
+    public int fieldIndexForOffset(long constantOffset) {
+        // (lstadler) unsafe access to a newly created boxing object should only ever touch the value field
+        return 0;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java	Wed Nov 28 09:01:39 2012 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.nodes.virtual;
 
+import sun.misc.*;
+
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.spi.*;
@@ -70,4 +72,59 @@
     public String fieldName(int index) {
         return "[" + index + "]";
     }
+
+    @Override
+    public int fieldIndexForOffset(long constantOffset) {
+        int baseOffset;
+        int indexScale;
+        switch (componentType.getKind()) {
+            case Boolean:
+                baseOffset = Unsafe.ARRAY_BOOLEAN_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_BOOLEAN_INDEX_SCALE;
+                break;
+            case Byte:
+                baseOffset = Unsafe.ARRAY_BYTE_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_BYTE_INDEX_SCALE;
+                break;
+            case Short:
+                baseOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_SHORT_INDEX_SCALE;
+                break;
+            case Char:
+                baseOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_CHAR_INDEX_SCALE;
+                break;
+            case Int:
+                baseOffset = Unsafe.ARRAY_INT_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_INT_INDEX_SCALE;
+                break;
+            case Long:
+                baseOffset = Unsafe.ARRAY_LONG_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_LONG_INDEX_SCALE;
+                break;
+            case Float:
+                baseOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_FLOAT_INDEX_SCALE;
+                break;
+            case Double:
+                baseOffset = Unsafe.ARRAY_DOUBLE_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_DOUBLE_INDEX_SCALE;
+                break;
+            case Object:
+                baseOffset = Unsafe.ARRAY_OBJECT_BASE_OFFSET;
+                indexScale = Unsafe.ARRAY_OBJECT_INDEX_SCALE;
+                break;
+            default:
+                return -1;
+        }
+        long index = constantOffset - baseOffset;
+        if (index % indexScale != 0) {
+            return -1;
+        }
+        long elementIndex = index / indexScale;
+        if (elementIndex < 0 || elementIndex >= length) {
+            return -1;
+        }
+        return (int) elementIndex;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java	Wed Nov 28 09:01:39 2012 +0100
@@ -75,4 +75,9 @@
         Integer index = fieldMap.get(field);
         return index == null ? -1 : index;
     }
+
+    @Override
+    public int fieldIndexForOffset(long constantOffset) {
+        return fieldIndex(type.findInstanceFieldWithOffset(constantOffset));
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java	Wed Nov 28 09:01:39 2012 +0100
@@ -57,4 +57,6 @@
     public void materializeAt(@SuppressWarnings("unused") FixedNode fixed) {
         // nothing to do in here - this method allows subclasses to respond to materialization
     }
+
+    public abstract int fieldIndexForOffset(long constantOffset);
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/BoxingEliminationPhase.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/BoxingEliminationPhase.java	Wed Nov 28 09:01:39 2012 +0100
@@ -71,7 +71,7 @@
             ObjectStamp stamp = phiNode.objectStamp();
             if (stamp.nonNull() && stamp.isExactType()) {
                 ResolvedJavaType type = stamp.type();
-                if (type != null && type.toJava() == kind.toBoxedJavaClass()) {
+                if (type != null && type.isClass(kind.toBoxedJavaClass())) {
                     StructuredGraph graph = (StructuredGraph) phiNode.graph();
                     result = graph.add(new PhiNode(kind, phiNode.merge()));
                     phiReplacements.put(phiNode, result);
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Wed Nov 28 09:01:39 2012 +0100
@@ -171,6 +171,7 @@
     public static boolean GenAssertionCode                   = ____;
     public static boolean AlignCallsForPatching              = true;
     public static boolean ResolveClassBeforeStaticInvoke     = true;
+    public static boolean CanOmitFrame                       = true;
 
     // Translating tableswitch instructions
     public static int     MinimumJumpTableSize               = 5;
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java	Wed Nov 28 09:01:39 2012 +0100
@@ -214,17 +214,13 @@
             writeByte(POOL_NULL);
             return;
         }
-        if (object instanceof ResolvedJavaType) {
-            writePoolObject(((ResolvedJavaType) object).toJava());
-            return;
-        }
         Integer id = constantPool.get(object);
         if (id == null) {
             addPoolEntry(object);
         } else {
             if (object instanceof Enum<?>) {
                 writeByte(POOL_ENUM);
-            } else if (object instanceof Class<?>) {
+            } else if (object instanceof Class<?> || object instanceof JavaType) {
                 writeByte(POOL_CLASS);
             } else if (object instanceof NodeClass) {
                 writeByte(POOL_NODE_CLASS);
@@ -270,6 +266,11 @@
             writeByte(POOL_ENUM);
             writePoolObject(object.getClass());
             writeInt(((Enum) object).ordinal());
+        } else if (object instanceof JavaType) {
+            JavaType type = (JavaType) object;
+            writeByte(POOL_CLASS);
+            writeString(MetaUtil.toJavaName(type));
+            writeByte(KLASS);
         } else if (object instanceof NodeClass) {
             NodeClass nodeClass = (NodeClass) object;
             writeByte(POOL_NODE_CLASS);
--- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/NewMultiArrayTest.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/NewMultiArrayTest.java	Wed Nov 28 09:01:39 2012 +0100
@@ -99,9 +99,8 @@
     @Override
     protected Object referenceInvoke(Method method, Object receiver, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
         if (bottomType != null) {
-            Class< ? > componentType = bottomType.toJava();
             try {
-                return Array.newInstance(componentType, dimensions);
+                return Array.newInstance(bottomClass, dimensions);
             } catch (Exception e) {
                 throw new InvocationTargetException(e);
             }
@@ -111,11 +110,13 @@
 
     ResolvedJavaType arrayType;
     ResolvedJavaType bottomType;
+    Class bottomClass;
     int[] dimensions;
 
     @Test
     public void test1() {
         for (Class clazz : new Class[] {byte.class, char.class, short.class, int.class, float.class, long.class, double.class, String.class}) {
+            bottomClass = clazz;
             bottomType = runtime.lookupJavaType(clazz);
             arrayType = bottomType;
             for (int rank : new int[] {1, 2, 10, 50, 100, 200, 254, 255}) {
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java	Wed Nov 28 09:01:39 2012 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.snippets;
 
+import static com.oracle.graal.api.meta.MetaUtil.*;
+
 import java.lang.annotation.*;
 import java.lang.reflect.*;
 
@@ -80,7 +82,7 @@
                 if (method.getAnnotation(NodeIntrinsic.class) != null) {
                     return false;
                 }
-                if (Throwable.class.isAssignableFrom(method.getDeclaringClass().toJava())) {
+                if (Throwable.class.isAssignableFrom(getMirrorOrFail(method.getDeclaringClass(), null))) {
                     if (method.getName().equals("<init>")) {
                         return false;
                     }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java	Wed Nov 28 09:01:39 2012 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.snippets;
 
+import static com.oracle.graal.api.meta.MetaUtil.*;
+
 import java.lang.reflect.*;
 import java.util.*;
 
@@ -79,6 +81,15 @@
         }
     }
 
+    public static Class<?>[] signatureToTypes(Signature signature, ResolvedJavaType accessingClass) {
+        int count = signature.getParameterCount(false);
+        Class<?>[] result = new Class< ? >[count];
+        for (int i = 0; i < result.length; ++i) {
+            result[i] = getMirrorOrFail(signature.getParameterType(i, accessingClass).resolve(accessingClass), null);
+        }
+        return result;
+    }
+
     private void tryIntrinsify(Invoke invoke) {
         ResolvedJavaMethod target = invoke.methodCallTarget().targetMethod();
         NodeIntrinsic intrinsic = target.getAnnotation(Node.NodeIntrinsic.class);
@@ -87,7 +98,7 @@
             assert target.getAnnotation(Fold.class) == null;
             assert Modifier.isNative(target.getModifiers()) : "node intrinsic " + target + " should be native";
 
-            Class< ? >[] parameterTypes = MetaUtil.signatureToTypes(target.getSignature(), declaringClass);
+            Class< ? >[] parameterTypes = signatureToTypes(target.getSignature(), declaringClass);
             ResolvedJavaType returnType = target.getSignature().getReturnType(declaringClass).resolve(declaringClass);
 
             // Prepare the arguments for the reflective constructor call on the node class.
@@ -104,7 +115,7 @@
             // Clean up checkcast instructions inserted by javac if the return type is generic.
             cleanUpReturnCheckCast(newInstance);
         } else if (target.getAnnotation(Fold.class) != null) {
-            Class< ? >[] parameterTypes = MetaUtil.signatureToTypes(target.getSignature(), declaringClass);
+            Class< ? >[] parameterTypes = signatureToTypes(target.getSignature(), declaringClass);
 
             // Prepare the arguments for the reflective method call
             Object[] arguments = prepareArguments(invoke, parameterTypes, target, true);
@@ -115,7 +126,7 @@
             }
 
             // Call the method
-            Constant constant = callMethod(target.getSignature().getReturnKind(), declaringClass.toJava(), target.getName(), parameterTypes, receiver, arguments);
+            Constant constant = callMethod(target.getSignature().getReturnKind(), getMirrorOrFail(declaringClass, null), target.getName(), parameterTypes, receiver, arguments);
 
             if (constant != null) {
                 // Replace the invoke with the result of the call
@@ -180,7 +191,7 @@
     private static Class< ? > getNodeClass(ResolvedJavaMethod target, NodeIntrinsic intrinsic) {
         Class< ? > result = intrinsic.value();
         if (result == NodeIntrinsic.class) {
-            result = target.getDeclaringClass().toJava();
+            return getMirrorOrFail(target.getDeclaringClass(), null);
         }
         assert Node.class.isAssignableFrom(result);
         return result;
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Wed Nov 28 09:01:39 2012 +0100
@@ -404,7 +404,7 @@
     private static boolean checkVarargs(final ResolvedJavaMethod method, Signature signature, int i, String name, Varargs varargs) {
         Object arg = varargs.getArray();
         ResolvedJavaType type = (ResolvedJavaType) signature.getParameterType(i, method.getDeclaringClass());
-        assert type.isArrayClass() : "varargs parameter must be an array type";
+        assert type.isArray() : "varargs parameter must be an array type";
         assert type.isInstance(Constant.forObject(arg)) : "value for " + name + " is not a " + MetaUtil.toJavaName(type) + " instance: " + arg;
         return true;
     }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java	Wed Nov 28 09:01:15 2012 +0100
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java	Wed Nov 28 09:01:39 2012 +0100
@@ -85,7 +85,7 @@
     private void materializeChangedBefore(FixedNode fixed, VirtualObjectNode virtual, HashSet<VirtualObjectNode> deferred, GraphEffectList deferredStores, GraphEffectList materializeEffects) {
         trace("materializing %s at %s", virtual, fixed);
         ObjectState obj = getObjectState(virtual);
-        if (obj.getLockCount() > 0 && obj.virtual.type().isArrayClass()) {
+        if (obj.getLockCount() > 0 && obj.virtual.type().isArray()) {
             throw new BailoutException("array materialized with lock");
         }
 
--- a/src/share/vm/code/debugInfo.cpp	Wed Nov 28 09:01:15 2012 +0100
+++ b/src/share/vm/code/debugInfo.cpp	Wed Nov 28 09:01:39 2012 +0100
@@ -77,7 +77,11 @@
 
 enum { LOCATION_CODE = 0, CONSTANT_INT_CODE = 1,  CONSTANT_OOP_CODE = 2,
                           CONSTANT_LONG_CODE = 3, CONSTANT_DOUBLE_CODE = 4,
-                          OBJECT_CODE = 5,        OBJECT_ID_CODE = 6 };
+                          OBJECT_CODE = 5,        OBJECT_ID_CODE = 6,
+#ifdef GRAAL
+                          DEFERRED_READ_CODE = 7, DEFERRED_WRITE_CODE = 8
+#endif // GRAAL
+};
 
 ScopeValue* ScopeValue::read_from(DebugInfoReadStream* stream) {
   ScopeValue* result = NULL;
@@ -89,6 +93,10 @@
    case CONSTANT_DOUBLE_CODE: result = new ConstantDoubleValue(stream);  break;
    case OBJECT_CODE:          result = stream->read_object_value();      break;
    case OBJECT_ID_CODE:       result = stream->get_cached_object();      break;
+#ifdef GRAAL
+   case DEFERRED_READ_CODE:   result = new DeferredReadValue(stream);    break;
+   case DEFERRED_WRITE_CODE:  result = new DeferredWriteValue(stream);   break;
+#endif // GRAAL
    default: ShouldNotReachHere();
   }
   return result;
@@ -109,6 +117,63 @@
   location().print_on(st);
 }
 
+#ifdef GRAAL
+
+// DeferredLocationValue
+
+DeferredLocationValue::DeferredLocationValue(DebugInfoReadStream* stream) {
+  _base = read_from(stream);
+  _index = read_from(stream);
+  _scale = stream->read_int();
+  _disp = stream->read_long();
+}
+
+void DeferredLocationValue::write_on(DebugInfoWriteStream* stream) {
+  _base->write_on(stream);
+  _index->write_on(stream);
+  stream->write_int(_scale);
+  stream->write_long(_disp);
+}
+
+void DeferredLocationValue::print_on(outputStream* st) const {
+  _base->print_on(st);
+  _index->print_on(st);
+  st->print("%i %i", _scale, _disp);
+}
+
+// DeferredReadValue
+
+DeferredReadValue::DeferredReadValue(DebugInfoReadStream* stream)
+: DeferredLocationValue(stream) {
+}
+
+void DeferredReadValue::write_on(DebugInfoWriteStream* st) {
+  DeferredLocationValue::write_on(st);
+}
+
+void DeferredReadValue::print_on(outputStream* st) const {
+  DeferredLocationValue::print_on(st);
+}
+
+// DeferredWriteValue
+
+DeferredWriteValue::DeferredWriteValue(DebugInfoReadStream* stream)
+: DeferredLocationValue(stream) {
+  _value = read_from(stream);
+}
+
+void DeferredWriteValue::write_on(DebugInfoWriteStream* st) {
+  DeferredLocationValue::write_on(st);
+  _value->write_on(st);
+}
+
+void DeferredWriteValue::print_on(outputStream* st) const {
+  DeferredLocationValue::print_on(st);
+  _value->print_on(st);
+}
+
+#endif // GRAAL
+
 // ObjectValue
 
 void ObjectValue::read_object(DebugInfoReadStream* stream) {
--- a/src/share/vm/code/debugInfo.hpp	Wed Nov 28 09:01:15 2012 +0100
+++ b/src/share/vm/code/debugInfo.hpp	Wed Nov 28 09:01:39 2012 +0100
@@ -61,6 +61,11 @@
   // Serialization of debugging information
   virtual void write_on(DebugInfoWriteStream* stream) = 0;
   static ScopeValue* read_from(DebugInfoReadStream* stream);
+
+#ifdef GRAAL
+  // Printing
+  virtual void print_on(outputStream* st) const = 0;
+#endif // GRAAL
 };
 
 
@@ -83,6 +88,64 @@
   void print_on(outputStream* st) const;
 };
 
+#ifdef GRAAL
+
+class DeferredLocationValue: public ScopeValue {
+private:
+  ScopeValue* _base;
+  ScopeValue* _index;
+  jint _scale;
+  jlong _disp;
+public:
+  DeferredLocationValue(ScopeValue* base, ScopeValue* index, jint scale, jlong disp)
+  : _base(base), _index(index), _scale(scale), _disp(disp) { }
+
+  ScopeValue* base() { return _base; }
+  ScopeValue* index() { return _index; }
+  jint scale() { return _scale; }
+  jlong disp() { return _disp; }
+
+  // Serialization of debugging information
+  DeferredLocationValue(DebugInfoReadStream* stream);
+  void write_on(DebugInfoWriteStream* stream);
+
+  // Printing
+  void print_on(outputStream* st) const;
+};
+
+
+class DeferredReadValue: public DeferredLocationValue {
+public:
+  DeferredReadValue(ScopeValue* base, ScopeValue* index, jint scale, jint disp)
+  : DeferredLocationValue(base, index, scale, disp) { }
+
+  // Serialization of debugging information
+  DeferredReadValue(DebugInfoReadStream* stream);
+  void write_on(DebugInfoWriteStream* stream);
+
+  // Printing
+  void print_on(outputStream* st) const;
+};
+
+class DeferredWriteValue: public DeferredLocationValue {
+private:
+  ScopeValue* _value;
+public:
+  DeferredWriteValue(ScopeValue* base, ScopeValue* index, jint scale, jint disp, ScopeValue* value)
+  : DeferredLocationValue(base, index, scale, disp), _value(value) { }
+
+  ScopeValue* value() { return _value; }
+
+  // Serialization of debugging information
+  DeferredWriteValue(DebugInfoReadStream* stream);
+  void write_on(DebugInfoWriteStream* stream);
+
+  // Printing
+  void print_on(outputStream* st) const;
+};
+
+#endif // GRAAL
+
 
 // An ObjectValue describes an object eliminated by escape analysis.
 
--- a/src/share/vm/code/debugInfoRec.cpp	Wed Nov 28 09:01:15 2012 +0100
+++ b/src/share/vm/code/debugInfoRec.cpp	Wed Nov 28 09:01:39 2012 +0100
@@ -213,6 +213,29 @@
   return result;
 }
 
+#ifdef GRAAL
+
+int DebugInformationRecorder::serialize_deferred_writes(GrowableArray<DeferredWriteValue*>* deferred_writes) {
+  if (deferred_writes == NULL || deferred_writes->is_empty()) return DebugInformationRecorder::serialized_null;
+  assert(_recording_state == rs_safepoint, "must be recording a safepoint");
+  int result = stream()->position();
+  assert(result != serialized_null, "sanity");
+  stream()->write_int(deferred_writes->length());
+  for (int index = 0; index < deferred_writes->length(); index++) {
+    deferred_writes->at(index)->write_on(stream());
+  }
+
+  // (See comment below on DebugInformationRecorder::describe_scope.)
+  int shared_result = find_sharable_decode_offset(result);
+  if (shared_result != serialized_null) {
+    stream()->set_position(result);
+    result = shared_result;
+  }
+
+  return result;
+}
+
+#endif // GRAAL
 
 #ifndef PRODUCT
 // These variables are put into one block to reduce relocations
@@ -289,7 +312,11 @@
                                               bool        return_oop,
                                               DebugToken* locals,
                                               DebugToken* expressions,
-                                              DebugToken* monitors) {
+                                              DebugToken* monitors
+#ifdef GRAAL
+                                              , DebugToken* deferred_writes
+#endif // GRAAL
+                                              ) {
   assert(_recording_state != rs_null, "nesting of recording calls");
   PcDesc* last_pd = last_pc();
   assert(last_pd->pc_offset() == pc_offset, "must be last pc");
@@ -328,6 +355,9 @@
   stream()->write_int((intptr_t) locals);
   stream()->write_int((intptr_t) expressions);
   stream()->write_int((intptr_t) monitors);
+#ifdef GRAAL
+  stream()->write_int((intptr_t) deferred_writes);
+#endif // GRAAL
 
   // Here's a tricky bit.  We just wrote some bytes.
   // Wouldn't it be nice to find that we had already
@@ -409,6 +439,14 @@
   return (DebugToken*) (intptr_t) serialize_monitor_values(monitors);
 }
 
+#ifdef GRAAL
+
+DebugToken* DebugInformationRecorder::create_deferred_writes(GrowableArray<DeferredWriteValue*>* deferred_writes) {
+  assert(!recorders_frozen(), "not frozen yet");
+  return (DebugToken*) (intptr_t) serialize_deferred_writes(deferred_writes);
+}
+
+#endif // GRAAL
 
 int DebugInformationRecorder::data_size() {
   debug_only(mark_recorders_frozen());  // mark it "frozen" for asserts
--- a/src/share/vm/code/debugInfoRec.hpp	Wed Nov 28 09:01:15 2012 +0100
+++ b/src/share/vm/code/debugInfoRec.hpp	Wed Nov 28 09:01:39 2012 +0100
@@ -107,7 +107,11 @@
                       bool        return_oop = false,
                       DebugToken* locals      = NULL,
                       DebugToken* expressions = NULL,
-                      DebugToken* monitors    = NULL);
+                      DebugToken* monitors    = NULL
+#ifdef GRAAL
+                      , DebugToken* deferred_writes = NULL
+#endif // GRAAL
+                      );
 
 
   void dump_object_pool(GrowableArray<ScopeValue*>* objects);
@@ -120,6 +124,9 @@
   // helper fuctions for describe_scope to enable sharing
   DebugToken* create_scope_values(GrowableArray<ScopeValue*>* values);
   DebugToken* create_monitor_values(GrowableArray<MonitorValue*>* monitors);
+#ifdef GRAAL
+  DebugToken* create_deferred_writes(GrowableArray<DeferredWriteValue*>* deferred_writes);
+#endif // GRAAL
 
   // returns the size of the generated scopeDescs.
   int data_size();
@@ -194,6 +201,9 @@
 
   int  serialize_monitor_values(GrowableArray<MonitorValue*>* monitors);
   int  serialize_scope_values(GrowableArray<ScopeValue*>* values);
+#ifdef GRAAL
+  int serialize_deferred_writes(GrowableArray<DeferredWriteValue*>* deferred_writes);
+#endif // GRAAL
   int  find_sharable_decode_offset(int stream_offset);
 
 #ifndef PRODUCT
--- a/src/share/vm/code/scopeDesc.cpp	Wed Nov 28 09:01:15 2012 +0100
+++ b/src/share/vm/code/scopeDesc.cpp	Wed Nov 28 09:01:39 2012 +0100
@@ -73,6 +73,9 @@
     _locals_decode_offset = DebugInformationRecorder::serialized_null;
     _expressions_decode_offset = DebugInformationRecorder::serialized_null;
     _monitors_decode_offset = DebugInformationRecorder::serialized_null;
+#ifdef GRAAL
+    _deferred_writes_decode_offset = DebugInformationRecorder::serialized_null;
+#endif // GRAAL
   } else {
     // decode header
     DebugInfoReadStream* stream  = stream_at(decode_offset());
@@ -85,6 +88,9 @@
     _locals_decode_offset      = stream->read_int();
     _expressions_decode_offset = stream->read_int();
     _monitors_decode_offset    = stream->read_int();
+#ifdef GRAAL
+    _deferred_writes_decode_offset = stream->read_int();
+#endif // GRAAL
   }
 }
 
@@ -126,6 +132,25 @@
   return result;
 }
 
+#ifdef GRAAL
+
+GrowableArray<DeferredWriteValue*>* ScopeDesc::decode_deferred_writes(int decode_offset) {
+  if (decode_offset == DebugInformationRecorder::serialized_null) return NULL;
+  DebugInfoReadStream* stream  = stream_at(decode_offset);
+  int length = stream->read_int();
+  GrowableArray<DeferredWriteValue*>* result = new GrowableArray<DeferredWriteValue*> (length);
+  for (int index = 0; index < length; index++) {
+    result->push(new DeferredWriteValue(stream));
+  }
+  return result;
+}
+
+GrowableArray<DeferredWriteValue*>* ScopeDesc::deferred_writes() {
+  return decode_deferred_writes(_deferred_writes_decode_offset);
+}
+
+#endif // GRAAL
+
 DebugInfoReadStream* ScopeDesc::stream_at(int decode_offset) const {
   return new DebugInfoReadStream(_code, decode_offset, _objects);
 }
@@ -225,8 +250,8 @@
     }
   }
 
-#ifdef COMPILER2
-  if (DoEscapeAnalysis && is_top() && _objects != NULL) {
+#if defined(COMPILER2) || defined(GRAAL)
+  if (NOT_GRAAL(DoEscapeAnalysis &&) is_top() && _objects != NULL) {
     tty->print_cr("Objects");
     for (int i = 0; i < _objects->length(); i++) {
       ObjectValue* sv = (ObjectValue*) _objects->at(i);
@@ -235,7 +260,20 @@
       tty->cr();
     }
   }
-#endif // COMPILER2
+#endif // COMPILER2 || GRAAL
+#ifdef GRAAL
+  // deferred writes
+  { GrowableArray<DeferredWriteValue*>* l = ((ScopeDesc*) this)->deferred_writes();
+    if (l != NULL) {
+      st->print_cr("   Deferred writes");
+      for (int index = 0; index < l->length(); index++) {
+        st->print("    - @%d: ", index);
+        l->at(index)->print_on(st);
+        st->cr();
+      }
+    }
+  }
+#endif
 }
 
 #endif
--- a/src/share/vm/code/scopeDesc.hpp	Wed Nov 28 09:01:15 2012 +0100
+++ b/src/share/vm/code/scopeDesc.hpp	Wed Nov 28 09:01:39 2012 +0100
@@ -78,6 +78,9 @@
   GrowableArray<ScopeValue*>*   expressions();
   GrowableArray<MonitorValue*>* monitors();
   GrowableArray<ScopeValue*>*   objects();
+#ifdef GRAAL
+  GrowableArray<DeferredWriteValue*>* deferred_writes();
+#endif // GRAAL
 
   // Stack walking, returns NULL if this is the outer most scope.
   ScopeDesc* sender() const;
@@ -107,6 +110,9 @@
   int _locals_decode_offset;
   int _expressions_decode_offset;
   int _monitors_decode_offset;
+#ifdef GRAAL
+  int _deferred_writes_decode_offset;
+#endif // GRAAL
 
   // Object pool
   GrowableArray<ScopeValue*>* _objects;
@@ -119,6 +125,9 @@
   GrowableArray<ScopeValue*>* decode_scope_values(int decode_offset);
   GrowableArray<MonitorValue*>* decode_monitor_values(int decode_offset);
   GrowableArray<ScopeValue*>* decode_object_values(int decode_offset);
+#ifdef GRAAL
+  GrowableArray<DeferredWriteValue*>* decode_deferred_writes(int decode_offset);
+#endif // GRAAL
 
   DebugInfoReadStream* stream_at(int decode_offset) const;
 
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Wed Nov 28 09:01:15 2012 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Wed Nov 28 09:01:39 2012 +0100
@@ -530,9 +530,13 @@
   DebugToken* expressions_token = _debug_recorder->create_scope_values(expressions);
   DebugToken* monitors_token = _debug_recorder->create_monitor_values(monitors);
 
+  GrowableArray<DeferredWriteValue*>* deferred_writes = new GrowableArray<DeferredWriteValue*> ();
+//  deferred_writes->append(new DeferredWriteValue(new LocationValue(Location::new_reg_loc(Location::lng, rax->as_VMReg())), new ConstantIntValue(0), 0, 100, new ConstantIntValue(123)));
+  DebugToken* deferred_writes_token = _debug_recorder->create_deferred_writes(deferred_writes);
+
   bool throw_exception = BytecodeFrame::rethrowException(frame) == JNI_TRUE;
 
-  _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, false, locals_token, expressions_token, monitors_token);
+  _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, false, locals_token, expressions_token, monitors_token, deferred_writes_token);
 }
 
 void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) {
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Wed Nov 28 09:01:15 2012 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Wed Nov 28 09:01:39 2012 +0100
@@ -195,6 +195,17 @@
   return (jlong) (address) method();
 }
 
+C2V_VMENTRY(jlong, getMetaspaceConstructor, (JNIEnv *, jobject, jobject reflection_ctor_handle, jobject resultHolder))
+  oop reflection_ctor = JNIHandles::resolve(reflection_ctor_handle);
+  oop reflection_holder = java_lang_reflect_Constructor::clazz(reflection_ctor);
+  int slot = java_lang_reflect_Constructor::slot(reflection_ctor);
+  Klass* holder = java_lang_Class::as_Klass(reflection_holder);
+  methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
+  Handle type = GraalCompiler::createHotSpotResolvedJavaType(method, CHECK_0);
+  objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type());
+  return (jlong) (address) method();
+}
+
 C2V_VMENTRY(jobject, getJavaField, (JNIEnv *, jobject, jobject reflection_field_handle))
   oop reflection_field = JNIHandles::resolve(reflection_field_handle);
   oop reflection_holder = java_lang_reflect_Field::clazz(reflection_field);
@@ -892,6 +903,7 @@
 #define RUNTIME_CALL          "Lcom/oracle/graal/api/code/RuntimeCall;"
 #define EXCEPTION_HANDLERS    "[Lcom/oracle/graal/api/meta/ExceptionHandler;"
 #define REFLECT_METHOD        "Ljava/lang/reflect/Method;"
+#define REFLECT_CONSTRUCTOR   "Ljava/lang/reflect/Constructor;"
 #define REFLECT_FIELD         "Ljava/lang/reflect/Field;"
 #define STRING                "Ljava/lang/String;"
 #define OBJECT                "Ljava/lang/Object;"
@@ -937,6 +949,7 @@
   {CC"getMaxCallTargetOffset",        CC"(J)J",                                                         FN_PTR(getMaxCallTargetOffset)},
   {CC"getResolvedType",               CC"("CLASS")"RESOLVED_TYPE,                                       FN_PTR(getResolvedType)},
   {CC"getMetaspaceMethod",            CC"("REFLECT_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD,        FN_PTR(getMetaspaceMethod)},
+  {CC"getMetaspaceConstructor",       CC"("REFLECT_CONSTRUCTOR"["HS_RESOLVED_TYPE")"METASPACE_METHOD,   FN_PTR(getMetaspaceConstructor)},
   {CC"getJavaField",                  CC"("REFLECT_FIELD")"HS_RESOLVED_FIELD,                           FN_PTR(getJavaField)},
   {CC"initializeConfiguration",       CC"("HS_CONFIG")V",                                               FN_PTR(initializeConfiguration)},
   {CC"installCode",                   CC"("HS_COMP_RESULT HS_INSTALLED_CODE HS_CODE_INFO")"HS_INSTALLED_CODE, FN_PTR(installCode)},
--- a/src/share/vm/graal/graalVMToCompiler.cpp	Wed Nov 28 09:01:15 2012 +0100
+++ b/src/share/vm/graal/graalVMToCompiler.cpp	Wed Nov 28 09:01:39 2012 +0100
@@ -234,17 +234,6 @@
   return (oop) result.get_jobject();
 }
 
-oop VMToCompiler::createSignature(Handle name, TRAPS) {
-  assert(!name.is_null(), "just checking");
-  JavaValue result(T_OBJECT);
-  JavaCallArguments args;
-  args.push_oop(instance());
-  args.push_oop(name);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createSignature_name(), vmSymbols::createSignature_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createSignature");
-  return (oop) result.get_jobject();
-}
-
 oop VMToCompiler::createConstant(Handle kind, jlong value, TRAPS) {
   JavaValue result(T_OBJECT);
   JavaCallArguments args;
--- a/src/share/vm/graal/graalVMToCompiler.hpp	Wed Nov 28 09:01:15 2012 +0100
+++ b/src/share/vm/graal/graalVMToCompiler.hpp	Wed Nov 28 09:01:39 2012 +0100
@@ -86,9 +86,6 @@
   // public abstract JavaType createPrimitiveJavaType(int basicType);
   static oop createPrimitiveJavaType(int basicType, TRAPS);
 
-  // public abstract Signature createSignature(String signature);
-  static oop createSignature(Handle name, TRAPS);
-
   // public abstract Constant createConstant(Kind kind, long value);
   static oop createConstant(Handle kind, jlong value, TRAPS);