changeset 7044:34753b057324

added unit tests for JavaType, JavaMethod and ResolvedJavaMethod
author Doug Simon <doug.simon@oracle.com>
date Tue, 27 Nov 2012 16:09:05 +0100
parents 947de43c68d6
children 7ac6e4c10e37
files graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/NameAndSignature.java graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java src/share/vm/graal/graalCompilerToVM.cpp
diffstat 12 files changed, 472 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- /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	Tue Nov 27 16:09:05 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	Tue Nov 27 16:09:05 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	Tue Nov 27 16:09:05 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	Tue Nov 27 15:10:50 2012 +0100
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java	Tue Nov 27 16:09:05 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
--- /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	Tue Nov 27 16:09:05 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	Tue Nov 27 15:10:50 2012 +0100
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java	Tue Nov 27 16:09:05 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
@@ -351,44 +351,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) {
@@ -401,7 +365,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);
                     }
@@ -414,10 +378,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;
                 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Tue Nov 27 15:10:50 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Tue Nov 27 16:09:05 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.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Tue Nov 27 15:10:50 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Tue Nov 27 16:09:05 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	Tue Nov 27 15:10:50 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Tue Nov 27 16:09:05 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/meta/HotSpotResolvedJavaType.java	Tue Nov 27 15:10:50 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Tue Nov 27 16:09:05 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.*;
@@ -159,12 +160,36 @@
         return javaComponentType == null ? null : fromClass(javaComponentType);
     }
 
+    public ResolvedJavaType getElementType() {
+        ResolvedJavaType type = this;
+        while (type.getComponentType() != null) {
+            type = type.getComponentType();
+        }
+        return type;
+    }
+
+    private static boolean hasSubtype(ResolvedJavaType type) {
+        assert !type.isInterface() && !type.isArrayClass() : type;
+        if (isPrimitive(type)) {
+            return false;
+        }
+        HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
+        if (unsafeReadWord(((HotSpotResolvedJavaType) type).metaspaceKlass + config.subklassOffset) != 0) {
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public ResolvedJavaType findUniqueConcreteSubtype() {
+        HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
         if (isArrayClass()) {
-            return getComponentType().findUniqueConcreteSubtype() == getComponentType() ? this : null;
+            ResolvedJavaType elementType = getElementType();
+            if (hasSubtype(elementType)) {
+                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 +201,6 @@
             if (unsafeReadWord(type.metaspaceKlass + config.subklassOffset) != 0) {
                 return null;
             }
-            assert !type.isInterface();
             return type;
         }
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Nov 27 15:10:50 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Nov 27 16:09:05 2012 +0100
@@ -675,7 +675,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/src/share/vm/graal/graalCompilerToVM.cpp	Tue Nov 27 15:10:50 2012 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Tue Nov 27 16:09:05 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)},