changeset 16991:4a6d852dbb68

added support to get the generated Node class represented by a NodeClass instance
author Doug Simon <doug.simon@oracle.com>
date Thu, 28 Aug 2014 11:42:02 +0200
parents e98ccb0c3c05
children 5a1d764f6afc
files graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java
diffstat 2 files changed, 40 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java	Thu Aug 28 08:54:10 2014 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java	Thu Aug 28 11:42:02 2014 +0200
@@ -189,11 +189,7 @@
                     throw new AssertionError(String.format("Node subclass %s requires %s annotation", c.getName(), NodeClass.class.getSimpleName()));
                 }
                 if (!Modifier.isAbstract(c.getModifiers())) {
-                    try {
-                        Class.forName(c.getName().replace('$', '_') + "Gen");
-                    } catch (ClassNotFoundException e) {
-                        throw new AssertionError(String.format("Missing generated Node class %s", c.getName() + "Gen"));
-                    }
+                    NodeClass.get(c).getGenClass();
                 }
             }
         }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Thu Aug 28 08:54:10 2014 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Thu Aug 28 11:42:02 2014 +0200
@@ -25,6 +25,7 @@
 import static com.oracle.graal.graph.Graph.*;
 import static com.oracle.graal.graph.Node.*;
 import static com.oracle.graal.graph.util.CollectionsAccess.*;
+import static java.lang.reflect.Modifier.*;
 
 import java.lang.reflect.*;
 import java.util.*;
@@ -67,9 +68,14 @@
                 if (value == null) {
                     GeneratedNode gen = c.getAnnotation(GeneratedNode.class);
                     if (gen != null) {
-                        Class<? extends Node> genKey = (Class<? extends Node>) gen.value();
-                        value = (NodeClass) allClasses.get(genKey);
+                        Class<? extends Node> originalNodeClass = (Class<? extends Node>) gen.value();
+                        value = (NodeClass) allClasses.get(originalNodeClass);
                         assert value != null;
+                        if (value.genClass == null) {
+                            value.genClass = (Class<? extends Node>) c;
+                        } else {
+                            assert value.genClass == c;
+                        }
                     } else {
                         value = new NodeClass(key);
                     }
@@ -102,6 +108,13 @@
     private final EnumSet<InputType> allowedUsageTypes;
     private int[] iterableIds;
 
+    /**
+     * The {@linkplain GeneratedNode generated} node class denoted by this object. This value is
+     * lazily initialized to avoid class initialization circularity issues. A sentinel value of
+     * {@code Node.class} is used to denote absence of a generated class.
+     */
+    private Class<? extends Node> genClass;
+
     private static final DebugMetric ITERABLE_NODE_TYPES = Debug.metric("IterableNodeTypes");
     private final DebugMetric nodeIterableCount;
 
@@ -223,6 +236,30 @@
         nodeIterableCount = Debug.metric("NodeIterable_%s", shortName);
     }
 
+    /**
+     * Gets the {@linkplain GeneratedNode generated} node class (if any) described by the object.
+     */
+    @SuppressWarnings("unchecked")
+    public Class<? extends Node> getGenClass() {
+        if (USE_GENERATED_NODES) {
+            if (genClass == null) {
+                if (!isAbstract(getClazz().getModifiers())) {
+                    String genClassName = getClazz().getName().replace('$', '_') + "Gen";
+                    try {
+                        genClass = (Class<? extends Node>) Class.forName(genClassName);
+                    } catch (ClassNotFoundException e) {
+                        throw new GraalInternalError("Could not find generated class " + genClassName + " for " + getClazz());
+                    }
+                } else {
+                    // Sentinel value denoting no generated class
+                    genClass = Node.class;
+                }
+            }
+            return genClass.equals(Node.class) ? null : genClass;
+        }
+        return null;
+    }
+
     private static boolean containsId(int iterableId, int[] iterableIds) {
         for (int i : iterableIds) {
             if (i == iterableId) {