changeset 20973:cb406df0ecc3

Visit CompositeValues manually
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Tue, 14 Apr 2015 11:36:42 -0700
parents a69a7c0e0ccc
children 1af76d197949
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest1.java graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest2.java 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/LIRIntrospection.java
diffstat 9 files changed, 132 insertions(+), 347 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java	Tue Apr 07 12:09:46 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java	Tue Apr 14 11:36:42 2015 -0700
@@ -26,7 +26,6 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.lir.*;
 
 /**
  * Represents a constant non-{@code null} object reference, within the compiler and across the
@@ -84,14 +83,6 @@
     JavaConstant getCallSiteTarget(Assumptions assumptions);
 
     /**
-     * Gets the result of {@link CompositeValueClass#create(Class)} for the {@link Class} object
-     * represented by this constant.
-     *
-     * @return {@code null} if this constant does not represent a {@link Class} object
-     */
-    JavaConstant getCompositeValueClass();
-
-    /**
      * Determines if this constant represents an {@linkplain String#intern() interned} string.
      */
     boolean isInternedString();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java	Tue Apr 07 12:09:46 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java	Tue Apr 14 11:36:42 2015 -0700
@@ -28,9 +28,8 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.lir.*;
 
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import edu.umd.cs.findbugs.annotations.*;
 
 /**
  * Represents a constant non-{@code null} object reference, within the compiler and across the
@@ -184,16 +183,6 @@
         return null;
     }
 
-    @SuppressWarnings("unchecked")
-    public JavaConstant getCompositeValueClass() {
-        if (object instanceof Class) {
-            Class<? extends CompositeValue> c = (Class<? extends CompositeValue>) object;
-            assert CompositeValue.class.isAssignableFrom(c) : c;
-            return HotSpotObjectConstantImpl.forObject(CompositeValueClass.create(c));
-        }
-        return null;
-    }
-
     @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "reference equality is what we want")
     public boolean isInternedString() {
         if (object instanceof String) {
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java	Tue Apr 07 12:09:46 2015 -0700
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java	Tue Apr 14 11:36:42 2015 -0700
@@ -25,16 +25,16 @@
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
+import java.util.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.asm.amd64.AMD64Address.Scale;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.OperandFlag;
+import com.oracle.graal.lir.LIRInstruction.*;
 
 public final class AMD64AddressValue extends CompositeValue {
-    public static final CompositeValueClass<AMD64AddressValue> TYPE = CompositeValueClass.create(AMD64AddressValue.class);
-
     private static final long serialVersionUID = -4444600052487578694L;
 
     @Component({REG, OperandFlag.ILLEGAL}) protected AllocatableValue base;
@@ -42,12 +42,14 @@
     protected final Scale scale;
     protected final int displacement;
 
+    private static final EnumSet<OperandFlag> flags = EnumSet.of(OperandFlag.REG, OperandFlag.ILLEGAL);
+
     public AMD64AddressValue(LIRKind kind, AllocatableValue base, int displacement) {
         this(kind, base, Value.ILLEGAL, Scale.Times1, displacement);
     }
 
     public AMD64AddressValue(LIRKind kind, AllocatableValue base, AllocatableValue index, Scale scale, int displacement) {
-        super(TYPE, kind);
+        super(kind);
         this.base = base;
         this.index = index;
         this.scale = scale;
@@ -56,6 +58,16 @@
         assert scale != null;
     }
 
+    @Override
+    public CompositeValue forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc) {
+        AllocatableValue newBase = (AllocatableValue) proc.doValue(inst, base, mode, flags);
+        AllocatableValue newIndex = (AllocatableValue) proc.doValue(inst, index, mode, flags);
+        if (!base.identityEquals(newBase) || !index.identityEquals(newIndex)) {
+            return new AMD64AddressValue(getLIRKind(), newBase, newIndex, scale, displacement);
+        }
+        return this;
+    }
+
     private static Register toRegister(AllocatableValue value) {
         if (value.equals(Value.ILLEGAL)) {
             return Register.None;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java	Tue Apr 07 12:09:46 2015 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java	Tue Apr 14 11:36:42 2015 -0700
@@ -25,33 +25,46 @@
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
+import java.util.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.LIRInstruction.OperandFlag;
+import com.oracle.graal.lir.LIRInstruction.OperandMode;
 
 public final class SPARCAddressValue extends CompositeValue {
-    public static final CompositeValueClass<SPARCAddressValue> TYPE = CompositeValueClass.create(SPARCAddressValue.class);
-
     private static final long serialVersionUID = -3583286416638228207L;
 
     @Component({REG, OperandFlag.ILLEGAL}) protected AllocatableValue base;
     @Component({REG, OperandFlag.ILLEGAL}) protected AllocatableValue index;
     protected final int displacement;
 
+    private static final EnumSet<OperandFlag> flags = EnumSet.of(OperandFlag.REG, OperandFlag.ILLEGAL);
+
     public SPARCAddressValue(LIRKind kind, AllocatableValue base, int displacement) {
         this(kind, base, Value.ILLEGAL, displacement);
     }
 
     public SPARCAddressValue(LIRKind kind, AllocatableValue base, AllocatableValue index, int displacement) {
-        super(TYPE, kind);
+        super(kind);
         assert isIllegal(index) || displacement == 0;
         this.base = base;
         this.index = index;
         this.displacement = displacement;
     }
 
+    @Override
+    public CompositeValue forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc) {
+        AllocatableValue newBase = (AllocatableValue) proc.doValue(inst, base, mode, flags);
+        AllocatableValue newIndex = (AllocatableValue) proc.doValue(inst, index, mode, flags);
+        if (!base.identityEquals(newBase) || !index.identityEquals(newIndex)) {
+            return new SPARCAddressValue(getLIRKind(), newBase, newIndex, displacement);
+        }
+        return this;
+    }
+
     private static Register toRegister(AllocatableValue value) {
         if (isIllegal(value)) {
             return Register.None;
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest1.java	Tue Apr 07 12:09:46 2015 -0700
+++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest1.java	Tue Apr 14 11:36:42 2015 -0700
@@ -25,11 +25,14 @@
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static org.junit.Assert.*;
 
+import java.util.*;
+
 import org.junit.*;
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.LIRInstruction.OperandFlag;
+import com.oracle.graal.lir.LIRInstruction.OperandMode;
 import com.oracle.graal.lir.asm.*;
 
 /**
@@ -38,17 +41,26 @@
  */
 public class CompositeValueReplacementTest1 {
 
-    private static class NestedCompositeValue extends CompositeValue {
-        public static final CompositeValueClass<NestedCompositeValue> TYPE = CompositeValueClass.create(NestedCompositeValue.class);
+    private static class TestCompositeValue extends CompositeValue {
 
         private static final long serialVersionUID = -8804214200173503527L;
         @Component({REG, OperandFlag.ILLEGAL}) protected Value value;
 
-        public NestedCompositeValue(Value value) {
-            super(TYPE, LIRKind.Illegal);
+        public TestCompositeValue(Value value) {
+            super(LIRKind.Illegal);
             this.value = value;
         }
 
+        private static final EnumSet<OperandFlag> flags = EnumSet.of(OperandFlag.REG, OperandFlag.ILLEGAL);
+
+        @Override
+        public CompositeValue forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc) {
+            Value newValue = proc.doValue(inst, value, mode, flags);
+            if (!value.identityEquals(newValue)) {
+                return new TestCompositeValue(newValue);
+            }
+            return this;
+        }
     }
 
     private static class DummyValue extends AbstractValue {
@@ -98,9 +110,9 @@
     private static final class TestOp extends LIRInstruction {
         public static final LIRInstructionClass<TestOp> TYPE = LIRInstructionClass.create(TestOp.class);
 
-        @Use({COMPOSITE}) protected NestedCompositeValue compValue;
+        @Use({COMPOSITE}) protected TestCompositeValue compValue;
 
-        public TestOp(NestedCompositeValue compValue) {
+        public TestOp(TestCompositeValue compValue) {
             super(TYPE);
             this.compValue = compValue;
         }
@@ -112,43 +124,12 @@
 
     }
 
-    private static NestedCompositeValue createNestedCompValue(Value value, int nestingLevel) {
-        NestedCompositeValue compValue = new NestedCompositeValue(value);
-        for (int i = 0; i < nestingLevel; i++) {
-            compValue = new NestedCompositeValue(compValue);
-        }
-        return compValue;
-    }
-
     @Test
     public void replaceCompValueTest0() {
         DummyValue dummyValue1 = new DummyValue();
         DummyValue dummyValue2 = new DummyValue();
         DummyValue dummyValue3 = new DummyValue();
-        NestedCompositeValue compValue1 = createNestedCompValue(dummyValue1, 0);
-        LIRInstruction op1 = new TestOp(compValue1);
-        LIRInstruction op2 = new TestOp(compValue1);
-
-        op1.forEachInput((instruction, value, mode, flags) -> {
-            assertEquals(dummyValue1, value);
-            return dummyValue2;
-        });
-
-        op2.forEachInput((instruction, value, mode, flags) -> {
-            assertEquals(dummyValue1, value);
-            return dummyValue3;
-        });
-
-        op1.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue2, value));
-        op2.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue3, value));
-    }
-
-    @Test
-    public void replaceCompValueTest1() {
-        DummyValue dummyValue1 = new DummyValue();
-        DummyValue dummyValue2 = new DummyValue();
-        DummyValue dummyValue3 = new DummyValue();
-        NestedCompositeValue compValue1 = createNestedCompValue(dummyValue1, 1);
+        TestCompositeValue compValue1 = new TestCompositeValue(dummyValue1);
         LIRInstruction op1 = new TestOp(compValue1);
         LIRInstruction op2 = new TestOp(compValue1);
 
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest2.java	Tue Apr 07 12:09:46 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-/*
- * Copyright (c) 2014, 2014, 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.test;
-
-import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
-import static org.junit.Assert.*;
-
-import org.junit.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.LIRInstruction.OperandFlag;
-import com.oracle.graal.lir.asm.*;
-
-/**
- * Same as {@link CompositeValueReplacementTest1} but with value arrays.
- *
- * @see CompositeValueReplacementTest1
- */
-public class CompositeValueReplacementTest2 {
-
-    private static class NestedCompositeValue extends CompositeValue {
-        public static final CompositeValueClass<NestedCompositeValue> TYPE = CompositeValueClass.create(NestedCompositeValue.class);
-
-        private static final long serialVersionUID = -8804214200173503527L;
-        @Component({REG, OperandFlag.ILLEGAL}) protected Value[] values;
-
-        public NestedCompositeValue(Value value) {
-            super(TYPE, LIRKind.Illegal);
-            this.values = new Value[]{value};
-        }
-
-    }
-
-    private static class DummyValue extends AbstractValue {
-
-        private static final long serialVersionUID = -645435039553382737L;
-        private final int id;
-        private static int counter = 1;
-
-        protected DummyValue() {
-            super(LIRKind.Illegal);
-            this.id = counter++;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = super.hashCode();
-            result = prime * result + id;
-            return result;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (!super.equals(obj)) {
-                return false;
-            }
-            if (getClass() != obj.getClass()) {
-                return false;
-            }
-            DummyValue other = (DummyValue) obj;
-            if (id != other.id) {
-                return false;
-            }
-            return true;
-        }
-
-        @Override
-        public String toString() {
-            return "DummyValue [id=" + id + "]";
-        }
-
-    }
-
-    private static final class TestOp extends LIRInstruction {
-        public static final LIRInstructionClass<TestOp> TYPE = LIRInstructionClass.create(TestOp.class);
-
-        @Use({COMPOSITE}) protected NestedCompositeValue compValue;
-
-        public TestOp(NestedCompositeValue compValue) {
-            super(TYPE);
-            this.compValue = compValue;
-        }
-
-        @Override
-        public void emitCode(CompilationResultBuilder crb) {
-            fail("should not reach!");
-        }
-
-    }
-
-    private static NestedCompositeValue createNestedCompValue(Value value, int nestingLevel) {
-        NestedCompositeValue compValue = new NestedCompositeValue(value);
-        for (int i = 0; i < nestingLevel; i++) {
-            compValue = new NestedCompositeValue(compValue);
-        }
-        return compValue;
-    }
-
-    @Test
-    public void replaceCompValueTest0() {
-        DummyValue dummyValue1 = new DummyValue();
-        DummyValue dummyValue2 = new DummyValue();
-        DummyValue dummyValue3 = new DummyValue();
-        NestedCompositeValue compValue1 = createNestedCompValue(dummyValue1, 0);
-        LIRInstruction op1 = new TestOp(compValue1);
-        LIRInstruction op2 = new TestOp(compValue1);
-
-        op1.forEachInput((instruction, value, mode, flags) -> {
-            assertEquals(dummyValue1, value);
-            return dummyValue2;
-        });
-
-        op2.forEachInput((instruction, value, mode, flags) -> {
-            assertEquals(dummyValue1, value);
-            return dummyValue3;
-        });
-
-        op1.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue2, value));
-        op2.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue3, value));
-    }
-
-    @Test
-    public void replaceCompValueTest1() {
-        DummyValue dummyValue1 = new DummyValue();
-        DummyValue dummyValue2 = new DummyValue();
-        DummyValue dummyValue3 = new DummyValue();
-        NestedCompositeValue compValue1 = createNestedCompValue(dummyValue1, 1);
-        LIRInstruction op1 = new TestOp(compValue1);
-        LIRInstruction op2 = new TestOp(compValue1);
-
-        op1.forEachInput((instruction, value, mode, flags) -> {
-            assertEquals(dummyValue1, value);
-            return dummyValue2;
-        });
-
-        op2.forEachInput((instruction, value, mode, flags) -> {
-            assertEquals(dummyValue1, value);
-            return dummyValue3;
-        });
-
-        op1.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue2, value));
-        op2.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue3, value));
-    }
-}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java	Tue Apr 07 12:09:46 2015 -0700
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java	Tue Apr 14 11:36:42 2015 -0700
@@ -23,17 +23,19 @@
 package com.oracle.graal.lir;
 
 import java.lang.annotation.*;
