changeset 6699:d79098b9db3b

Support for interfaces in the Graal API: Make interfaces implemented by a ResolvedJavaType available; change semantics of ResolvedJavaType.getSuperclass to return null for interfaces (to conform with java.lang.Class); change semantics of ResolvedJavaType.isInstanceClass to return false for interfaces.
author Christian Wimmer <christian.wimmer@oracle.com>
date Fri, 09 Nov 2012 17:15:13 -0800
parents f5715c5a106a
children 3a93ae3a6c9e
files graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java src/share/vm/graal/graalCompiler.cpp
diffstat 9 files changed, 49 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Fri Nov 09 17:04:16 2012 -0800
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Fri Nov 09 17:15:13 2012 -0800
@@ -37,6 +37,15 @@
 public class MetaUtil {
 
     /**
+     * Returns true if the specified typed is exactly the type {@link java.lang.Object}.
+     */
+    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;
+    }
+
+    /**
      * Extends the functionality of {@link Class#getSimpleName()} to include a non-empty string for anonymous and local
      * classes.
      * 
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Fri Nov 09 17:04:16 2012 -0800
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Fri Nov 09 17:15:13 2012 -0800
@@ -152,6 +152,11 @@
     ResolvedJavaType getSuperclass();
 
     /**
+     * Gets the interfaces that this type defines. This method is analogous to {@link Class#getInterfaces()}.
+     */
+    ResolvedJavaType[] getInterfaces();
+
+    /**
      * Walks the class hierarchy upwards and returns the least common class that is a superclass of both the current and
      * the given type.
      *
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Fri Nov 09 17:04:16 2012 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Fri Nov 09 17:15:13 2012 -0800
@@ -49,6 +49,7 @@
     private int instanceSize;
     private HashMap<Long, ResolvedJavaField> fieldCache;
     private ResolvedJavaType superType;
+    private ResolvedJavaType[] interfaces;
     private boolean superTypeSet;
     private ResolvedJavaField[] fields;
     private ConstantPool constantPool;
@@ -94,13 +95,31 @@
     @Override
     public ResolvedJavaType getSuperclass() {
         if (!superTypeSet) {
-            superType = (ResolvedJavaType) HotSpotGraalRuntime.getInstance().getCompilerToVM().getSuperType(this);
+            Class<?> javaSuper = toJava().getSuperclass();
+            if (javaSuper == null) {
+                superType = null;
+            } else {
+                superType = HotSpotGraalRuntime.getInstance().getRuntime().lookupJavaType(javaSuper);
+            }
             superTypeSet = true;
         }
         return superType;
     }
 
     @Override
+    public ResolvedJavaType[] getInterfaces() {
+        if (interfaces == null) {
+            Class[] javaInterfaces = toJava().getInterfaces();
+            ResolvedJavaType[] result = new ResolvedJavaType[javaInterfaces.length];
+            for (int i = 0; i < javaInterfaces.length; i++) {
+                result[i] = HotSpotGraalRuntime.getInstance().getRuntime().lookupJavaType(javaInterfaces[i]);
+            }
+            interfaces = result;
+        }
+        return interfaces;
+    }
+
+    @Override
     public ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType) {
         if (otherType instanceof HotSpotTypePrimitive) {
             return null;
@@ -145,6 +164,7 @@
 
     @Override
     public boolean isArrayClass() {
+        assert isArrayClass ^ (isInterface || isInstanceClass);
         return isArrayClass;
     }
 
@@ -171,11 +191,13 @@
 
     @Override
     public boolean isInstanceClass() {
+        assert isInstanceClass ^ (isInterface || isArrayClass);
         return isInstanceClass;
     }
 
     @Override
     public boolean isInterface() {
+        assert isInterface ^ (isInstanceClass || isArrayClass);
         return isInterface;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Nov 09 17:04:16 2012 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Nov 09 17:15:13 2012 -0800
@@ -57,6 +57,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.printer.*;
 import com.oracle.graal.snippets.*;
 
 /**
@@ -482,12 +483,10 @@
                 ResolvedJavaType arrayType = array.objectStamp().type();
                 if (arrayType != null && array.objectStamp().isExactType()) {
                     ResolvedJavaType elementType = arrayType.getComponentType();
-                    if (elementType.getSuperclass() != null) {
+                    if (!MetaUtil.isJavaLangObject(elementType)) {
                         CheckCastNode checkcast = graph.add(new CheckCastNode(elementType, value, null));
                         graph.addBeforeFixed(storeIndexed, checkcast);
                         value = checkcast;
-                    } else {
-                        assert elementType.getName().equals("Ljava/lang/Object;") : elementType.getName();
                     }
                 } else {
                     LoadHubNode arrayClass = graph.add(new LoadHubNode(array));
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java	Fri Nov 09 17:04:16 2012 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java	Fri Nov 09 17:15:13 2012 -0800
@@ -71,6 +71,11 @@
     }
 
     @Override
+    public ResolvedJavaType[] getInterfaces() {
+        return new ResolvedJavaType[0];
+    }
+
+    @Override
     public ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType) {
         return null;
     }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Fri Nov 09 17:04:16 2012 -0800
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Fri Nov 09 17:15:13 2012 -0800
@@ -762,7 +762,7 @@
         while (stream.currentBCI() <= block.endBci) {
             switch (stream.currentBC()) {
                 case RETURN:
-                    if (method.isConstructor() && method.getDeclaringClass().getSuperclass() == null) {
+                    if (method.isConstructor() && MetaUtil.isJavaLangObject(method.getDeclaringClass())) {
                         // 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/FrameStateBuilder.java	Fri Nov 09 17:04:16 2012 -0800
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java	Fri Nov 09 17:15:13 2012 -0800
@@ -339,7 +339,7 @@
      * @param i the index into the locals
      * @return the instruction that produced the value for the specified local
      */
-    protected final ValueNode localAt(int i) {
+    public final ValueNode localAt(int i) {
         return locals[i];
     }
 
@@ -349,7 +349,7 @@
      * @param i the index into the stack, with {@code 0} being the bottom of the stack
      * @return the instruction at the specified position in the stack
      */
-    protected final ValueNode stackAt(int i) {
+    public final ValueNode stackAt(int i) {
         return stack[i];
     }
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Nov 09 17:04:16 2012 -0800
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Nov 09 17:15:13 2012 -0800
@@ -1363,7 +1363,7 @@
     }
 
     private void createReturn() {
-        if (method.isConstructor() && method.getDeclaringClass().getSuperclass() == null) {
+        if (method.isConstructor() && MetaUtil.isJavaLangObject(method.getDeclaringClass())) {
             callRegisterFinalizer();
         }
         Kind returnKind = method.getSignature().getReturnKind().getStackKind();
--- a/src/share/vm/graal/graalCompiler.cpp	Fri Nov 09 17:04:16 2012 -0800
+++ b/src/share/vm/graal/graalCompiler.cpp	Fri Nov 09 17:15:13 2012 -0800
@@ -286,7 +286,7 @@
   HotSpotResolvedJavaType::set_accessFlags(obj, klass->access_flags().as_int());
   HotSpotResolvedJavaType::set_isInterface(obj, klass->is_interface());
   HotSpotResolvedJavaType::set_superCheckOffset(obj, klass->super_check_offset());
-  HotSpotResolvedJavaType::set_isInstanceClass(obj, klass->oop_is_instance());
+  HotSpotResolvedJavaType::set_isInstanceClass(obj, klass->oop_is_instance() && !klass->is_interface());
 
   if (klass->oop_is_javaArray()) {
     HotSpotResolvedJavaType::set_isArrayClass(obj, true);