# HG changeset patch # User Doug Simon # Date 1411991981 -7200 # Node ID eed077c367d3af9e8feb93f6aa2982d61c72a396 # Parent 44c5817156a9b737a99b775f432258890d812e13 improved performance of NodeClass initialization by improving the way information is derived from super NodeClasses diff -r 44c5817156a9 -r eed077c367d3 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/FieldIntrospection.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/FieldIntrospection.java Mon Sep 29 13:58:19 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/FieldIntrospection.java Mon Sep 29 13:59:41 2014 +0200 @@ -112,7 +112,7 @@ /** * Scans the fields in a class hierarchy. */ - public void scan(Class clazz) { + public void scan(Class clazz, boolean includeSuperclasses) { Class currentClazz = clazz; do { for (Field field : currentClazz.getDeclaredFields()) { @@ -123,7 +123,7 @@ scanField(field, offset); } currentClazz = currentClazz.getSuperclass(); - } while (currentClazz.getSuperclass() != Object.class); + } while (includeSuperclasses && currentClazz.getSuperclass() != Object.class); } protected abstract void scanField(Field field, long offset); diff -r 44c5817156a9 -r eed077c367d3 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/Fields.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/Fields.java Mon Sep 29 13:58:19 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/Fields.java Mon Sep 29 13:59:41 2014 +0200 @@ -71,6 +71,12 @@ return offsets.length; } + public static void translateInto(Fields fields, ArrayList infos) { + for (int index = 0; index < fields.getCount(); index++) { + infos.add(new FieldInfo(fields.offsets[index], fields.names[index], fields.types[index])); + } + } + /** * Gets the value of a field for a given object. * diff -r 44c5817156a9 -r eed077c367d3 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java Mon Sep 29 13:58:19 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java Mon Sep 29 13:59:41 2014 +0200 @@ -28,8 +28,9 @@ import java.util.*; +import com.oracle.graal.compiler.common.FieldIntrospection.FieldInfo; import com.oracle.graal.compiler.common.*; -import com.oracle.graal.compiler.common.FieldIntrospection.*; +import com.oracle.graal.graph.NodeClass.EdgeInfo; /** * Describes {@link Node} fields representing the set of inputs for the node or the set of the @@ -48,12 +49,18 @@ private final int directCount; private final Type type; - public Edges(Type type, int directCount, ArrayList fields) { - super(fields); + public Edges(Type type, int directCount, ArrayList edges) { + super(edges); this.type = type; this.directCount = directCount; } + public static void translateInto(Edges edges, ArrayList infos) { + for (int index = 0; index < edges.getCount(); index++) { + infos.add(new EdgeInfo(edges.offsets[index], edges.getName(index), edges.getType(index))); + } + } + private static Node getNode(Node node, long offset) { return (Node) unsafe.getObject(node, offset); } diff -r 44c5817156a9 -r eed077c367d3 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/InputEdges.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/InputEdges.java Mon Sep 29 13:58:19 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/InputEdges.java Mon Sep 29 13:59:41 2014 +0200 @@ -26,7 +26,7 @@ import java.util.*; -import com.oracle.graal.graph.NodeClass.InputFieldInfo; +import com.oracle.graal.graph.NodeClass.InputInfo; import com.oracle.graal.nodeinfo.*; public final class InputEdges extends Edges { @@ -34,14 +34,20 @@ private final InputType[] inputTypes; private final boolean[] isOptional; - public InputEdges(int directCount, ArrayList fields) { - super(Inputs, directCount, fields); + public InputEdges(int directCount, ArrayList edges) { + super(Inputs, directCount, edges); - this.inputTypes = new InputType[fields.size()]; - this.isOptional = new boolean[fields.size()]; - for (int i = 0; i < fields.size(); i++) { - this.inputTypes[i] = fields.get(i).inputType; - this.isOptional[i] = fields.get(i).optional; + this.inputTypes = new InputType[edges.size()]; + this.isOptional = new boolean[edges.size()]; + for (int i = 0; i < edges.size(); i++) { + this.inputTypes[i] = edges.get(i).inputType; + this.isOptional[i] = edges.get(i).optional; + } + } + + public static void translateInto(InputEdges inputs, ArrayList infos) { + for (int index = 0; index < inputs.getCount(); index++) { + infos.add(new InputInfo(inputs.offsets[index], inputs.getName(index), inputs.getType(index), inputs.inputTypes[index], inputs.isOptional(index))); } } diff -r 44c5817156a9 -r eed077c367d3 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 Mon Sep 29 13:58:19 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Mon Sep 29 13:59:41 2014 +0200 @@ -22,10 +22,14 @@ */ package com.oracle.graal.graph; +import static com.oracle.graal.compiler.common.Fields.*; +import static com.oracle.graal.graph.Edges.*; +import static com.oracle.graal.graph.InputEdges.*; import static com.oracle.graal.graph.Node.*; import static com.oracle.graal.graph.util.CollectionsAccess.*; import static java.lang.reflect.Modifier.*; +import java.lang.annotation.*; import java.lang.reflect.*; import java.util.*; @@ -54,12 +58,20 @@ // Timers for creation of a NodeClass instance private static final DebugTimer Init = Debug.timer("NodeClass.Init"); private static final DebugTimer Init_FieldScanning = Debug.timer("NodeClass.Init.FieldScanning"); + private static final DebugTimer Init_FieldScanningInner = Debug.timer("NodeClass.Init.FieldScanning.Inner"); + private static final DebugTimer Init_AnnotationParsing = Debug.timer("NodeClass.Init.AnnotationParsing"); private static final DebugTimer Init_Edges = Debug.timer("NodeClass.Init.Edges"); private static final DebugTimer Init_Data = Debug.timer("NodeClass.Init.Data"); private static final DebugTimer Init_Naming = Debug.timer("NodeClass.Init.Naming"); private static final DebugTimer Init_AllowedUsages = Debug.timer("NodeClass.Init.AllowedUsages"); private static final DebugTimer Init_IterableIds = Debug.timer("NodeClass.Init.IterableIds"); + private static T getAnnotation(AnnotatedElement e, Class annotationClass) { + try (TimerCloseable s = Init_AnnotationParsing.start()) { + return e.getAnnotation(annotationClass); + } + } + /** * Gets the {@link NodeClass} associated with a given {@link Class}. */ @@ -77,7 +89,7 @@ try (TimerCloseable t = Init.start()) { value = (NodeClass) allClasses.get(key); if (value == null) { - GeneratedNode gen = c.getAnnotation(GeneratedNode.class); + GeneratedNode gen = getAnnotation(c, GeneratedNode.class); if (gen != null) { Class originalNodeClass = (Class) gen.value(); value = (NodeClass) allClasses.get(originalNodeClass); @@ -89,11 +101,12 @@ } } else { Class superclass = c.getSuperclass(); + NodeClass superNodeClass = null; if (superclass != NODE_CLASS) { // Ensure NodeClass for superclass exists - get(superclass); + superNodeClass = get(superclass); } - value = new NodeClass(key); + value = new NodeClass(key, superNodeClass); } Object old = allClasses.putIfAbsent(key, value); assert old == null : old + " " + key; @@ -110,8 +123,9 @@ private static int nextIterableId = 0; - private final Edges inputs; - private final Edges successors; + private final InputEdges inputs; + private final SuccessorEdges successors; + private final NodeClass superNodeClass; private final boolean canGVN; private final int startGVNNumber; @@ -142,12 +156,13 @@ private final boolean isSimplifiable; private final boolean isLeafNode; - public NodeClass(Class clazz) { - this(clazz, new DefaultCalcOffset(), null, 0); + public NodeClass(Class clazz, NodeClass superNodeClass) { + this(clazz, superNodeClass, new DefaultCalcOffset(), null, 0); } - public NodeClass(Class clazz, CalcOffset calcOffset, int[] presetIterableIds, int presetIterableId) { + public NodeClass(Class clazz, NodeClass superNodeClass, CalcOffset calcOffset, int[] presetIterableIds, int presetIterableId) { super(clazz); + this.superNodeClass = superNodeClass; assert NODE_CLASS.isAssignableFrom(clazz); this.isCanonicalizable = Canonicalizable.class.isAssignableFrom(clazz); @@ -157,9 +172,9 @@ this.isSimplifiable = Simplifiable.class.isAssignableFrom(clazz); - FieldScanner fs = new FieldScanner(calcOffset); + FieldScanner fs = new FieldScanner(calcOffset, superNodeClass); try (TimerCloseable t = Init_FieldScanning.start()) { - fs.scan(clazz); + fs.scan(clazz, false); } try (TimerCloseable t1 = Init_Edges.start()) { @@ -175,14 +190,13 @@ canGVN = Node.ValueNumberable.class.isAssignableFrom(clazz); startGVNNumber = clazz.hashCode(); - String newNameTemplate = null; - String newShortName; + NodeInfo info = getAnnotation(clazz, NodeInfo.class); try (TimerCloseable t1 = Init_Naming.start()) { - newShortName = clazz.getSimpleName(); + String newNameTemplate = null; + String newShortName = clazz.getSimpleName(); if (newShortName.endsWith("Node") && !newShortName.equals("StartNode") && !newShortName.equals("EndNode")) { newShortName = newShortName.substring(0, newShortName.length() - 4); } - NodeInfo info = clazz.getAnnotation(NodeInfo.class); assert info != null : "missing " + NodeInfo.class.getSimpleName() + " annotation on " + clazz; if (!info.shortName().isEmpty()) { newShortName = info.shortName(); @@ -190,23 +204,14 @@ if (!info.nameTemplate().isEmpty()) { newNameTemplate = info.nameTemplate(); } + this.nameTemplate = newNameTemplate == null ? newShortName : newNameTemplate; + this.shortName = newShortName; } - EnumSet newAllowedUsageTypes = EnumSet.noneOf(InputType.class); try (TimerCloseable t1 = Init_AllowedUsages.start()) { - Class current = clazz; - do { - NodeInfo currentInfo = current.getAnnotation(NodeInfo.class); - if (currentInfo != null) { - if (currentInfo.allowedUsageTypes().length > 0) { - newAllowedUsageTypes.addAll(Arrays.asList(currentInfo.allowedUsageTypes())); - } - } - current = current.getSuperclass(); - } while (current != Node.class); + allowedUsageTypes = superNodeClass == null ? EnumSet.noneOf(InputType.class) : superNodeClass.allowedUsageTypes.clone(); + allowedUsageTypes.addAll(Arrays.asList(info.allowedUsageTypes())); } - this.nameTemplate = newNameTemplate == null ? newShortName : newNameTemplate; - this.allowedUsageTypes = newAllowedUsageTypes; - this.shortName = newShortName; + if (presetIterableIds != null) { this.iterableIds = presetIterableIds; this.iterableId = presetIterableId; @@ -215,15 +220,12 @@ try (TimerCloseable t1 = Init_IterableIds.start()) { this.iterableId = nextIterableId++; - Class superclass = clazz.getSuperclass(); - while (superclass != NODE_CLASS) { - if (IterableNodeType.class.isAssignableFrom(superclass)) { - NodeClass superNodeClass = NodeClass.get(superclass); - assert !containsId(this.iterableId, superNodeClass.iterableIds); - superNodeClass.iterableIds = Arrays.copyOf(superNodeClass.iterableIds, superNodeClass.iterableIds.length + 1); - superNodeClass.iterableIds[superNodeClass.iterableIds.length - 1] = this.iterableId; - } - superclass = superclass.getSuperclass(); + NodeClass snc = superNodeClass; + while (snc != null && IterableNodeType.class.isAssignableFrom(snc.getClazz())) { + assert !containsId(this.iterableId, snc.iterableIds); + snc.iterableIds = Arrays.copyOf(snc.iterableIds, snc.iterableIds.length + 1); + snc.iterableIds[snc.iterableIds.length - 1] = this.iterableId; + snc = snc.superNodeClass; } this.iterableIds = new int[]{iterableId}; @@ -275,7 +277,7 @@ * *
      *     if (node.getNodeClass().is(BeginNode.class)) { ... }
