changeset 8164:25fd899b979f

Move reusable parts of LIRInstructionClass into base class.
author Roland Schatz <roland.schatz@oracle.com>
date Thu, 07 Mar 2013 15:16:18 +0100
parents d9d06daac640
children a85ef330ffe7
files graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java
diffstat 2 files changed, 224 insertions(+), 165 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java	Thu Mar 07 15:16:12 2013 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java	Thu Mar 07 15:16:18 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,12 +22,8 @@
  */
 package com.oracle.graal.lir;
 
-import static com.oracle.graal.api.code.ValueUtil.*;
-
-import java.lang.annotation.*;
 import java.lang.reflect.*;
 import java.util.*;
-import java.util.Map.Entry;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -37,7 +33,7 @@
 import com.oracle.graal.lir.LIRInstruction.StateProcedure;
 import com.oracle.graal.lir.LIRInstruction.ValueProcedure;
 
-public class LIRInstructionClass extends FieldIntrospection {
+public class LIRInstructionClass extends LIRIntrospection {
 
     public static final LIRInstructionClass get(Class<? extends LIRInstruction> c) {
         LIRInstructionClass clazz = (LIRInstructionClass) allClasses.get(c);
@@ -56,11 +52,8 @@
         }
     }
 
-    private static final Class<?> INSTRUCTION_CLASS = LIRInstruction.class;
-    private static final Class<?> VALUE_CLASS = Value.class;
-    private static final Class<?> CONSTANT_CLASS = Constant.class;
-    private static final Class<?> VALUE_ARRAY_CLASS = Value[].class;
-    private static final Class<?> STATE_CLASS = LIRFrameState.class;
+    private static final Class<LIRInstruction> INSTRUCTION_CLASS = LIRInstruction.class;
+    private static final Class<LIRFrameState> STATE_CLASS = LIRFrameState.class;
 
     private final int directUseCount;
     private final long[] useOffsets;
@@ -81,11 +74,11 @@
     private long opcodeOffset;
 
     @SuppressWarnings("unchecked")
-    public LIRInstructionClass(Class<?> clazz) {
+    public LIRInstructionClass(Class<? extends LIRInstruction> clazz) {
         super(clazz);
         assert INSTRUCTION_CLASS.isAssignableFrom(clazz);
 
-        FieldScanner scanner = new FieldScanner(new DefaultCalcOffset());
+        InstructionFieldScanner scanner = new InstructionFieldScanner(new DefaultCalcOffset());
         scanner.scan(clazz);
 
         OperandModeAnnotation mode = scanner.valueAnnotations.get(LIRInstruction.Use.class);
@@ -120,7 +113,7 @@
 
     @Override
     protected void rescanFieldOffsets(CalcOffset calc) {
-        FieldScanner scanner = new FieldScanner(calc);
+        InstructionFieldScanner scanner = new InstructionFieldScanner(calc);
         scanner.scan(clazz);
 
         OperandModeAnnotation mode = scanner.valueAnnotations.get(LIRInstruction.Use.class);
@@ -144,44 +137,22 @@
         opcodeOffset = scanner.opcodeOffset;
     }
 
-    private static class OperandModeAnnotation {
-
-        public final ArrayList<Long> scalarOffsets = new ArrayList<>();
-        public final ArrayList<Long> arrayOffsets = new ArrayList<>();
-        public final Map<Long, EnumSet<OperandFlag>> flags = new HashMap<>();
-    }
-
-    protected static class FieldScanner extends BaseFieldScanner {
-
-        public final Map<Class<? extends Annotation>, OperandModeAnnotation> valueAnnotations;
-        public final ArrayList<Long> stateOffsets = new ArrayList<>();
+    private static class InstructionFieldScanner extends FieldScanner {
 
         private String opcodeConstant;
         private long opcodeOffset;
 
-        public FieldScanner(CalcOffset calc) {
+        public InstructionFieldScanner(CalcOffset calc) {
             super(calc);
 
-            valueAnnotations = new HashMap<>();
-            valueAnnotations.put(LIRInstruction.Use.class, new OperandModeAnnotation()); // LIRInstruction.Use.class));
-            valueAnnotations.put(LIRInstruction.Alive.class, new OperandModeAnnotation()); // LIRInstruction.Alive.class));
-            valueAnnotations.put(LIRInstruction.Temp.class, new OperandModeAnnotation()); // LIRInstruction.Temp.class));
-            valueAnnotations.put(LIRInstruction.Def.class, new OperandModeAnnotation()); // LIRInstruction.Def.class));
+            valueAnnotations.put(LIRInstruction.Use.class, new OperandModeAnnotation());
+            valueAnnotations.put(LIRInstruction.Alive.class, new OperandModeAnnotation());
+            valueAnnotations.put(LIRInstruction.Temp.class, new OperandModeAnnotation());
+            valueAnnotations.put(LIRInstruction.Def.class, new OperandModeAnnotation());
         }
 
-        private OperandModeAnnotation getOperandModeAnnotation(Field field) {
-            OperandModeAnnotation result = null;
-            for (Entry<Class<? extends Annotation>, OperandModeAnnotation> entry : valueAnnotations.entrySet()) {
-                Annotation annotation = field.getAnnotation(entry.getKey());
-                if (annotation != null) {
-                    assert result == null : "Field has two operand mode annotations: " + field;
-                    result = entry.getValue();
-                }
-            }
-            return result;
-        }
-
-        private static EnumSet<OperandFlag> getFlags(Field field) {
+        @Override
+        protected EnumSet<OperandFlag> getFlags(Field field) {
             EnumSet<OperandFlag> result = EnumSet.noneOf(OperandFlag.class);
             // Unfortunately, annotations cannot have class hierarchies or implement interfaces, so
             // we have to duplicate the code for every operand mode.
@@ -220,25 +191,12 @@
 
         @Override
         protected void scanField(Field field, Class<?> type, long offset) {
-            if (VALUE_CLASS.isAssignableFrom(type) && type != CONSTANT_CLASS) {
-                assert !Modifier.isFinal(field.getModifiers()) : "Value field must not be declared final because it is modified by register allocator: " + field;
-                OperandModeAnnotation annotation = getOperandModeAnnotation(field);
-                assert annotation != null : "Field must have operand mode annotation: " + field;
-                annotation.scalarOffsets.add(offset);
-                annotation.flags.put(offset, getFlags(field));
-            } else if (VALUE_ARRAY_CLASS.isAssignableFrom(type)) {
-                OperandModeAnnotation annotation = getOperandModeAnnotation(field);
-                assert annotation != null : "Field must have operand mode annotation: " + field;
-                annotation.arrayOffsets.add(offset);
-                annotation.flags.put(offset, getFlags(field));
-            } else if (STATE_CLASS.isAssignableFrom(type)) {
+            if (STATE_CLASS.isAssignableFrom(type)) {
                 assert getOperandModeAnnotation(field) == null : "Field must not have operand mode annotation: " + field;
                 assert field.getAnnotation(LIRInstruction.State.class) != null : "Field must have state annotation: " + field;
                 stateOffsets.add(offset);
             } else {
-                assert getOperandModeAnnotation(field) == null : "Field must not have operand mode annotation: " + field;
-                assert field.getAnnotation(LIRInstruction.State.class) == null : "Field must not have state annotation: " + field;
-                dataOffsets.add(offset);
+                super.scanField(field, type, offset);
             }
 
             if (field.getAnnotation(LIRInstruction.Opcode.class) != null) {
@@ -334,39 +292,6 @@
         }
     }
 
-    private static void forEach(LIRInstruction obj, int directCount, long[] offsets, OperandMode mode, EnumSet<OperandFlag>[] flags, ValueProcedure proc) {
-        for (int i = 0; i < offsets.length; i++) {
-            assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(flags[i]);
-
-            if (i < directCount) {
-                Value value = getValue(obj, offsets[i]);
-                if (isAddress(value)) {
-                    doAddress(asAddress(value), mode, flags[i], proc);
-                } else {
-                    setValue(obj, offsets[i], proc.doValue(value, mode, flags[i]));
-                }
-            } else {
-                Value[] values = getValueArray(obj, offsets[i]);
-                for (int j = 0; j < values.length; j++) {
-                    Value value = values[j];
-                    if (isAddress(value)) {
-                        doAddress(asAddress(value), mode, flags[i], proc);
-                    } else {
-                        values[j] = proc.doValue(value, mode, flags[i]);
-                    }
-                }
-            }
-        }
-    }
-
-    private static void doAddress(Address address, OperandMode mode, EnumSet<OperandFlag> flags, ValueProcedure proc) {
-        assert flags.contains(OperandFlag.ADDR);
-        Value[] components = address.components();
-        for (int i = 0; i < components.length; i++) {
-            components[i] = proc.doValue(components[i], mode, LIRInstruction.ADDRESS_FLAGS);
-        }
-    }
-
     public final Value forEachRegisterHint(LIRInstruction obj, OperandMode mode, ValueProcedure proc) {
         int hintDirectCount = 0;
         long[] hintOffsets = null;
@@ -401,18 +326,6 @@
         return null;
     }
 
-    private static Value getValue(LIRInstruction obj, long offset) {
-        return (Value) unsafe.getObject(obj, offset);
-    }
-
-    private static void setValue(LIRInstruction obj, long offset, Value value) {
-        unsafe.putObject(obj, offset, value);
-    }
-
-    private static Value[] getValueArray(LIRInstruction obj, long offset) {
-        return (Value[]) unsafe.getObject(obj, offset);
-    }
-
     private static LIRFrameState getState(LIRInstruction obj, long offset) {
         return (LIRFrameState) unsafe.getObject(obj, offset);
     }
@@ -447,65 +360,4 @@
 
         return result.toString();
     }
-
-    private void appendValues(StringBuilder result, LIRInstruction obj, String start, String end, String startMultiple, String endMultiple, String[] prefix, long[]... moffsets) {
-        int total = 0;
-        for (long[] offsets : moffsets) {
-            total += offsets.length;
-        }
-        if (total == 0) {
-            return;
-        }
-
-        result.append(start);
-        if (total > 1) {
-            result.append(startMultiple);
-        }
-        String sep = "";
-        for (int i = 0; i < moffsets.length; i++) {
-            long[] offsets = moffsets[i];
-
-            for (int j = 0; j < offsets.length; j++) {
-                result.append(sep).append(prefix[i]);
-                long offset = offsets[j];
-                if (total > 1) {
-                    result.append(fieldNames.get(offset)).append(": ");
-                }
-                result.append(getFieldString(obj, offset));
-                sep = ", ";
-            }
-        }
-        if (total > 1) {
-            result.append(endMultiple);
-        }
-        result.append(end);
-    }
-
-    private String getFieldString(Object obj, long offset) {
-        Class<?> type = fieldTypes.get(offset);
-        if (type == int.class) {
-            return String.valueOf(unsafe.getInt(obj, offset));
-        } else if (type == long.class) {
-            return String.valueOf(unsafe.getLong(obj, offset));
-        } else if (type == boolean.class) {
-            return String.valueOf(unsafe.getBoolean(obj, offset));
-        } else if (type == float.class) {
-            return String.valueOf(unsafe.getFloat(obj, offset));
-        } else if (type == double.class) {
-            return String.valueOf(unsafe.getDouble(obj, offset));
-        } else if (!type.isPrimitive()) {
-            Object value = unsafe.getObject(obj, offset);
-            if (!type.isArray()) {
-                return String.valueOf(value);
-            } else if (type == int[].class) {
-                return Arrays.toString((int[]) value);
-            } else if (type == double[].class) {
-                return Arrays.toString((double[]) value);
-            } else if (!type.getComponentType().isPrimitive()) {
-                return Arrays.toString((Object[]) value);
-            }
-        }
-        assert false : "unhandled field type: " + type;
-        return "";
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java	Thu Mar 07 15:16:18 2013 +0100
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.lir;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.Map.Entry;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.LIRInstruction.OperandFlag;
+import com.oracle.graal.lir.LIRInstruction.OperandMode;
+import com.oracle.graal.lir.LIRInstruction.ValueProcedure;
+
+abstract class LIRIntrospection extends FieldIntrospection {
+
+    private static final Class<Value> VALUE_CLASS = Value.class;
+    private static final Class<Constant> CONSTANT_CLASS = Constant.class;
+    private static final Class<Value[]> VALUE_ARRAY_CLASS = Value[].class;
+
+    public LIRIntrospection(Class<?> clazz) {
+        super(clazz);
+    }
+
+    protected static class OperandModeAnnotation {
+
+        public final ArrayList<Long> scalarOffsets = new ArrayList<>();
+        public final ArrayList<Long> arrayOffsets = new ArrayList<>();
+        public final Map<Long, EnumSet<OperandFlag>> flags = new HashMap<>();
+    }
+
+    protected abstract static class FieldScanner extends BaseFieldScanner {
+
+        public final Map<Class<? extends Annotation>, OperandModeAnnotation> valueAnnotations;
+        public final ArrayList<Long> stateOffsets = new ArrayList<>();
+
+        public FieldScanner(CalcOffset calc) {
+            super(calc);
+
+            valueAnnotations = new HashMap<>();
+        }
+
+        protected OperandModeAnnotation getOperandModeAnnotation(Field field) {
+            OperandModeAnnotation result = null;
+            for (Entry<Class<? extends Annotation>, OperandModeAnnotation> entry : valueAnnotations.entrySet()) {
+                Annotation annotation = field.getAnnotation(entry.getKey());
+                if (annotation != null) {
+                    assert result == null : "Field has two operand mode annotations: " + field;
+                    result = entry.getValue();
+                }
+            }
+            return result;
+        }
+
+        protected abstract EnumSet<OperandFlag> getFlags(Field field);
+
+        @Override
+        protected void scanField(Field field, Class<?> type, long offset) {
+            if (VALUE_CLASS.isAssignableFrom(type) && type != CONSTANT_CLASS) {
+                assert !Modifier.isFinal(field.getModifiers()) : "Value field must not be declared final because it is modified by register allocator: " + field;
+                OperandModeAnnotation annotation = getOperandModeAnnotation(field);
+                assert annotation != null : "Field must have operand mode annotation: " + field;
+                annotation.scalarOffsets.add(offset);
+                annotation.flags.put(offset, getFlags(field));
+            } else if (VALUE_ARRAY_CLASS.isAssignableFrom(type)) {
+                OperandModeAnnotation annotation = getOperandModeAnnotation(field);
+                assert annotation != null : "Field must have operand mode annotation: " + field;
+                annotation.arrayOffsets.add(offset);
+                annotation.flags.put(offset, getFlags(field));
+            } else {
+                assert getOperandModeAnnotation(field) == null : "Field must not have operand mode annotation: " + field;
+                assert field.getAnnotation(LIRInstruction.State.class) == null : "Field must not have state annotation: " + field;
+                dataOffsets.add(offset);
+            }
+        }
+    }
+
+    protected static void forEach(Object obj, int directCount, long[] offsets, OperandMode mode, EnumSet<OperandFlag>[] flags, ValueProcedure proc) {
+        for (int i = 0; i < offsets.length; i++) {
+            assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(flags[i]);
+
+            if (i < directCount) {
+                Value value = getValue(obj, offsets[i]);
+                if (isAddress(value)) {
+                    doAddress(asAddress(value), mode, flags[i], proc);
+                } else {
+                    setValue(obj, offsets[i], proc.doValue(value, mode, flags[i]));
+                }
+            } else {
+                Value[] values = getValueArray(obj, offsets[i]);
+                for (int j = 0; j < values.length; j++) {
+                    Value value = values[j];
+                    if (isAddress(value)) {
+                        doAddress(asAddress(value), mode, flags[i], proc);
+                    } else {
+                        values[j] = proc.doValue(value, mode, flags[i]);
+                    }
+                }
+            }
+        }
+    }
+
+    private static void doAddress(Address address, OperandMode mode, EnumSet<OperandFlag> flags, ValueProcedure proc) {
+        assert flags.contains(OperandFlag.ADDR);
+        Value[] components = address.components();
+        for (int i = 0; i < components.length; i++) {
+            components[i] = proc.doValue(components[i], mode, LIRInstruction.ADDRESS_FLAGS);
+        }
+    }
+
+    protected static Value getValue(Object obj, long offset) {
+        return (Value) unsafe.getObject(obj, offset);
+    }
+
+    protected static void setValue(Object obj, long offset, Value value) {
+        unsafe.putObject(obj, offset, value);
+    }
+
+    protected static Value[] getValueArray(Object obj, long offset) {
+        return (Value[]) unsafe.getObject(obj, offset);
+    }
+
+    protected void appendValues(StringBuilder result, Object obj, String start, String end, String startMultiple, String endMultiple, String[] prefix, long[]... moffsets) {
+        int total = 0;
+        for (long[] offsets : moffsets) {
+            total += offsets.length;
+        }
+        if (total == 0) {
+            return;
+        }
+
+        result.append(start);
+        if (total > 1) {
+            result.append(startMultiple);
+        }
+        String sep = "";
+        for (int i = 0; i < moffsets.length; i++) {
+            long[] offsets = moffsets[i];
+
+            for (int j = 0; j < offsets.length; j++) {
+                result.append(sep).append(prefix[i]);
+                long offset = offsets[j];
+                if (total > 1) {
+                    result.append(fieldNames.get(offset)).append(": ");
+                }
+                result.append(getFieldString(obj, offset));
+                sep = ", ";
+            }
+        }
+        if (total > 1) {
+            result.append(endMultiple);
+        }
+        result.append(end);
+    }
+
+    protected String getFieldString(Object obj, long offset) {
+        Class<?> type = fieldTypes.get(offset);
+        if (type == int.class) {
+            return String.valueOf(unsafe.getInt(obj, offset));
+        } else if (type == long.class) {
+            return String.valueOf(unsafe.getLong(obj, offset));
+        } else if (type == boolean.class) {
+            return String.valueOf(unsafe.getBoolean(obj, offset));
+        } else if (type == float.class) {
+            return String.valueOf(unsafe.getFloat(obj, offset));
+        } else if (type == double.class) {
+            return String.valueOf(unsafe.getDouble(obj, offset));
+        } else if (!type.isPrimitive()) {
+            Object value = unsafe.getObject(obj, offset);
+            if (!type.isArray()) {
+                return String.valueOf(value);
+            } else if (type == int[].class) {
+                return Arrays.toString((int[]) value);
+            } else if (type == double[].class) {
+                return Arrays.toString((double[]) value);
+            } else if (!type.getComponentType().isPrimitive()) {
+                return Arrays.toString((Object[]) value);
+            }
+        }
+        assert false : "unhandled field type: " + type;
+        return "";
+    }
+}