# HG changeset patch # User Roland Schatz # Date 1362665779 -3600 # Node ID a85ef330ffe7b20aa671932f6f0006364bc5eca6 # Parent 25fd899b979f797fd3c87c9ca7c55cc4ccbf0f10 Composite value. diff -r 25fd899b979f -r a85ef330ffe7 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java Thu Mar 07 15:16:19 2013 +0100 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 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 java.lang.annotation.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.lir.LIRInstruction.OperandFlag; +import com.oracle.graal.lir.LIRInstruction.OperandMode; +import com.oracle.graal.lir.LIRInstruction.ValueProcedure; + +/** + * Base class to represent values that need to be stored in more than one register. + */ +public abstract class CompositeValue extends Value { + + private static final long serialVersionUID = -169180052684126180L; + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + public static @interface Component { + + OperandFlag[] value() default OperandFlag.REG; + } + + private final CompositeValueClass valueClass; + + public CompositeValue(Kind kind) { + super(kind); + valueClass = CompositeValueClass.get(getClass()); + } + + public final void forEachComponent(OperandMode mode, ValueProcedure proc) { + valueClass.forEachComponent(this, mode, proc); + } + + @Override + public String toString() { + return valueClass.toString(this); + } +} diff -r 25fd899b979f -r a85ef330ffe7 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java Thu Mar 07 15:16:19 2013 +0100 @@ -0,0 +1,145 @@ +/* + * Copyright (c) 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 java.lang.reflect.*; +import java.util.*; + +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; + +public class CompositeValueClass extends LIRIntrospection { + + public static final CompositeValueClass get(Class c) { + CompositeValueClass clazz = (CompositeValueClass) allClasses.get(c); + if (clazz != null) { + return clazz; + } + + // We can have a race of multiple threads creating the LIRInstructionClass at the same time. + // However, only one will be put into the map, and this is the one returned by all threads. + clazz = new CompositeValueClass(c); + CompositeValueClass oldClazz = (CompositeValueClass) allClasses.putIfAbsent(c, clazz); + if (oldClazz != null) { + return oldClazz; + } else { + return clazz; + } + } + + private final int directComponentCount; + private final long[] componentOffsets; + private final EnumSet[] componentFlags; + + @SuppressWarnings("unchecked") + public CompositeValueClass(Class clazz) { + super(clazz); + + ValueFieldScanner scanner = new ValueFieldScanner(new DefaultCalcOffset()); + scanner.scan(clazz); + + OperandModeAnnotation mode = scanner.valueAnnotations.get(CompositeValue.Component.class); + directComponentCount = mode.scalarOffsets.size(); + componentOffsets = sortedLongCopy(mode.scalarOffsets, mode.arrayOffsets); + componentFlags = arrayUsingSortedOffsets(mode.flags, componentOffsets, new EnumSet[componentOffsets.length]); + + dataOffsets = sortedLongCopy(scanner.dataOffsets); + + fieldNames = scanner.fieldNames; + fieldTypes = scanner.fieldTypes; + } + + @Override + protected void rescanFieldOffsets(CalcOffset calc) { + ValueFieldScanner scanner = new ValueFieldScanner(calc); + scanner.scan(clazz); + + OperandModeAnnotation mode = scanner.valueAnnotations.get(CompositeValue.Component.class); + copyInto(componentOffsets, sortedLongCopy(mode.scalarOffsets, mode.arrayOffsets)); + + copyInto(dataOffsets, sortedLongCopy(scanner.dataOffsets)); + + fieldNames.clear(); + fieldNames.putAll(scanner.fieldNames); + fieldTypes.clear(); + fieldTypes.putAll(scanner.fieldTypes); + } + + private static class ValueFieldScanner extends FieldScanner { + + public ValueFieldScanner(CalcOffset calc) { + super(calc); + + valueAnnotations.put(CompositeValue.Component.class, new OperandModeAnnotation()); + } + + @Override + protected 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)) { + result.addAll(Arrays.asList(field.getAnnotation(CompositeValue.Component.class).value())); + } else { + GraalInternalError.shouldNotReachHere(); + } + return result; + } + } + + @Override + public String toString() { + StringBuilder str = new StringBuilder(); + str.append(getClass().getSimpleName()).append(" ").append(clazz.getSimpleName()).append(" component["); + for (int i = 0; i < componentOffsets.length; i++) { + str.append(i == 0 ? "" : ", ").append(componentOffsets[i]); + } + str.append("] data["); + for (int i = 0; i < dataOffsets.length; i++) { + str.append(i == 0 ? "" : ", ").append(dataOffsets[i]); + } + str.append("]"); + return str.toString(); + } + + public final void forEachComponent(CompositeValue obj, OperandMode mode, ValueProcedure proc) { + forEach(obj, directComponentCount, componentOffsets, mode, componentFlags, proc); + } + + public String toString(CompositeValue obj) { + StringBuilder result = new StringBuilder(); + + appendValues(result, obj, "", "", "{", "}", new String[]{""}, componentOffsets); + + for (int i = 0; i < dataOffsets.length; i++) { + result.append(" ").append(fieldNames.get(dataOffsets[i])).append(": ").append(getFieldString(obj, dataOffsets[i])); + } + + return result.toString(); + } +} diff -r 25fd899b979f -r a85ef330ffe7 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Thu Mar 07 15:16:18 2013 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Thu Mar 07 15:16:19 2013 +0100 @@ -171,6 +171,11 @@ ADDR, /** + * The value can be a {@link CompositeValue}. + */ + COMPOSITE, + + /** * The value can be a {@link Constant}. */ CONST, @@ -205,10 +210,10 @@ static { ALLOWED_FLAGS = new EnumMap<>(OperandMode.class); - ALLOWED_FLAGS.put(USE, EnumSet.of(REG, STACK, ADDR, CONST, ILLEGAL, HINT, UNINITIALIZED)); - ALLOWED_FLAGS.put(ALIVE, EnumSet.of(REG, STACK, ADDR, CONST, ILLEGAL, HINT, UNINITIALIZED)); - ALLOWED_FLAGS.put(TEMP, EnumSet.of(REG, CONST, ILLEGAL, HINT)); - ALLOWED_FLAGS.put(DEF, EnumSet.of(REG, STACK, ILLEGAL, HINT)); + ALLOWED_FLAGS.put(USE, EnumSet.of(REG, STACK, ADDR, COMPOSITE, CONST, ILLEGAL, HINT, UNUSED, UNINITIALIZED)); + ALLOWED_FLAGS.put(ALIVE, EnumSet.of(REG, STACK, ADDR, COMPOSITE, CONST, ILLEGAL, HINT, UNUSED, UNINITIALIZED)); + ALLOWED_FLAGS.put(TEMP, EnumSet.of(REG, COMPOSITE, CONST, ILLEGAL, UNUSED, HINT)); + ALLOWED_FLAGS.put(DEF, EnumSet.of(REG, STACK, COMPOSITE, ILLEGAL, UNUSED, HINT)); } /** diff -r 25fd899b979f -r a85ef330ffe7 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java Thu Mar 07 15:16:18 2013 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java Thu Mar 07 15:16:19 2013 +0100 @@ -105,7 +105,10 @@ if (i < directCount) { Value value = getValue(obj, offsets[i]); - if (isAddress(value)) { + if (value instanceof CompositeValue) { + CompositeValue composite = (CompositeValue) value; + composite.forEachComponent(mode, proc); + } else if (isAddress(value)) { doAddress(asAddress(value), mode, flags[i], proc); } else { setValue(obj, offsets[i], proc.doValue(value, mode, flags[i])); @@ -114,7 +117,10 @@ Value[] values = getValueArray(obj, offsets[i]); for (int j = 0; j < values.length; j++) { Value value = values[j]; - if (isAddress(value)) { + if (value instanceof CompositeValue) { + CompositeValue composite = (CompositeValue) value; + composite.forEachComponent(mode, proc); + } else if (isAddress(value)) { doAddress(asAddress(value), mode, flags[i], proc); } else { values[j] = proc.doValue(value, mode, flags[i]);