-     * 
+     *
      *     // Due to generated Node classes, the test below
      *     // is *not* the same as the test above:
      *     if (node.getClass() == BeginNode.class) { ... }
@@ -284,7 +286,7 @@
      * @param nodeClass a {@linkplain GeneratedNode non-generated} {@link Node} class
      */
     public boolean is(Class nodeClass) {
-        assert nodeClass.getAnnotation(GeneratedNode.class) == null : "cannot test NodeClas against generated " + nodeClass;
+        assert getAnnotation(nodeClass, GeneratedNode.class) == null : "cannot test NodeClas against generated " + nodeClass;
         return nodeClass == getClazz();
     }
 
@@ -330,9 +332,9 @@
     /**
      * Describes a field representing an input or successor edge in a node.
      */
-    protected static class EdgeFieldInfo extends FieldInfo {
+    protected static class EdgeInfo extends FieldInfo {
 
-        public EdgeFieldInfo(long offset, String name, Class type) {
+        public EdgeInfo(long offset, String name, Class type) {
             super(offset, name, type);
         }
 
@@ -357,11 +359,11 @@
     /**
      * Describes a field representing an {@linkplain Type#Inputs input} edge in a node.
      */
-    protected static class InputFieldInfo extends EdgeFieldInfo {
+    protected static class InputInfo extends EdgeInfo {
         final InputType inputType;
         final boolean optional;
 
-        public InputFieldInfo(long offset, String name, Class type, InputType inputType, boolean optional) {
+        public InputInfo(long offset, String name, Class type, InputType inputType, boolean optional) {
             super(offset, name, type);
             this.inputType = inputType;
             this.optional = optional;
@@ -375,55 +377,69 @@
 
     protected static class FieldScanner extends BaseFieldScanner {
 
-        public final ArrayList inputs = new ArrayList<>();
-        public final ArrayList successors = new ArrayList<>();
+        public final ArrayList inputs = new ArrayList<>();
+        public final ArrayList successors = new ArrayList<>();
         int directInputs;
         int directSuccessors;
 
-        protected FieldScanner(CalcOffset calc) {
+        protected FieldScanner(CalcOffset calc, NodeClass superNodeClass) {
             super(calc);
+            if (superNodeClass != null) {
+                translateInto(superNodeClass.inputs, inputs);
+                translateInto(superNodeClass.successors, successors);
+                translateInto(superNodeClass.data, data);
+                directInputs = superNodeClass.inputs.getDirectCount();
+                directSuccessors = superNodeClass.successors.getDirectCount();
+            }
         }
 
         @Override
         protected void scanField(Field field, long offset) {
-            Class type = field.getType();
-            if (field.isAnnotationPresent(Node.Input.class) || field.isAnnotationPresent(Node.OptionalInput.class)) {
-                assert !field.isAnnotationPresent(Node.Successor.class) : "field cannot be both input and successor";
-                assert field.isAnnotationPresent(Node.Input.class) ^ field.isAnnotationPresent(Node.OptionalInput.class) : "inputs can either be optional or non-optional";
-                if (INPUT_LIST_CLASS.isAssignableFrom(type)) {
-                    // NodeInputList fields should not be final since they are
-                    // written (via Unsafe) in clearInputs()
-                    GraalInternalError.guarantee(!Modifier.isFinal(field.getModifiers()), "NodeInputList input field %s should not be final", field);
-                    GraalInternalError.guarantee(!Modifier.isPublic(field.getModifiers()), "NodeInputList input field %s should not be public", field);
-                } else {
-                    GraalInternalError.guarantee(NODE_CLASS.isAssignableFrom(type) || type.isInterface(), "invalid input type: %s", type);
-                    GraalInternalError.guarantee(!Modifier.isFinal(field.getModifiers()), "Node input field %s should not be final", field);
-                    directInputs++;
-                }
-                InputType inputType;
-                if (field.isAnnotationPresent(Node.Input.class)) {
-                    inputType = field.getAnnotation(Node.Input.class).value();
+            Input inputAnnotation = getAnnotation(field, Node.Input.class);
+            OptionalInput optionalInputAnnotation = getAnnotation(field, Node.OptionalInput.class);
+            Successor successorAnnotation = getAnnotation(field, Successor.class);
+            try (TimerCloseable s = Init_FieldScanningInner.start()) {
+                Class type = field.getType();
+                int modifiers = field.getModifiers();
+
+                if (inputAnnotation != null || optionalInputAnnotation != null) {
+                    assert successorAnnotation == null : "field cannot be both input and successor";
+                    if (INPUT_LIST_CLASS.isAssignableFrom(type)) {
+                        // NodeInputList fields should not be final since they are
+                        // written (via Unsafe) in clearInputs()
+                        GraalInternalError.guarantee(!Modifier.isFinal(modifiers), "NodeInputList input field %s should not be final", field);
+                        GraalInternalError.guarantee(!Modifier.isPublic(modifiers), "NodeInputList input field %s should not be public", field);
+                    } else {
+                        GraalInternalError.guarantee(NODE_CLASS.isAssignableFrom(type) || type.isInterface(), "invalid input type: %s", type);
+                        GraalInternalError.guarantee(!Modifier.isFinal(modifiers), "Node input field %s should not be final", field);
+                        directInputs++;
+                    }
+                    InputType inputType;
+                    if (inputAnnotation != null) {
+                        assert optionalInputAnnotation == null : "inputs can either be optional or non-optional";
+                        inputType = inputAnnotation.value();
+                    } else {
+                        inputType = optionalInputAnnotation.value();
+                    }
+                    inputs.add(new InputInfo(offset, field.getName(), type, inputType, field.isAnnotationPresent(Node.OptionalInput.class)));
+                } else if (successorAnnotation != null) {
+                    if (SUCCESSOR_LIST_CLASS.isAssignableFrom(type)) {
+                        // NodeSuccessorList fields should not be final since they are
+                        // written (via Unsafe) in clearSuccessors()
+                        GraalInternalError.guarantee(!Modifier.isFinal(modifiers), "NodeSuccessorList successor field % should not be final", field);
+                        GraalInternalError.guarantee(!Modifier.isPublic(modifiers), "NodeSuccessorList successor field %s should not be public", field);
+                    } else {
+                        GraalInternalError.guarantee(NODE_CLASS.isAssignableFrom(type), "invalid successor type: %s", type);
+                        GraalInternalError.guarantee(!Modifier.isFinal(modifiers), "Node successor field %s should not be final", field);
+                        directSuccessors++;
+                    }
+                    successors.add(new EdgeInfo(offset, field.getName(), type));
                 } else {
-                    inputType = field.getAnnotation(Node.OptionalInput.class).value();
+                    GraalInternalError.guarantee(!NODE_CLASS.isAssignableFrom(type) || field.getName().equals("Null"), "suspicious node field: %s", field);
+                    GraalInternalError.guarantee(!INPUT_LIST_CLASS.isAssignableFrom(type), "suspicious node input list field: %s", field);
+                    GraalInternalError.guarantee(!SUCCESSOR_LIST_CLASS.isAssignableFrom(type), "suspicious node successor list field: %s", field);
+                    data.add(new FieldInfo(offset, field.getName(), type));
                 }
-                inputs.add(new InputFieldInfo(offset, field.getName(), type, inputType, field.isAnnotationPresent(Node.OptionalInput.class)));
-            } else if (field.isAnnotationPresent(Node.Successor.class)) {
-                if (SUCCESSOR_LIST_CLASS.isAssignableFrom(type)) {
-                    // NodeSuccessorList fields should not be final since they are
-                    // written (via Unsafe) in clearSuccessors()
-                    GraalInternalError.guarantee(!Modifier.isFinal(field.getModifiers()), "NodeSuccessorList successor field % should not be final", field);
-                    GraalInternalError.guarantee(!Modifier.isPublic(field.getModifiers()), "NodeSuccessorList successor field %s should not be public", field);
-                } else {
-                    GraalInternalError.guarantee(NODE_CLASS.isAssignableFrom(type), "invalid successor type: %s", type);
-                    GraalInternalError.guarantee(!Modifier.isFinal(field.getModifiers()), "Node successor field %s should not be final", field);
-                    directSuccessors++;
-                }
-                successors.add(new FieldInfo(offset, field.getName(), type));
-            } else {
-                GraalInternalError.guarantee(!NODE_CLASS.isAssignableFrom(type) || field.getName().equals("Null"), "suspicious node field: %s", field);
-                GraalInternalError.guarantee(!INPUT_LIST_CLASS.isAssignableFrom(type), "suspicious node input list field: %s", field);
-                GraalInternalError.guarantee(!SUCCESSOR_LIST_CLASS.isAssignableFrom(type), "suspicious node successor list field: %s", field);
-                data.add(new FieldInfo(offset, field.getName(), type));
             }
         }
     }
diff -r 44c5817156a9 -r eed077c367d3 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/SuccessorEdges.java
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/SuccessorEdges.java	Mon Sep 29 13:58:19 2014 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/SuccessorEdges.java	Mon Sep 29 13:59:41 2014 +0200
@@ -26,12 +26,12 @@
 
 import java.util.*;
 
-import com.oracle.graal.compiler.common.FieldIntrospection.FieldInfo;
+import com.oracle.graal.graph.NodeClass.EdgeInfo;
 
 public final class SuccessorEdges extends Edges {
 
-    public SuccessorEdges(int directCount, ArrayList fields) {
-        super(Successors, directCount, fields);
+    public SuccessorEdges(int directCount, ArrayList edges) {
+        super(Successors, directCount, edges);
     }
 
     @Override
diff -r 44c5817156a9 -r eed077c367d3 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java	Mon Sep 29 13:58:19 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java	Mon Sep 29 13:59:41 2014 +0200
@@ -65,7 +65,7 @@
         super(clazz);
 
         ValueFieldScanner vfs = new ValueFieldScanner(calcOffset);
-        vfs.scan(clazz);
+        vfs.scan(clazz, true);
 
         values = new Values(vfs.valueAnnotations.get(CompositeValue.Component.class));
         data = new Fields(vfs.data);
@@ -79,11 +79,6 @@
         }
 
         @Override
-        public void scan(Class clazz) {
-            super.scan(clazz);
-        }
-
-        @Override
         protected EnumSet getFlags(Field field) {
             EnumSet result = EnumSet.noneOf(OperandFlag.class);
             if (field.isAnnotationPresent(CompositeValue.Component.class)) {
diff -r 44c5817156a9 -r eed077c367d3 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java	Mon Sep 29 13:58:19 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java	Mon Sep 29 13:59:41 2014 +0200
@@ -128,14 +128,13 @@
             return result;
         }
 
-        @Override
         public void scan(Class clazz) {
             if (clazz.getAnnotation(Opcode.class) != null) {
                 opcodeConstant = clazz.getAnnotation(Opcode.class).value();
             }
             opcodeField = null;
 
-            super.scan(clazz);
+            super.scan(clazz, true);
 
             if (opcodeConstant == null && opcodeField == null) {
                 opcodeConstant = clazz.getSimpleName();