# HG changeset patch # User Roland Schatz # Date 1362665778 -3600 # Node ID 25fd899b979f797fd3c87c9ca7c55cc4ccbf0f10 # Parent d9d06daac6408af7c67863eed8cf17d3f09ffddb Move reusable parts of LIRInstructionClass into base class. diff -r d9d06daac640 -r 25fd899b979f 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 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 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 INSTRUCTION_CLASS = LIRInstruction.class; + private static final Class 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 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 scalarOffsets = new ArrayList<>(); - public final ArrayList arrayOffsets = new ArrayList<>(); - public final Map> flags = new HashMap<>(); - } - - protected static class FieldScanner extends BaseFieldScanner { - - public final Map, OperandModeAnnotation> valueAnnotations; - public final ArrayList 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, 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 getFlags(Field field) { + @Override + protected EnumSet getFlags(Field field) { EnumSet 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[] 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 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 ""; - } } diff -r d9d06daac640 -r 25fd899b979f graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java --- /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_CLASS = Value.class; + private static final Class CONSTANT_CLASS = Constant.class; + private static final Class VALUE_ARRAY_CLASS = Value[].class; + + public LIRIntrospection(Class clazz) { + super(clazz); + } + + protected static class OperandModeAnnotation { + + public final ArrayList scalarOffsets = new ArrayList<>(); + public final ArrayList arrayOffsets = new ArrayList<>(); + public final Map> flags = new HashMap<>(); + } + + protected abstract static class FieldScanner extends BaseFieldScanner { + + public final Map, OperandModeAnnotation> valueAnnotations; + public final ArrayList stateOffsets = new ArrayList<>(); + + public FieldScanner(CalcOffset calc) { + super(calc); + + valueAnnotations = new HashMap<>(); + } + + protected OperandModeAnnotation getOperandModeAnnotation(Field field) { + OperandModeAnnotation result = null; + for (Entry, 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 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[] 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 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 ""; + } +}