--- /dev/null 2016-05-31 09:42:47.975716356 -0700 +++ new/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/CompositeValue.java 2016-12-09 00:53:56.901108300 -0800 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013, 2015, 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 org.graalvm.compiler.lir; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.EnumSet; + +import org.graalvm.compiler.debug.Debug; +import org.graalvm.compiler.debug.DebugCounter; +import org.graalvm.compiler.lir.LIRInstruction.OperandFlag; +import org.graalvm.compiler.lir.LIRInstruction.OperandMode; + +import jdk.vm.ci.meta.Value; +import jdk.vm.ci.meta.ValueKind; + +/** + * 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 Value { + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + public static @interface Component { + + OperandFlag[] value() default OperandFlag.REG; + } + + private static final DebugCounter COMPOSITE_VALUE_COUNT = Debug.counter("CompositeValues"); + + public CompositeValue(ValueKind kind) { + super(kind); + COMPOSITE_VALUE_COUNT.increment(); + assert CompositeValueClass.get(getClass()) != null; + } + + /** + * 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 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; + } + + protected abstract void visitEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueConsumer proc); + + @Override + public String toString() { + return CompositeValueClass.format(this); + } + + @Override + public int hashCode() { + return 53 * super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof CompositeValue) { + CompositeValue other = (CompositeValue) obj; + return super.equals(other); + } + return false; + } +}