changeset 8165:a85ef330ffe7

Composite value.
author Roland Schatz <roland.schatz@oracle.com>
date Thu, 07 Mar 2013 15:16:19 +0100
parents 25fd899b979f
children d2733c9b3d0e
files graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java
diffstat 4 files changed, 223 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- /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);
+    }
+}
--- /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<? extends CompositeValue> 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<OperandFlag>[] componentFlags;
+
+    @SuppressWarnings("unchecked")
+    public CompositeValueClass(Class<? extends CompositeValue> 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<OperandFlag> getFlags(Field field) {
+            EnumSet<OperandFlag> 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();
+    }
+}
--- 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));
     }
 
     /**
--- 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]);