+import java.util.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.lir.LIRInstruction.OperandFlag;
 import com.oracle.graal.lir.LIRInstruction.OperandMode;
 
 /**
- * Base class to represent values that need to be stored in more than one register.
+ * Base class to represent values that need to be stored in more than one register. This is mainly
+ * intended to support addresses and not general arbitrary nesting of composite values. Because of
+ * the possibility of sharing of CompositeValues they should be immutable.
  */
-public abstract class CompositeValue extends AbstractValue implements Cloneable {
+public abstract class CompositeValue extends AbstractValue {
 
     private static final long serialVersionUID = -169180052684126180L;
 
@@ -44,57 +46,67 @@
         OperandFlag[] value() default OperandFlag.REG;
     }
 
-    private final CompositeValueClass<?> valueClass;
-
     private static final DebugMetric COMPOSITE_VALUE_COUNT = Debug.metric("CompositeValues");
 
-    public CompositeValue(CompositeValueClass<? extends CompositeValue> c, LIRKind kind) {
+    public CompositeValue(LIRKind kind) {
         super(kind);
         COMPOSITE_VALUE_COUNT.increment();
-        valueClass = c;
-        assert c.getClazz() == this.getClass();
+        assert CompositeValueClass.get(getClass()) != null;
     }
 
-    final CompositeValue forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc) {
-        return valueClass.forEachComponent(inst, this, mode, proc);
+    /**
+     * Invoke {@code proc} on each {@link Value} element of this {@link CompositeValue}. If
+     * {@code proc} replaces any value then a new CompositeValue should be returned.
+     *
+     * @param inst
+     * @param mode
+     * @param proc
+     * @return the original CompositeValue or a copy with any modified values
+     */
+    public abstract CompositeValue forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc);
+
+    /**
+     * A helper method to visit {@link Value}[] ensuring that a copy of the array is made if it's
+     * needed.
+     *
+     * @param inst
+     * @param values
+     * @param mode
+     * @param proc
+     * @param flags
+     * @return the original {@code values} array or a copy if values changed
+     */
+    protected Value[] visitValueArray(LIRInstruction inst, Value[] values, OperandMode mode, InstructionValueProcedure proc, EnumSet<OperandFlag> flags) {
+        Value[] newValues = null;
+        for (int i = 0; i < values.length; i++) {
+            Value value = values[i];
+            Value newValue = proc.doValue(inst, value, mode, flags);
+            if (!value.identityEquals(newValue)) {
+                if (newValues == null) {
+                    newValues = values.clone();
+                }
+                newValues[i] = value;
+            }
+        }
+        return newValues != null ? newValues : values;
     }
 
     @Override
     public String toString() {
-        return valueClass.toString(this);
+        return CompositeValueClass.format(this);
     }
 
     @Override
     public int hashCode() {
-        return 53 * super.hashCode() + valueClass.hashCode();
+        return 53 * super.hashCode();
     }
 
     @Override
     public boolean equals(Object obj) {
         if (obj instanceof CompositeValue) {
             CompositeValue other = (CompositeValue) obj;
-            return super.equals(other) && valueClass.equals(other.valueClass);
+            return super.equals(other);
         }
         return false;
     }
-
-    CompositeValueClass<?> getValueClass() {
-        return valueClass;
-    }
-
-    @Override
-    public final CompositeValue clone() {
-        CompositeValue compositeValue = null;
-        try {
-            compositeValue = (CompositeValue) super.clone();
-        } catch (CloneNotSupportedException e) {
-            throw new GraalInternalError(e);
-        }
-
-        // copy value arrays
-        getValueClass().copyValueArrays(compositeValue);
-
-        return compositeValue;
-    }
-
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java	Tue Apr 07 12:09:46 2015 -0700
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java	Tue Apr 14 11:36:42 2015 -0700
@@ -25,11 +25,12 @@
 import java.lang.reflect.*;
 import java.util.*;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.CompositeValue.Component;
 import com.oracle.graal.lir.LIRInstruction.OperandFlag;
-import com.oracle.graal.lir.LIRInstruction.OperandMode;
+import com.oracle.graal.lir.LIRIntrospection.LIRFieldsScanner;
+import com.oracle.graal.lir.LIRIntrospection.OperandModeAnnotation;
+import com.oracle.graal.lir.LIRIntrospection.Values;
 
 /**
  * Lazily associated metadata for every {@link CompositeValue} type. The metadata includes:
@@ -38,20 +39,35 @@
  * such fields.</li>
  * </ul>
  */
-public class CompositeValueClass<T> extends LIRIntrospection<T> {
+public final class CompositeValueClass<T> {
+
+    /**
+     * The CompositeValueClass is only used for formatting for the most part so cache it as a
+     * ClassValue.
+     */
+    private static final ClassValue<CompositeValueClass<?>> compositeClass = new ClassValue<CompositeValueClass<?>>() {
 
-    public static final <T extends CompositeValue> CompositeValueClass<T> create(Class<T> c) {
-        return new CompositeValueClass<>(c);
+        @Override
+        protected CompositeValueClass<?> computeValue(Class<?> type) {
+            CompositeValueClass<?> compositeValueClass = new CompositeValueClass<>(type);
+            assert compositeValueClass.values.getDirectCount() == compositeValueClass.values.getCount() : "only direct fields are allowed in composites";
+            return compositeValueClass;
+        }
+
+    };
+
+    public static CompositeValueClass<?> get(Class<?> type) {
+        return compositeClass.get(type);
     }
 
-    public CompositeValueClass(Class<T> clazz) {
-        this(clazz, new FieldsScanner.DefaultCalcOffset());
-    }
+    private final Class<?> clazz;
+    private final Values values;
+    private final Fields data;
 
-    public CompositeValueClass(Class<T> clazz, FieldsScanner.CalcOffset calcOffset) {
-        super(clazz);
+    private CompositeValueClass(Class<T> clazz) {
+        this.clazz = clazz;
 
-        CompositeValueFieldsScanner vfs = new CompositeValueFieldsScanner(calcOffset);
+        CompositeValueFieldsScanner vfs = new CompositeValueFieldsScanner(new FieldsScanner.DefaultCalcOffset());
         vfs.scan(clazz, CompositeValue.class, false);
 
         values = new Values(vfs.valueAnnotations.get(CompositeValue.Component.class));
@@ -80,7 +96,7 @@
     @Override
     public String toString() {
         StringBuilder str = new StringBuilder();
-        str.append(getClass().getSimpleName()).append(" ").append(getClazz().getSimpleName()).append(" components[");
+        str.append(getClass().getSimpleName()).append(" ").append(clazz.getSimpleName()).append(" components[");
         values.appendFields(str);
         str.append("] data[");
         data.appendFields(str);
@@ -88,27 +104,16 @@
         return str.toString();
     }
 
-    final CompositeValue forEachComponent(LIRInstruction inst, CompositeValue obj, OperandMode mode, InstructionValueProcedure proc) {
-        return super.forEachComponent(inst, obj, values, mode, proc);
-    }
-
-    public String toString(CompositeValue obj) {
+    public static String format(CompositeValue obj) {
+        CompositeValueClass<?> valueClass = compositeClass.get(obj.getClass());
         StringBuilder result = new StringBuilder();
 
-        appendValues(result, obj, "", "", "{", "}", new String[]{""}, values);
+        LIRIntrospection.appendValues(result, obj, "", "", "{", "}", new String[]{""}, valueClass.values);
 
-        for (int i = 0; i < data.getCount(); i++) {
-            result.append(" ").append(data.getName(i)).append(": ").append(getFieldString(obj, i, data));
+        for (int i = 0; i < valueClass.data.getCount(); i++) {
+            result.append(" ").append(valueClass.data.getName(i)).append(": ").append(LIRIntrospection.getFieldString(obj, i, valueClass.data));
         }
 
         return result.toString();
     }
-
-    void copyValueArrays(CompositeValue compositeValue) {
-        for (int i = values.getDirectCount(); i < values.getCount(); i++) {
-            Value[] valueArray = values.getValueArray(compositeValue, i);
-            Value[] newValueArray = Arrays.copyOf(valueArray, valueArray.length);
-            values.setValueArray(compositeValue, i, newValueArray);
-        }
-    }
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java	Tue Apr 07 12:09:46 2015 -0700
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java	Tue Apr 14 11:36:42 2015 -0700
@@ -235,56 +235,7 @@
         }
     }
 
-    protected static CompositeValue forEachComponent(LIRInstruction inst, CompositeValue obj, Values values, OperandMode mode, InstructionValueProcedure proc) {
-        CompositeValue newCompValue = null;
-        for (int i = 0; i < values.getCount(); i++) {
-            assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(values.getFlags(i));
-
-            if (i < values.getDirectCount()) {
-                Value value = values.getValue(obj, i);
-                Value newValue;
-                if (value instanceof CompositeValue) {
-                    CompositeValue composite = (CompositeValue) value;
-                    newValue = composite.forEachComponent(inst, mode, proc);
-                } else {
-                    newValue = proc.doValue(inst, value, mode, values.getFlags(i));
-                }
-                if (!value.identityEquals(newValue)) {
-                    // lazy initialize
-                    if (newCompValue == null) {
-                        newCompValue = obj.clone();
-                    }
-                    values.setValue(newCompValue, i, newValue);
-                }
-            } else {
-                Value[] valueArray = values.getValueArray(obj, i);
-                Value[] newValues = null;
-                for (int j = 0; j < valueArray.length; j++) {
-                    Value value = valueArray[j];
-                    Value newValue;
-                    if (value instanceof CompositeValue) {
-                        CompositeValue composite = (CompositeValue) value;
-                        newValue = composite.forEachComponent(inst, mode, proc);
-                    } else {
-                        newValue = proc.doValue(inst, value, mode, values.getFlags(i));
-                    }
-                    if (!value.identityEquals(newValue)) {
-                        // lazy initialize
-                        if (newValues == null) {
-                            if (newCompValue == null) {
-                                newCompValue = obj.clone();
-                            }
-                            newValues = values.getValueArray(newCompValue, i);
-                        }
-                        newValues[j] = newValue;
-                    }
-                }
-            }
-        }
-        return newCompValue != null ? newCompValue : obj;
-    }
-
-    protected void appendValues(StringBuilder sb, Object obj, String start, String end, String startMultiple, String endMultiple, String[] prefix, Fields... fieldsList) {
+    protected static void appendValues(StringBuilder sb, Object obj, String start, String end, String startMultiple, String endMultiple, String[] prefix, Fields... fieldsList) {
         int total = 0;
         for (Fields fields : fieldsList) {
             total += fields.getCount();
@@ -316,7 +267,7 @@
         sb.append(end);
     }
 
-    protected String getFieldString(Object obj, int index, Fields fields) {
+    protected static String getFieldString(Object obj, int index, Fields fields) {
         Object value = fields.get(obj, index);
         Class<?> type = fields.getType(index);
         if (value == null || type.isPrimitive() || !type.isArray()) {