changeset 17247:eed077c367d3

improved performance of NodeClass initialization by improving the way information is derived from super NodeClasses
author Doug Simon <doug.simon@oracle.com>
date Mon, 29 Sep 2014 13:59:41 +0200
parents 44c5817156a9
children 03826360967b
files graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/FieldIntrospection.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/Fields.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/InputEdges.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/SuccessorEdges.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java
diffstat 8 files changed, 135 insertions(+), 106 deletions(-) [+]
line wrap: on
line diff
--- 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);
--- 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<FieldInfo> 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.
      *
--- 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<? extends FieldInfo> fields) {
-        super(fields);
+    public Edges(Type type, int directCount, ArrayList<? extends FieldInfo> edges) {
+        super(edges);
         this.type = type;
         this.directCount = directCount;
     }
 
+    public static void translateInto(Edges edges, ArrayList<EdgeInfo> 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);
     }
--- 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<InputFieldInfo> fields) {
-        super(Inputs, directCount, fields);
+    public InputEdges(int directCount, ArrayList<InputInfo> 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<InputInfo> 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)));
         }
     }
 
--- 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 extends Annotation> T getAnnotation(AnnotatedElement e, Class<T> 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<? extends Node> originalNodeClass = (Class<? extends Node>) 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<InputType> 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 @@
      *
      * <pre>
      *     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<? extends Node> 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<InputFieldInfo> inputs = new ArrayList<>();
-        public final ArrayList<FieldInfo> successors = new ArrayList<>();
+        public final ArrayList<InputInfo> inputs = new ArrayList<>();
+        public final ArrayList<EdgeInfo> 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));
             }
         }
     }
--- 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<FieldInfo> fields) {
-        super(Successors, directCount, fields);
+    public SuccessorEdges(int directCount, ArrayList<EdgeInfo> edges) {
+        super(Successors, directCount, edges);
     }
 
     @Override
--- 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<OperandFlag> getFlags(Field field) {
             EnumSet<OperandFlag> result = EnumSet.noneOf(OperandFlag.class);
             if (field.isAnnotationPresent(CompositeValue.Component.class)) {
--- 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();