# HG changeset patch # User Doug Simon # Date 1409218922 -7200 # Node ID 4a6d852dbb68136f41d52b5841088d46d3ccc3c4 # Parent e98ccb0c3c05cbab9bdf7a49aaba76945e26c194 added support to get the generated Node class represented by a NodeClass instance diff -r e98ccb0c3c05 -r 4a6d852dbb68 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java --- 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(); } } } diff -r e98ccb0c3c05 -r 4a6d852dbb68 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- 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 genKey = (Class) gen.value(); - value = (NodeClass) allClasses.get(genKey); + Class originalNodeClass = (Class) gen.value(); + value = (NodeClass) allClasses.get(originalNodeClass); assert value != null; + if (value.genClass == null) { + value.genClass = (Class) c; + } else { + assert value.genClass == c; + } } else { value = new NodeClass(key); } @@ -102,6 +108,13 @@ private final EnumSet 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 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 getGenClass() { + if (USE_GENERATED_NODES) { + if (genClass == null) { + if (!isAbstract(getClazz().getModifiers())) { + String genClassName = getClazz().getName().replace('$', '_') + "Gen"; + try { + genClass = (Class) 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) {