# HG changeset patch # User Josef Eisl # Date 1412336938 -7200 # Node ID 5d4749f9c5f6e12c020abcbc1f5a536976faae28 # Parent 8a2a809110ba21bf69a7f1181ccbd1c3288c86b3# Parent 95b879bdce67faa998d687e2d09b416e962ad30f merge diff -r 8a2a809110ba -r 5d4749f9c5f6 CHANGELOG.md --- a/CHANGELOG.md Fri Oct 03 11:07:44 2014 +0200 +++ b/CHANGELOG.md Fri Oct 03 13:48:58 2014 +0200 @@ -6,6 +6,7 @@ * ... ### Truffle +* Relaxed declared type restriction on child fields to allow for interface types in addition to Node subclasses. * ... ## Version 0.5 diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java --- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java Fri Oct 03 13:48:58 2014 +0200 @@ -595,10 +595,7 @@ @Override protected Value appendConstant(Constant constant) { - if (gen.canInlineConstant(constant)) { - return constant; - } - return gen.emitMove(constant); + return gen.emitLoadConstant(constant); } @Override diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Oct 03 13:48:58 2014 +0200 @@ -93,21 +93,6 @@ } @Override - public boolean canStoreConstant(Constant c) { - // there is no immediate move of 64-bit constants on Intel - switch (c.getKind()) { - case Long: - return Util.isInt(c.asLong()) && !getCodeCache().needsDataPatch(c); - case Double: - return false; - case Object: - return c.isNull(); - default: - return true; - } - } - - @Override public boolean canInlineConstant(Constant c) { switch (c.getKind()) { case Long: @@ -119,13 +104,6 @@ } } - @Override - public Variable emitMove(Value input) { - Variable result = newVariable(input.getLIRKind()); - emitMove(result, input); - return result; - } - protected AMD64LIRInstruction createMove(AllocatableValue dst, Value src) { if (src instanceof AMD64AddressValue) { return new LeaOp(dst, (AMD64AddressValue) src); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/FieldIntrospection.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/FieldIntrospection.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/FieldIntrospection.java Fri Oct 03 13:48:58 2014 +0200 @@ -47,9 +47,11 @@ protected static final ConcurrentHashMap, FieldIntrospection> allClasses = new ConcurrentHashMap<>(); private final Class clazz; - protected long[] dataOffsets; - protected Map fieldNames; - protected Map> fieldTypes; + + /** + * The set of fields in {@link #clazz} that do long belong to a more specific category. + */ + protected Fields data; public FieldIntrospection(Class clazz) { this.clazz = clazz; @@ -59,90 +61,71 @@ return clazz; } + /** + * Gets the fields in {@link #getClazz()} that do long belong to specific category. + */ + public Fields getData() { + return data; + } + + /** + * Describes a field in a class during scanning. + */ + public static class FieldInfo implements Comparable { + public final long offset; + public final String name; + public final Class type; + + public FieldInfo(long offset, String name, Class type) { + this.offset = offset; + this.name = name; + this.type = type; + } + + /** + * Sorts fields in ascending order by their {@link #offset}s. + */ + public int compareTo(FieldInfo o) { + return offset < o.offset ? -1 : (offset > o.offset ? 1 : 0); + } + + @Override + public String toString() { + return "[" + offset + "]" + name + ":" + type.getSimpleName(); + } + } + public abstract static class BaseFieldScanner { private final CalcOffset calc; - /** The offsets of fields that are not specially handled by subclasses. */ - public final ArrayList dataOffsets = new ArrayList<>(); - - public final Map fieldNames = new HashMap<>(); - public final Map> fieldTypes = new HashMap<>(); + /** + * Fields not belonging to a more specific category defined by scanner subclasses are added + * to this list. + */ + public final ArrayList data = new ArrayList<>(); protected BaseFieldScanner(CalcOffset calc) { this.calc = calc; } - public void scan(Class clazz) { + /** + * Scans the fields in a class hierarchy. + */ + public void scan(Class clazz, boolean includeSuperclasses) { Class currentClazz = clazz; do { for (Field field : currentClazz.getDeclaredFields()) { if (Modifier.isStatic(field.getModifiers()) || Modifier.isTransient(field.getModifiers())) { continue; } - Class type = field.getType(); long offset = calc.getOffset(field); - - // scanField() may overwrite the name with a customized name. - fieldNames.put(offset, field.getName()); - fieldTypes.put(offset, type); - - scanField(field, type, offset); + scanField(field, offset); } currentClazz = currentClazz.getSuperclass(); - } while (currentClazz.getSuperclass() != Object.class); + } while (includeSuperclasses && currentClazz.getSuperclass() != Object.class); } - protected abstract void scanField(Field field, Class type, long offset); - } - - protected static void copyInto(long[] dest, long[] src) { - assert dest.length == src.length; - for (int i = 0; i < dest.length; i++) { - dest[i] = src[i]; - } - } - - protected static void copyInto(T[] dest, T[] src) { - assert dest.length == src.length; - for (int i = 0; i < dest.length; i++) { - dest[i] = src[i]; - } - } - - protected static void copyInto(T[] dest, List src) { - assert dest.length == src.size(); - for (int i = 0; i < dest.length; i++) { - dest[i] = src.get(i); - } - } - - protected static T[] arrayUsingSortedOffsets(Map map, long[] sortedOffsets, T[] result) { - for (int i = 0; i < sortedOffsets.length; i++) { - result[i] = map.get(sortedOffsets[i]); - } - return result; - } - - protected static long[] sortedLongCopy(ArrayList list1) { - Collections.sort(list1); - long[] result = new long[list1.size()]; - for (int i = 0; i < list1.size(); i++) { - result[i] = list1.get(i); - } - return result; - } - - protected static long[] sortedLongCopy(ArrayList list1, ArrayList list2) { - Collections.sort(list1); - Collections.sort(list2); - long[] result = new long[list1.size() + list2.size()]; - for (int i = 0; i < list1.size(); i++) { - result[i] = list1.get(i); - } - for (int i = 0; i < list2.size(); i++) { - result[list1.size() + i] = list2.get(i); - } - return result; + protected abstract void scanField(Field field, long offset); } } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/Fields.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/Fields.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/Fields.java Fri Oct 03 13:48:58 2014 +0200 @@ -28,25 +28,39 @@ import sun.misc.*; +import com.oracle.graal.compiler.common.FieldIntrospection.FieldInfo; + /** * Describes fields in a class, primarily for access via {@link Unsafe}. */ public class Fields { - protected final Class clazz; + /** + * Offsets used with {@link Unsafe} to access the fields. + */ protected final long[] offsets; + + /** + * The names of the fields. + */ private final String[] names; + + /** + * The types of the fields. + */ private final Class[] types; - public Fields(Class clazz, long[] offsets, Map names, Map> types) { - this.clazz = clazz; - this.offsets = offsets; - + public Fields(ArrayList fields) { + Collections.sort(fields); + this.offsets = new long[fields.size()]; this.names = new String[offsets.length]; this.types = new Class[offsets.length]; - for (int i = 0; i < offsets.length; i++) { - this.names[i] = names.get(offsets[i]); - this.types[i] = types.get(offsets[i]); + int index = 0; + for (FieldInfo f : fields) { + offsets[index] = f.offset; + names[index] = f.name; + types[index] = f.type; + index++; } } @@ -57,6 +71,12 @@ return offsets.length; } + public static void translateInto(Fields fields, ArrayList infos) { + for (int index = 0; index < fields.getCount(); index++) { + infos.add(new FieldInfo(fields.offsets[index], fields.names[index], fields.types[index])); + } + } + /** * Gets the value of a field for a given object. * @@ -126,44 +146,46 @@ * @param index the index of the field to check * @param value a value that will be assigned to the field */ - private boolean checkAssignableFrom(int index, Object value) { - assert value == null || getType(index).isAssignableFrom(value.getClass()) : String.format("%s.%s of type %s is not assignable from %s", clazz.getSimpleName(), getName(index), - getType(index).getSimpleName(), value.getClass().getSimpleName()); + private boolean checkAssignableFrom(Object object, int index, Object value) { + assert value == null || getType(index).isAssignableFrom(value.getClass()) : String.format("Field %s.%s of type %s is not assignable from %s", object.getClass().getSimpleName(), + getName(index), getType(index).getSimpleName(), value.getClass().getSimpleName()); return true; } public void set(Object object, int index, Object value) { - long dataOffset = offsets[index]; + long offset = offsets[index]; Class type = types[index]; if (type.isPrimitive()) { if (type == Integer.TYPE) { - unsafe.putInt(object, dataOffset, (Integer) value); + unsafe.putInt(object, offset, (Integer) value); } else if (type == Long.TYPE) { - unsafe.putLong(object, dataOffset, (Long) value); + unsafe.putLong(object, offset, (Long) value); } else if (type == Boolean.TYPE) { - unsafe.putBoolean(object, dataOffset, (Boolean) value); + unsafe.putBoolean(object, offset, (Boolean) value); } else if (type == Float.TYPE) { - unsafe.putFloat(object, dataOffset, (Float) value); + unsafe.putFloat(object, offset, (Float) value); } else if (type == Double.TYPE) { - unsafe.putDouble(object, dataOffset, (Double) value); + unsafe.putDouble(object, offset, (Double) value); } else if (type == Short.TYPE) { - unsafe.putShort(object, dataOffset, (Short) value); + unsafe.putShort(object, offset, (Short) value); } else if (type == Character.TYPE) { - unsafe.putChar(object, dataOffset, (Character) value); + unsafe.putChar(object, offset, (Character) value); } else if (type == Byte.TYPE) { - unsafe.putByte(object, dataOffset, (Byte) value); + unsafe.putByte(object, offset, (Byte) value); } else { assert false : "unhandled property type: " + type; } } else { - assert checkAssignableFrom(index, value); - unsafe.putObject(object, dataOffset, value); + assert checkAssignableFrom(object, index, value); + unsafe.putObject(object, offset, value); } } @Override public String toString() { - return clazz.getSimpleName(); + StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('['); + appendFields(sb); + return sb.append(']').toString(); } public void appendFields(StringBuilder sb) { @@ -216,4 +238,9 @@ assert !types[i].isPrimitive(); return unsafe.getObject(object, offsets[i]); } + + public void putObject(Object object, int i, Object value) { + assert checkAssignableFrom(object, i, value); + unsafe.putObject(object, offsets[i], value); + } } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticOpTable.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticOpTable.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticOpTable.java Fri Oct 03 13:48:58 2014 +0200 @@ -23,27 +23,124 @@ package com.oracle.graal.compiler.common.type; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; /** * Information about arithmetic operations. */ public final class ArithmeticOpTable { - protected UnaryOp neg; - protected BinaryOp add; - protected BinaryOp sub; + private final UnaryOp neg; + private final BinaryOp add; + private final BinaryOp sub; - protected BinaryOp mul; - protected BinaryOp div; - protected BinaryOp rem; + private final BinaryOp mul; + private final BinaryOp div; + private final BinaryOp rem; - protected UnaryOp not; - protected BinaryOp and; - protected BinaryOp or; - protected BinaryOp xor; + private final UnaryOp not; + private final BinaryOp and; + private final BinaryOp or; + private final BinaryOp xor; public static ArithmeticOpTable forStamp(Stamp s) { - return ((ArithmeticStamp) s).getOps(); + if (s instanceof ArithmeticStamp) { + return ((ArithmeticStamp) s).getOps(); + } else { + return EMPTY; + } + } + + public static final ArithmeticOpTable EMPTY = create(); + + public static ArithmeticOpTable create(Op... ops) { + UnaryOp neg = null; + BinaryOp add = null; + BinaryOp sub = null; + + BinaryOp mul = null; + BinaryOp div = null; + BinaryOp rem = null; + + UnaryOp not = null; + BinaryOp and = null; + BinaryOp or = null; + BinaryOp xor = null; + + for (Op op : ops) { + if (op == null) { + continue; + } + + if (op instanceof UnaryOp) { + UnaryOp unary = (UnaryOp) op; + switch (unary.getOperator()) { + case '-': + assert neg == null; + neg = unary; + break; + case '~': + assert not == null; + not = unary; + break; + default: + throw GraalInternalError.shouldNotReachHere("unknown unary operator " + unary.getOperator()); + } + } else { + BinaryOp binary = (BinaryOp) op; + switch (binary.getOperator()) { + case '+': + assert add == null; + add = binary; + break; + case '-': + assert sub == null; + sub = binary; + break; + case '*': + assert mul == null; + mul = binary; + break; + case '/': + assert div == null; + div = binary; + break; + case '%': + assert rem == null; + rem = binary; + break; + case '&': + assert and == null; + and = binary; + break; + case '|': + assert or == null; + or = binary; + break; + case '^': + assert xor == null; + xor = binary; + break; + default: + throw GraalInternalError.shouldNotReachHere("unknown binary operator " + binary.getOperator()); + } + } + } + + return new ArithmeticOpTable(neg, add, sub, mul, div, rem, not, and, or, xor); + } + + private ArithmeticOpTable(UnaryOp neg, BinaryOp add, BinaryOp sub, BinaryOp mul, BinaryOp div, BinaryOp rem, UnaryOp not, BinaryOp and, BinaryOp or, BinaryOp xor) { + this.neg = neg; + this.add = add; + this.sub = sub; + this.mul = mul; + this.div = div; + this.rem = rem; + this.not = not; + this.and = and; + this.or = or; + this.xor = xor; } /** @@ -116,10 +213,32 @@ return xor; } + public abstract static class Op { + + private final char operator; + + protected Op(char operator) { + this.operator = operator; + } + + public char getOperator() { + return operator; + } + + @Override + public String toString() { + return Character.toString(operator); + } + } + /** * Describes a unary arithmetic operation. */ - public abstract static class UnaryOp { + public abstract static class UnaryOp extends Op { + + protected UnaryOp(char operation) { + super(operation); + } /** * Apply the operation to a {@link Constant}. @@ -135,12 +254,13 @@ /** * Describes a binary arithmetic operation. */ - public abstract static class BinaryOp { + public abstract static class BinaryOp extends Op { private final boolean associative; private final boolean commutative; - protected BinaryOp(boolean associative, boolean commutative) { + protected BinaryOp(char operation, boolean associative, boolean commutative) { + super(operation); this.associative = associative; this.commutative = commutative; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java Fri Oct 03 13:48:58 2014 +0200 @@ -252,188 +252,184 @@ return null; } - private static final ArithmeticOpTable OPS = new ArithmeticOpTable(); + private static final ArithmeticOpTable OPS = ArithmeticOpTable.create( - static { - OPS.neg = new UnaryOp() { + new UnaryOp('-') { - @Override - public Constant foldConstant(Constant value) { - switch (value.getKind()) { - case Float: - return Constant.forFloat(-value.asFloat()); - case Double: - return Constant.forDouble(-value.asDouble()); - default: - throw GraalInternalError.shouldNotReachHere(); - } - } - - @Override - public Stamp foldStamp(Stamp s) { - FloatStamp stamp = (FloatStamp) s; - return new FloatStamp(stamp.getBits(), -stamp.upperBound(), -stamp.lowerBound(), stamp.isNonNaN()); + @Override + public Constant foldConstant(Constant value) { + switch (value.getKind()) { + case Float: + return Constant.forFloat(-value.asFloat()); + case Double: + return Constant.forDouble(-value.asDouble()); + default: + throw GraalInternalError.shouldNotReachHere(); } - }; + } - OPS.add = new BinaryOp(false, true) { + @Override + public Stamp foldStamp(Stamp s) { + FloatStamp stamp = (FloatStamp) s; + return new FloatStamp(stamp.getBits(), -stamp.upperBound(), -stamp.lowerBound(), stamp.isNonNaN()); + } + }, + + new BinaryOp('+', false, true) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - switch (a.getKind()) { - case Float: - return Constant.forFloat(a.asFloat() + b.asFloat()); - case Double: - return Constant.forDouble(a.asDouble() + b.asDouble()); - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + switch (a.getKind()) { + case Float: + return Constant.forFloat(a.asFloat() + b.asFloat()); + case Double: + return Constant.forDouble(a.asDouble() + b.asDouble()); + default: + throw GraalInternalError.shouldNotReachHere(); } + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - // TODO - return stamp1.unrestricted(); - } + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + // TODO + return stamp1.unrestricted(); + } - @Override - public boolean isNeutral(Constant n) { - switch (n.getKind()) { - case Float: - return Float.compare(n.asFloat(), -0.0f) == 0; - case Double: - return Double.compare(n.asDouble(), -0.0) == 0; - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public boolean isNeutral(Constant n) { + switch (n.getKind()) { + case Float: + return Float.compare(n.asFloat(), -0.0f) == 0; + case Double: + return Double.compare(n.asDouble(), -0.0) == 0; + default: + throw GraalInternalError.shouldNotReachHere(); } - }; + } + }, - OPS.sub = new BinaryOp(false, false) { + new BinaryOp('-', false, false) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - switch (a.getKind()) { - case Float: - return Constant.forFloat(a.asFloat() - b.asFloat()); - case Double: - return Constant.forDouble(a.asDouble() - b.asDouble()); - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + switch (a.getKind()) { + case Float: + return Constant.forFloat(a.asFloat() - b.asFloat()); + case Double: + return Constant.forDouble(a.asDouble() - b.asDouble()); + default: + throw GraalInternalError.shouldNotReachHere(); } + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - // TODO - return stamp1.unrestricted(); - } + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + // TODO + return stamp1.unrestricted(); + } - @Override - public boolean isNeutral(Constant n) { - switch (n.getKind()) { - case Float: - return Float.compare(n.asFloat(), 0.0f) == 0; - case Double: - return Double.compare(n.asDouble(), 0.0) == 0; - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public boolean isNeutral(Constant n) { + switch (n.getKind()) { + case Float: + return Float.compare(n.asFloat(), 0.0f) == 0; + case Double: + return Double.compare(n.asDouble(), 0.0) == 0; + default: + throw GraalInternalError.shouldNotReachHere(); } - }; + } + }, - OPS.mul = new BinaryOp(false, true) { + new BinaryOp('*', false, true) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - switch (a.getKind()) { - case Float: - return Constant.forFloat(a.asFloat() * b.asFloat()); - case Double: - return Constant.forDouble(a.asDouble() * b.asDouble()); - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + switch (a.getKind()) { + case Float: + return Constant.forFloat(a.asFloat() * b.asFloat()); + case Double: + return Constant.forDouble(a.asDouble() * b.asDouble()); + default: + throw GraalInternalError.shouldNotReachHere(); } + } - @Override - public Stamp foldStamp(Stamp a, Stamp b) { - // TODO - return a.unrestricted(); - } + @Override + public Stamp foldStamp(Stamp a, Stamp b) { + // TODO + return a.unrestricted(); + } - @Override - public boolean isNeutral(Constant n) { - switch (n.getKind()) { - case Float: - return Float.compare(n.asFloat(), 1.0f) == 0; - case Double: - return Double.compare(n.asDouble(), 1.0) == 0; - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public boolean isNeutral(Constant n) { + switch (n.getKind()) { + case Float: + return Float.compare(n.asFloat(), 1.0f) == 0; + case Double: + return Double.compare(n.asDouble(), 1.0) == 0; + default: + throw GraalInternalError.shouldNotReachHere(); } + } + }, - // there is no multiplicative zero, since both 0.0 and -0.0 can flip sign - }; - - OPS.div = new BinaryOp(false, false) { + new BinaryOp('/', false, false) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - switch (a.getKind()) { - case Float: - return Constant.forFloat(a.asFloat() / b.asFloat()); - case Double: - return Constant.forDouble(a.asDouble() / b.asDouble()); - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + switch (a.getKind()) { + case Float: + return Constant.forFloat(a.asFloat() / b.asFloat()); + case Double: + return Constant.forDouble(a.asDouble() / b.asDouble()); + default: + throw GraalInternalError.shouldNotReachHere(); } + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - // TODO - return stamp1.unrestricted(); - } + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + // TODO + return stamp1.unrestricted(); + } - @Override - public boolean isNeutral(Constant n) { - switch (n.getKind()) { - case Float: - return Float.compare(n.asFloat(), 1.0f) == 0; - case Double: - return Double.compare(n.asDouble(), 1.0) == 0; - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public boolean isNeutral(Constant n) { + switch (n.getKind()) { + case Float: + return Float.compare(n.asFloat(), 1.0f) == 0; + case Double: + return Double.compare(n.asDouble(), 1.0) == 0; + default: + throw GraalInternalError.shouldNotReachHere(); } - }; + } + }, - OPS.rem = new BinaryOp(false, false) { + new BinaryOp('%', false, false) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - switch (a.getKind()) { - case Float: - return Constant.forFloat(a.asFloat() % b.asFloat()); - case Double: - return Constant.forDouble(a.asDouble() % b.asDouble()); - default: - throw GraalInternalError.shouldNotReachHere(); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + switch (a.getKind()) { + case Float: + return Constant.forFloat(a.asFloat() % b.asFloat()); + case Double: + return Constant.forDouble(a.asDouble() % b.asDouble()); + default: + throw GraalInternalError.shouldNotReachHere(); } + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - // TODO - return stamp1.unrestricted(); - } - }; - } + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + // TODO + return stamp1.unrestricted(); + } + }); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java Fri Oct 03 13:48:58 2014 +0200 @@ -350,290 +350,288 @@ return (x + y) ^ x ^ y; } - public static final ArithmeticOpTable OPS = new ArithmeticOpTable(); + public static final ArithmeticOpTable OPS = ArithmeticOpTable.create( - static { - OPS.neg = new UnaryOp() { + new UnaryOp('-') { - @Override - public Constant foldConstant(Constant value) { - return Constant.forIntegerKind(value.getKind(), -value.asLong()); - } + @Override + public Constant foldConstant(Constant value) { + return Constant.forIntegerKind(value.getKind(), -value.asLong()); + } - @Override - public Stamp foldStamp(Stamp s) { - IntegerStamp stamp = (IntegerStamp) s; - int bits = stamp.getBits(); - if (stamp.lowerBound() != CodeUtil.minValue(bits)) { - // TODO(ls) check if the mask calculation is correct... - return StampFactory.forInteger(bits, -stamp.upperBound(), -stamp.lowerBound()); - } else { - return stamp.unrestricted(); - } + @Override + public Stamp foldStamp(Stamp s) { + IntegerStamp stamp = (IntegerStamp) s; + int bits = stamp.getBits(); + if (stamp.lowerBound() != CodeUtil.minValue(bits)) { + // TODO(ls) check if the mask calculation is correct... + return StampFactory.forInteger(bits, -stamp.upperBound(), -stamp.lowerBound()); + } else { + return stamp.unrestricted(); } - }; + } + }, - OPS.add = new BinaryOp(true, true) { + new BinaryOp('+', true, true) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - return Constant.forIntegerKind(a.getKind(), a.asLong() + b.asLong()); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + return Constant.forIntegerKind(a.getKind(), a.asLong() + b.asLong()); + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - IntegerStamp a = (IntegerStamp) stamp1; - IntegerStamp b = (IntegerStamp) stamp2; + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + IntegerStamp a = (IntegerStamp) stamp1; + IntegerStamp b = (IntegerStamp) stamp2; - int bits = a.getBits(); - assert bits == b.getBits(); + int bits = a.getBits(); + assert bits == b.getBits(); - if (a.isUnrestricted()) { - return a; - } else if (b.isUnrestricted()) { - return b; - } - long defaultMask = CodeUtil.mask(bits); - long variableBits = (a.downMask() ^ a.upMask()) | (b.downMask() ^ b.upMask()); - long variableBitsWithCarry = variableBits | (carryBits(a.downMask(), b.downMask()) ^ carryBits(a.upMask(), b.upMask())); - long newDownMask = (a.downMask() + b.downMask()) & ~variableBitsWithCarry; - long newUpMask = (a.downMask() + b.downMask()) | variableBitsWithCarry; + if (a.isUnrestricted()) { + return a; + } else if (b.isUnrestricted()) { + return b; + } + long defaultMask = CodeUtil.mask(bits); + long variableBits = (a.downMask() ^ a.upMask()) | (b.downMask() ^ b.upMask()); + long variableBitsWithCarry = variableBits | (carryBits(a.downMask(), b.downMask()) ^ carryBits(a.upMask(), b.upMask())); + long newDownMask = (a.downMask() + b.downMask()) & ~variableBitsWithCarry; + long newUpMask = (a.downMask() + b.downMask()) | variableBitsWithCarry; - newDownMask &= defaultMask; - newUpMask &= defaultMask; + newDownMask &= defaultMask; + newUpMask &= defaultMask; - long newLowerBound; - long newUpperBound; - boolean lowerOverflowsPositively = addOverflowsPositively(a.lowerBound(), b.lowerBound(), bits); - boolean upperOverflowsPositively = addOverflowsPositively(a.upperBound(), b.upperBound(), bits); - boolean lowerOverflowsNegatively = addOverflowsNegatively(a.lowerBound(), b.lowerBound(), bits); - boolean upperOverflowsNegatively = addOverflowsNegatively(a.upperBound(), b.upperBound(), bits); - if ((lowerOverflowsNegatively && !upperOverflowsNegatively) || (!lowerOverflowsPositively && upperOverflowsPositively)) { - newLowerBound = CodeUtil.minValue(bits); - newUpperBound = CodeUtil.maxValue(bits); - } else { - newLowerBound = CodeUtil.signExtend((a.lowerBound() + b.lowerBound()) & defaultMask, bits); - newUpperBound = CodeUtil.signExtend((a.upperBound() + b.upperBound()) & defaultMask, bits); - } - IntegerStamp limit = StampFactory.forInteger(bits, newLowerBound, newUpperBound); - newUpMask &= limit.upMask(); - newUpperBound = CodeUtil.signExtend(newUpperBound & newUpMask, bits); - newDownMask |= limit.downMask(); - newLowerBound |= newDownMask; - return new IntegerStamp(bits, newLowerBound, newUpperBound, newDownMask, newUpMask); - } - - @Override - public boolean isNeutral(Constant n) { - return n.asLong() == 0; - } - }; - - OPS.sub = new BinaryOp(true, false) { - - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - return Constant.forIntegerKind(a.getKind(), a.asLong() - b.asLong()); - } - - @Override - public Stamp foldStamp(Stamp a, Stamp b) { - return OPS.add.foldStamp(a, OPS.neg.foldStamp(b)); - } - - @Override - public boolean isNeutral(Constant n) { - return n.asLong() == 0; + long newLowerBound; + long newUpperBound; + boolean lowerOverflowsPositively = addOverflowsPositively(a.lowerBound(), b.lowerBound(), bits); + boolean upperOverflowsPositively = addOverflowsPositively(a.upperBound(), b.upperBound(), bits); + boolean lowerOverflowsNegatively = addOverflowsNegatively(a.lowerBound(), b.lowerBound(), bits); + boolean upperOverflowsNegatively = addOverflowsNegatively(a.upperBound(), b.upperBound(), bits); + if ((lowerOverflowsNegatively && !upperOverflowsNegatively) || (!lowerOverflowsPositively && upperOverflowsPositively)) { + newLowerBound = CodeUtil.minValue(bits); + newUpperBound = CodeUtil.maxValue(bits); + } else { + newLowerBound = CodeUtil.signExtend((a.lowerBound() + b.lowerBound()) & defaultMask, bits); + newUpperBound = CodeUtil.signExtend((a.upperBound() + b.upperBound()) & defaultMask, bits); } + IntegerStamp limit = StampFactory.forInteger(bits, newLowerBound, newUpperBound); + newUpMask &= limit.upMask(); + newUpperBound = CodeUtil.signExtend(newUpperBound & newUpMask, bits); + newDownMask |= limit.downMask(); + newLowerBound |= newDownMask; + return new IntegerStamp(bits, newLowerBound, newUpperBound, newDownMask, newUpMask); + } - @Override - public Constant getZero(Stamp s) { - IntegerStamp stamp = (IntegerStamp) s; - return Constant.forPrimitiveInt(stamp.getBits(), 0); - } - }; + @Override + public boolean isNeutral(Constant n) { + return n.asLong() == 0; + } + }, + + new BinaryOp('-', true, false) { - OPS.mul = new BinaryOp(true, true) { + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + return Constant.forIntegerKind(a.getKind(), a.asLong() - b.asLong()); + } - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - return Constant.forIntegerKind(a.getKind(), a.asLong() * b.asLong()); - } + @Override + public Stamp foldStamp(Stamp a, Stamp b) { + return OPS.getAdd().foldStamp(a, OPS.getNeg().foldStamp(b)); + } + + @Override + public boolean isNeutral(Constant n) { + return n.asLong() == 0; + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - IntegerStamp a = (IntegerStamp) stamp1; - IntegerStamp b = (IntegerStamp) stamp2; - if (a.upMask() == 0) { - return a; - } else if (b.upMask() == 0) { - return b; - } else { - // TODO - return a.unrestricted(); - } - } + @Override + public Constant getZero(Stamp s) { + IntegerStamp stamp = (IntegerStamp) s; + return Constant.forPrimitiveInt(stamp.getBits(), 0); + } + }, + + new BinaryOp('*', true, true) { + + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + return Constant.forIntegerKind(a.getKind(), a.asLong() * b.asLong()); + } - @Override - public boolean isNeutral(Constant n) { - return n.asLong() == 1; + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + IntegerStamp a = (IntegerStamp) stamp1; + IntegerStamp b = (IntegerStamp) stamp2; + if (a.upMask() == 0) { + return a; + } else if (b.upMask() == 0) { + return b; + } else { + // TODO + return a.unrestricted(); } - }; + } - OPS.div = new BinaryOp(true, false) { + @Override + public boolean isNeutral(Constant n) { + return n.asLong() == 1; + } + }, - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - return Constant.forIntegerKind(a.getKind(), a.asLong() / b.asLong()); - } + new BinaryOp('/', true, false) { + + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + return Constant.forIntegerKind(a.getKind(), a.asLong() / b.asLong()); + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - IntegerStamp a = (IntegerStamp) stamp1; - IntegerStamp b = (IntegerStamp) stamp2; - assert a.getBits() == b.getBits(); - if (b.isStrictlyPositive()) { - long newLowerBound = a.lowerBound() / b.lowerBound(); - long newUpperBound = a.upperBound() / b.lowerBound(); - return StampFactory.forInteger(a.getBits(), newLowerBound, newUpperBound); - } else { - return a.unrestricted(); - } + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + IntegerStamp a = (IntegerStamp) stamp1; + IntegerStamp b = (IntegerStamp) stamp2; + assert a.getBits() == b.getBits(); + if (b.isStrictlyPositive()) { + long newLowerBound = a.lowerBound() / b.lowerBound(); + long newUpperBound = a.upperBound() / b.lowerBound(); + return StampFactory.forInteger(a.getBits(), newLowerBound, newUpperBound); + } else { + return a.unrestricted(); } + } - @Override - public boolean isNeutral(Constant n) { - return n.asLong() == 1; - } - }; + @Override + public boolean isNeutral(Constant n) { + return n.asLong() == 1; + } + }, - OPS.rem = new BinaryOp(false, false) { + new BinaryOp('%', false, false) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - return Constant.forIntegerKind(a.getKind(), a.asLong() % b.asLong()); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + return Constant.forIntegerKind(a.getKind(), a.asLong() % b.asLong()); + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - IntegerStamp a = (IntegerStamp) stamp1; - IntegerStamp b = (IntegerStamp) stamp2; - assert a.getBits() == b.getBits(); - // zero is always possible - long newLowerBound = Math.min(a.lowerBound(), 0); - long newUpperBound = Math.max(a.upperBound(), 0); + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + IntegerStamp a = (IntegerStamp) stamp1; + IntegerStamp b = (IntegerStamp) stamp2; + assert a.getBits() == b.getBits(); + // zero is always possible + long newLowerBound = Math.min(a.lowerBound(), 0); + long newUpperBound = Math.max(a.upperBound(), 0); - long magnitude; // the maximum absolute value of the result, derived from b - if (b.lowerBound() == CodeUtil.minValue(b.getBits())) { - // Math.abs(...) - 1 does not work in a case - magnitude = CodeUtil.maxValue(b.getBits()); - } else { - magnitude = Math.max(Math.abs(b.lowerBound()), Math.abs(b.upperBound())) - 1; - } - newLowerBound = Math.max(newLowerBound, -magnitude); - newUpperBound = Math.min(newUpperBound, magnitude); + long magnitude; // the maximum absolute value of the result, derived from b + if (b.lowerBound() == CodeUtil.minValue(b.getBits())) { + // Math.abs(...) - 1 does not work in a case + magnitude = CodeUtil.maxValue(b.getBits()); + } else { + magnitude = Math.max(Math.abs(b.lowerBound()), Math.abs(b.upperBound())) - 1; + } + newLowerBound = Math.max(newLowerBound, -magnitude); + newUpperBound = Math.min(newUpperBound, magnitude); - return StampFactory.forInteger(a.getBits(), newLowerBound, newUpperBound); - } - }; + return StampFactory.forInteger(a.getBits(), newLowerBound, newUpperBound); + } + }, - OPS.not = new UnaryOp() { + new UnaryOp('~') { - @Override - public Constant foldConstant(Constant value) { - return Constant.forIntegerKind(value.getKind(), ~value.asLong()); - } + @Override + public Constant foldConstant(Constant value) { + return Constant.forIntegerKind(value.getKind(), ~value.asLong()); + } - @Override - public Stamp foldStamp(Stamp stamp) { - IntegerStamp integerStamp = (IntegerStamp) stamp; - int bits = integerStamp.getBits(); - long defaultMask = CodeUtil.mask(bits); - return new IntegerStamp(bits, ~integerStamp.upperBound(), ~integerStamp.lowerBound(), (~integerStamp.upMask()) & defaultMask, (~integerStamp.downMask()) & defaultMask); - } - }; + @Override + public Stamp foldStamp(Stamp stamp) { + IntegerStamp integerStamp = (IntegerStamp) stamp; + int bits = integerStamp.getBits(); + long defaultMask = CodeUtil.mask(bits); + return new IntegerStamp(bits, ~integerStamp.upperBound(), ~integerStamp.lowerBound(), (~integerStamp.upMask()) & defaultMask, (~integerStamp.downMask()) & defaultMask); + } + }, - OPS.and = new BinaryOp(true, true) { + new BinaryOp('&', true, true) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - return Constant.forIntegerKind(a.getKind(), a.asLong() & b.asLong()); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + return Constant.forIntegerKind(a.getKind(), a.asLong() & b.asLong()); + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - IntegerStamp a = (IntegerStamp) stamp1; - IntegerStamp b = (IntegerStamp) stamp2; - assert a.getBits() == b.getBits(); - return stampForMask(a.getBits(), a.downMask() & b.downMask(), a.upMask() & b.upMask()); - } + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + IntegerStamp a = (IntegerStamp) stamp1; + IntegerStamp b = (IntegerStamp) stamp2; + assert a.getBits() == b.getBits(); + return stampForMask(a.getBits(), a.downMask() & b.downMask(), a.upMask() & b.upMask()); + } - @Override - public boolean isNeutral(Constant n) { - int bits = n.getKind().getBitCount(); - long mask = CodeUtil.mask(bits); - return (n.asLong() & mask) == mask; - } - }; + @Override + public boolean isNeutral(Constant n) { + int bits = n.getKind().getBitCount(); + long mask = CodeUtil.mask(bits); + return (n.asLong() & mask) == mask; + } + }, - OPS.or = new BinaryOp(true, true) { + new BinaryOp('|', true, true) { - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - return Constant.forIntegerKind(a.getKind(), a.asLong() | b.asLong()); - } + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + return Constant.forIntegerKind(a.getKind(), a.asLong() | b.asLong()); + } - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - IntegerStamp a = (IntegerStamp) stamp1; - IntegerStamp b = (IntegerStamp) stamp2; - assert a.getBits() == b.getBits(); - return stampForMask(a.getBits(), a.downMask() | b.downMask(), a.upMask() | b.upMask()); - } + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + IntegerStamp a = (IntegerStamp) stamp1; + IntegerStamp b = (IntegerStamp) stamp2; + assert a.getBits() == b.getBits(); + return stampForMask(a.getBits(), a.downMask() | b.downMask(), a.upMask() | b.upMask()); + } - @Override - public boolean isNeutral(Constant n) { - return n.asLong() == 0; - } - }; - - OPS.xor = new BinaryOp(true, true) { + @Override + public boolean isNeutral(Constant n) { + return n.asLong() == 0; + } + }, - @Override - public Constant foldConstant(Constant a, Constant b) { - assert a.getKind() == b.getKind(); - return Constant.forIntegerKind(a.getKind(), a.asLong() ^ b.asLong()); - } + new BinaryOp('^', true, true) { - @Override - public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { - IntegerStamp a = (IntegerStamp) stamp1; - IntegerStamp b = (IntegerStamp) stamp2; - assert a.getBits() == b.getBits(); + @Override + public Constant foldConstant(Constant a, Constant b) { + assert a.getKind() == b.getKind(); + return Constant.forIntegerKind(a.getKind(), a.asLong() ^ b.asLong()); + } - long variableBits = (a.downMask() ^ a.upMask()) | (b.downMask() ^ b.upMask()); - long newDownMask = (a.downMask() ^ b.downMask()) & ~variableBits; - long newUpMask = (a.downMask() ^ b.downMask()) | variableBits; - return stampForMask(a.getBits(), newDownMask, newUpMask); - } + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + IntegerStamp a = (IntegerStamp) stamp1; + IntegerStamp b = (IntegerStamp) stamp2; + assert a.getBits() == b.getBits(); + + long variableBits = (a.downMask() ^ a.upMask()) | (b.downMask() ^ b.upMask()); + long newDownMask = (a.downMask() ^ b.downMask()) & ~variableBits; + long newUpMask = (a.downMask() ^ b.downMask()) | variableBits; + return stampForMask(a.getBits(), newDownMask, newUpMask); + } - @Override - public boolean isNeutral(Constant n) { - return n.asLong() == 0; - } + @Override + public boolean isNeutral(Constant n) { + return n.asLong() == 0; + } - @Override - public Constant getZero(Stamp s) { - IntegerStamp stamp = (IntegerStamp) s; - return Constant.forPrimitiveInt(stamp.getBits(), 0); - } - }; - } + @Override + public Constant getZero(Stamp s) { + IntegerStamp stamp = (IntegerStamp) s; + return Constant.forPrimitiveInt(stamp.getBits(), 0); + } + }); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java Fri Oct 03 13:48:58 2014 +0200 @@ -115,8 +115,4 @@ public Constant asConstant() { return null; } - - public final Stamp asStamp() { - return this; - } } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java --- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Fri Oct 03 13:48:58 2014 +0200 @@ -62,12 +62,6 @@ } @Override - public boolean canStoreConstant(Constant c) { - // Operand b must be in the .reg state space. - return false; - } - - @Override public boolean canInlineConstant(Constant c) { switch (c.getKind()) { case Long: @@ -79,13 +73,6 @@ } } - @Override - public Variable emitMove(Value input) { - Variable result = newVariable(input.getLIRKind()); - emitMove(result, input); - return result; - } - protected HSAILLIRInstruction createMove(AllocatableValue dst, Value src) { if (src instanceof HSAILAddressValue) { return new LeaOp(dst, (HSAILAddressValue) src); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Fri Oct 03 13:48:58 2014 +0200 @@ -93,12 +93,6 @@ } @Override - public boolean canStoreConstant(Constant c) { - // Operand b must be in the .reg state space. - return false; - } - - @Override public boolean canInlineConstant(Constant c) { switch (c.getKind()) { case Long: @@ -131,13 +125,6 @@ } @Override - public Variable emitMove(Value input) { - Variable result = newVariable(input.getLIRKind()); - emitMove(result, input); - return result; - } - - @Override public void emitMove(AllocatableValue dst, Value src) { if (isRegister(src) || isStackSlot(dst)) { append(new MoveFromRegOp(dst, src)); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Fri Oct 03 13:48:58 2014 +0200 @@ -83,18 +83,6 @@ } @Override - public boolean canStoreConstant(Constant c) { - // SPARC can only store integer null constants (via g0) - switch (c.getKind()) { - case Float: - case Double: - return false; - default: - return c.isDefaultForKind(); - } - } - - @Override public boolean canInlineConstant(Constant c) { switch (c.getKind()) { case Int: @@ -108,13 +96,6 @@ } } - @Override - public Variable emitMove(Value input) { - Variable result = newVariable(input.getLIRKind()); - emitMove(result, input); - return result; - } - protected SPARCLIRInstruction createMove(AllocatableValue dst, Value src) { if (src instanceof SPARCAddressValue) { return new LoadAddressOp(dst, (SPARCAddressValue) src); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Fri Oct 03 13:48:58 2014 +0200 @@ -185,7 +185,7 @@ */ private static void checkClass(Class c, MetaAccessProvider metaAccess) { if (Node.class.isAssignableFrom(c)) { - if (c.getAnnotation(GeneratedNode.class) == null) { + if (!GeneratedNode.class.isAssignableFrom(c)) { if (Modifier.isFinal(c.getModifiers())) { throw new AssertionError(String.format("Node subclass %s must not be final", c.getName())); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NodePosIteratorTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NodePosIteratorTest.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NodePosIteratorTest.java Fri Oct 03 13:48:58 2014 +0200 @@ -44,6 +44,10 @@ public static TestNode create() { return USE_GENERATED_NODES ? new NodePosIteratorTest_TestNodeGen() : new TestNode(); } + + protected TestNode() { + // TODO Auto-generated constructor stub + } } @Test diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Fri Oct 03 13:48:58 2014 +0200 @@ -79,16 +79,12 @@ } } - private ValueProcedure collectStatsProc = new ValueProcedure() { - - @Override - public Value doValue(Value value) { - if (ValueUtil.isRegister(value)) { - final Register reg = ValueUtil.asRegister(value); - registers.add(reg); - } - return value; + private ValueProcedure collectStatsProc = (value, mode, flags) -> { + if (ValueUtil.isRegister(value)) { + final Register reg = ValueUtil.asRegister(value); + registers.add(reg); } + return value; }; private void collectStats(final LIRInstruction instr) { diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Fri Oct 03 13:48:58 2014 +0200 @@ -60,8 +60,6 @@ public static final OptionValue DebugValueSummary = new OptionValue<>("Name"); @Option(help = "Omit reporting 0-value metrics") public static final OptionValue SuppressZeroDebugValues = new OptionValue<>(false); - @Option(help = "Report and reset metrics after bootstrapping") - public static final OptionValue ResetDebugValuesAfterBootstrap = new OptionValue<>(true); @Option(help = "Send Graal IR to dump handlers on error") public static final OptionValue DumpOnError = new OptionValue<>(false); @Option(help = "Enable expensive assertions") diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Fri Oct 03 13:48:58 2014 +0200 @@ -612,13 +612,9 @@ intervalsSize = operandSize(); intervals = new Interval[intervalsSize + (intervalsSize >> SPLIT_INTERVALS_CAPACITY_RIGHT_SHIFT)]; - ValueConsumer setVariableConsumer = new ValueConsumer() { - - @Override - public void visitValue(Value value) { - if (isVariable(value)) { - getOrCreateInterval(asVariable(value)); - } + ValueConsumer setVariableConsumer = (value, mode, flags) -> { + if (isVariable(value)) { + getOrCreateInterval(asVariable(value)); } }; @@ -678,56 +674,44 @@ List instructions = ir.getLIRforBlock(block); int numInst = instructions.size(); - ValueConsumer useConsumer = new ValueConsumer() { - - @Override - protected void visitValue(Value operand) { - if (isVariable(operand)) { - int operandNum = operandNumber(operand); - if (!liveKill.get(operandNum)) { - liveGen.set(operandNum); - Debug.log("liveGen for operand %d", operandNum); - } - if (block.getLoop() != null) { - intervalInLoop.setBit(operandNum, block.getLoop().getIndex()); - } - } - - if (DetailedAsserts.getValue()) { - verifyInput(block, liveKill, operand); - } - } - }; - ValueConsumer stateConsumer = new ValueConsumer() { - - @Override - public void visitValue(Value operand) { + ValueConsumer useConsumer = (operand, mode, flags) -> { + if (isVariable(operand)) { int operandNum = operandNumber(operand); if (!liveKill.get(operandNum)) { liveGen.set(operandNum); - Debug.log("liveGen in state for operand %d", operandNum); + Debug.log("liveGen for operand %d", operandNum); + } + if (block.getLoop() != null) { + intervalInLoop.setBit(operandNum, block.getLoop().getIndex()); } } + + if (DetailedAsserts.getValue()) { + verifyInput(block, liveKill, operand); + } }; - ValueConsumer defConsumer = new ValueConsumer() { + ValueConsumer stateConsumer = (operand, mode, flags) -> { + int operandNum = operandNumber(operand); + if (!liveKill.get(operandNum)) { + liveGen.set(operandNum); + Debug.log("liveGen in state for operand %d", operandNum); + } + }; + ValueConsumer defConsumer = (operand, mode, flags) -> { + if (isVariable(operand)) { + int varNum = operandNumber(operand); + liveKill.set(varNum); + Debug.log("liveKill for operand %d", varNum); + if (block.getLoop() != null) { + intervalInLoop.setBit(varNum, block.getLoop().getIndex()); + } + } - @Override - public void visitValue(Value operand) { - if (isVariable(operand)) { - int varNum = operandNumber(operand); - liveKill.set(varNum); - Debug.log("liveKill for operand %d", varNum); - if (block.getLoop() != null) { - intervalInLoop.setBit(varNum, block.getLoop().getIndex()); - } - } - - if (DetailedAsserts.getValue()) { - // fixed intervals are never live at block boundaries, so - // they need not be processed in live sets - // process them only in debug mode so that this can be checked - verifyTemp(liveKill, operand); - } + if (DetailedAsserts.getValue()) { + // fixed intervals are never live at block boundaries, so + // they need not be processed in live sets + // process them only in debug mode so that this can be checked + verifyTemp(liveKill, operand); } }; @@ -923,13 +907,9 @@ try (Indent indent3 = Debug.logAndIndent("used in block B%d", block.getId())) { for (LIRInstruction ins : ir.getLIRforBlock(block)) { try (Indent indent4 = Debug.logAndIndent("%d: %s", ins.id(), ins)) { - ins.forEachState(new ValueProcedure() { - - @Override - public Value doValue(Value liveStateOperand) { - Debug.log("operand=%s", liveStateOperand); - return liveStateOperand; - } + ins.forEachState((liveStateOperand, mode, flags) -> { + Debug.log("operand=%s", liveStateOperand); + return liveStateOperand; }); } } @@ -1124,26 +1104,22 @@ void addRegisterHint(final LIRInstruction op, final Value targetValue, OperandMode mode, EnumSet flags, final boolean hintAtDef) { if (flags.contains(OperandFlag.HINT) && isVariableOrRegister(targetValue)) { - op.forEachRegisterHint(targetValue, mode, new ValueProcedure() { - - @Override - protected Value doValue(Value registerHint) { - if (isVariableOrRegister(registerHint)) { - Interval from = getOrCreateInterval((AllocatableValue) registerHint); - Interval to = getOrCreateInterval((AllocatableValue) targetValue); + op.forEachRegisterHint(targetValue, mode, (registerHint, valueMode, valueFlags) -> { + if (isVariableOrRegister(registerHint)) { + Interval from = getOrCreateInterval((AllocatableValue) registerHint); + Interval to = getOrCreateInterval((AllocatableValue) targetValue); - // hints always point from def to use - if (hintAtDef) { - to.setLocationHint(from); - } else { - from.setLocationHint(to); - } - Debug.log("operation at opId %d: added hint from interval %d to %d", op.id(), from.operandNumber, to.operandNumber); + /* hints always point from def to use */ + if (hintAtDef) { + to.setLocationHint(from); + } else { + from.setLocationHint(to); + } + Debug.log("operation at opId %d: added hint from interval %d to %d", op.id(), from.operandNumber, to.operandNumber); - return registerHint; - } - return null; + return registerHint; } + return null; }); } } @@ -1151,64 +1127,44 @@ void buildIntervals() { try (Indent indent = Debug.logAndIndent("build intervals")) { - InstructionValueConsumer outputConsumer = new InstructionValueConsumer() { - - @Override - public void visitValue(LIRInstruction op, Value operand, OperandMode mode, EnumSet flags) { - if (isVariableOrRegister(operand)) { - addDef((AllocatableValue) operand, op, registerPriorityOfOutputOperand(op), operand.getLIRKind()); - addRegisterHint(op, operand, mode, flags, true); - } + InstructionValueConsumer outputConsumer = (op, operand, mode, flags) -> { + if (isVariableOrRegister(operand)) { + addDef((AllocatableValue) operand, op, registerPriorityOfOutputOperand(op), operand.getLIRKind()); + addRegisterHint(op, operand, mode, flags, true); } }; - InstructionValueConsumer tempConsumer = new InstructionValueConsumer() { - - @Override - public void visitValue(LIRInstruction op, Value operand, OperandMode mode, EnumSet flags) { - if (isVariableOrRegister(operand)) { - addTemp((AllocatableValue) operand, op.id(), RegisterPriority.MustHaveRegister, operand.getLIRKind()); - addRegisterHint(op, operand, mode, flags, false); - } + InstructionValueConsumer tempConsumer = (op, operand, mode, flags) -> { + if (isVariableOrRegister(operand)) { + addTemp((AllocatableValue) operand, op.id(), RegisterPriority.MustHaveRegister, operand.getLIRKind()); + addRegisterHint(op, operand, mode, flags, false); } }; - InstructionValueConsumer aliveConsumer = new InstructionValueConsumer() { - - @Override - public void visitValue(LIRInstruction op, Value operand, OperandMode mode, EnumSet flags) { - if (isVariableOrRegister(operand)) { - RegisterPriority p = registerPriorityOfInputOperand(flags); - final int opId = op.id(); - final int blockFrom = getFirstLirInstructionId((blockForId(opId))); - addUse((AllocatableValue) operand, blockFrom, opId + 1, p, operand.getLIRKind()); - addRegisterHint(op, operand, mode, flags, false); - } + InstructionValueConsumer aliveConsumer = (op, operand, mode, flags) -> { + if (isVariableOrRegister(operand)) { + RegisterPriority p = registerPriorityOfInputOperand(flags); + int opId = op.id(); + int blockFrom = getFirstLirInstructionId((blockForId(opId))); + addUse((AllocatableValue) operand, blockFrom, opId + 1, p, operand.getLIRKind()); + addRegisterHint(op, operand, mode, flags, false); } }; - InstructionValueConsumer inputConsumer = new InstructionValueConsumer() { - - @Override - public void visitValue(LIRInstruction op, Value operand, OperandMode mode, EnumSet flags) { - if (isVariableOrRegister(operand)) { - final int opId = op.id(); - final int blockFrom = getFirstLirInstructionId((blockForId(opId))); - RegisterPriority p = registerPriorityOfInputOperand(flags); - addUse((AllocatableValue) operand, blockFrom, opId, p, operand.getLIRKind()); - addRegisterHint(op, operand, mode, flags, false); - } + InstructionValueConsumer inputConsumer = (op, operand, mode, flags) -> { + if (isVariableOrRegister(operand)) { + int opId = op.id(); + int blockFrom = getFirstLirInstructionId((blockForId(opId))); + RegisterPriority p = registerPriorityOfInputOperand(flags); + addUse((AllocatableValue) operand, blockFrom, opId, p, operand.getLIRKind()); + addRegisterHint(op, operand, mode, flags, false); } }; - InstructionValueConsumer stateProc = new InstructionValueConsumer() { - - @Override - public void visitValue(LIRInstruction op, Value operand) { - final int opId = op.id(); - final int blockFrom = getFirstLirInstructionId((blockForId(opId))); - addUse((AllocatableValue) operand, blockFrom, opId + 1, RegisterPriority.None, operand.getLIRKind()); - } + InstructionValueConsumer stateProc = (op, operand, mode, flags) -> { + int opId = op.id(); + int blockFrom = getFirstLirInstructionId((blockForId(opId))); + addUse((AllocatableValue) operand, blockFrom, opId + 1, RegisterPriority.None, operand.getLIRKind()); }; // create a list with all caller-save registers (cpu, fpu, xmm) @@ -1737,44 +1693,41 @@ return attributes(asRegister(operand)).isCallerSave(); } - private InstructionValueProcedure debugInfoProc = new InstructionValueProcedure() { - - @Override - public Value doValue(LIRInstruction op, Value operand) { - int tempOpId = op.id(); - OperandMode mode = OperandMode.USE; - AbstractBlock block = blockForId(tempOpId); - if (block.getSuccessorCount() == 1 && tempOpId == getLastLirInstructionId(block)) { - // generating debug information for the last instruction of a block. - // if this instruction is a branch, spill moves are inserted before this branch - // and so the wrong operand would be returned (spill moves at block boundaries - // are not - // considered in the live ranges of intervals) - // Solution: use the first opId of the branch target block instead. - final LIRInstruction instr = ir.getLIRforBlock(block).get(ir.getLIRforBlock(block).size() - 1); - if (instr instanceof StandardOp.JumpOp) { - if (blockData.get(block).liveOut.get(operandNumber(operand))) { - tempOpId = getFirstLirInstructionId(block.getSuccessors().iterator().next()); - mode = OperandMode.DEF; - } + @SuppressWarnings("unused") + private Value debugInfoProcedure(LIRInstruction op, Value operand, OperandMode valueMode, EnumSet flags) { + int tempOpId = op.id(); + OperandMode mode = OperandMode.USE; + AbstractBlock block = blockForId(tempOpId); + if (block.getSuccessorCount() == 1 && tempOpId == getLastLirInstructionId(block)) { + // generating debug information for the last instruction of a block. + // if this instruction is a branch, spill moves are inserted before this branch + // and so the wrong operand would be returned (spill moves at block boundaries + // are not + // considered in the live ranges of intervals) + // Solution: use the first opId of the branch target block instead. + final LIRInstruction instr = ir.getLIRforBlock(block).get(ir.getLIRforBlock(block).size() - 1); + if (instr instanceof StandardOp.JumpOp) { + if (blockData.get(block).liveOut.get(operandNumber(operand))) { + tempOpId = getFirstLirInstructionId(block.getSuccessors().iterator().next()); + mode = OperandMode.DEF; } } + } - // Get current location of operand - // The operand must be live because debug information is considered when building - // the intervals - // if the interval is not live, colorLirOperand will cause an assert on failure - Value result = colorLirOperand((Variable) operand, tempOpId, mode); - assert !hasCall(tempOpId) || isStackSlot(result) || isConstant(result) || !isCallerSave(result) : "cannot have caller-save register operands at calls"; - return result; - } - }; + // Get current location of operand + // The operand must be live because debug information is considered when building + // the intervals + // if the interval is not live, colorLirOperand will cause an assert on failure + Value result = colorLirOperand((Variable) operand, tempOpId, mode); + assert !hasCall(tempOpId) || isStackSlot(result) || isConstant(result) || !isCallerSave(result) : "cannot have caller-save register operands at calls"; + return result; + } private void computeDebugInfo(IntervalWalker iw, final LIRInstruction op, LIRFrameState info) { info.initDebugInfo(frameMap, !op.destroysCallerSavedRegisters() || !callKillsRegisters); markFrameLocations(iw, op, info); - info.forEachState(op, debugInfoProc); + info.forEachState(op, this::debugInfoProcedure); info.finish(op, frameMap); } @@ -1782,23 +1735,8 @@ int numInst = instructions.size(); boolean hasDead = false; - InstructionValueProcedure assignProc = new InstructionValueProcedure() { - - @Override - public Value doValue(LIRInstruction op, Value operand, OperandMode mode, EnumSet flags) { - if (isVariable(operand)) { - return colorLirOperand((Variable) operand, op.id(), mode); - } - return operand; - } - }; - InstructionStateProcedure stateProc = new InstructionStateProcedure() { - - @Override - protected void doState(LIRInstruction op, LIRFrameState state) { - computeDebugInfo(iw, op, state); - } - }; + InstructionValueProcedure assignProc = (op, operand, mode, flags) -> isVariable(operand) ? colorLirOperand((Variable) operand, op.id(), mode) : operand; + InstructionStateProcedure stateProc = (op, state) -> computeDebugInfo(iw, op, state); for (int j = 0; j < numInst; j++) { final LIRInstruction op = instructions.get(j); @@ -2208,13 +2146,13 @@ } } - class CheckConsumer extends ValueConsumer { + class CheckConsumer implements ValueConsumer { boolean ok; Interval curInterval; @Override - protected void visitValue(Value operand) { + public void visitValue(Value operand, OperandMode mode, EnumSet flags) { if (isRegister(operand)) { if (intervalFor(operand) == curInterval) { ok = true; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java Fri Oct 03 13:48:58 2014 +0200 @@ -202,18 +202,14 @@ } }; - InstructionValueConsumer defConsumer = new InstructionValueConsumer() { + InstructionValueConsumer defConsumer = (op, operand, mode, flags) -> { + if (LinearScan.isVariableOrRegister(operand) && allocator.isProcessed(operand)) { + Interval interval = intervalAt(operand); + if (op.id() != -1) { + interval = interval.getSplitChildAtOpId(op.id(), mode, allocator); + } - @Override - public void visitValue(LIRInstruction op, Value operand, OperandMode mode, EnumSet flags) { - if (LinearScan.isVariableOrRegister(operand) && allocator.isProcessed(operand)) { - Interval interval = intervalAt(operand); - if (op.id() != -1) { - interval = interval.getSplitChildAtOpId(op.id(), mode, allocator); - } - - statePut(inputState, interval.location(), interval.splitParent()); - } + statePut(inputState, interval.location(), interval.splitParent()); } }; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchContext.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchContext.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchContext.java Fri Oct 03 13:48:58 2014 +0200 @@ -126,8 +126,10 @@ */ public void setResult(ComplexMatchResult result) { ComplexMatchValue value = new ComplexMatchValue(result); - Debug.log("matched %s %s", rule.getName(), rule.getPattern()); - Debug.log("with nodes %s", rule.formatMatch(root)); + if (Debug.isLogEnabled()) { + Debug.log("matched %s %s", rule.getName(), rule.getPattern()); + Debug.log("with nodes %s", rule.formatMatch(root)); + } if (consumed != null) { for (ValueNode node : consumed) { // All the interior nodes should be skipped during the normal doRoot calls in diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeMapTest.java --- a/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeMapTest.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeMapTest.java Fri Oct 03 13:48:58 2014 +0200 @@ -34,7 +34,7 @@ @NodeInfo static class TestNode extends Node { - TestNode() { + protected TestNode() { } public static TestNode create() { diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeUsagesTests.java --- a/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeUsagesTests.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeUsagesTests.java Fri Oct 03 13:48:58 2014 +0200 @@ -35,6 +35,10 @@ @NodeInfo static class Def extends Node { + protected Def() { + // TODO Auto-generated constructor stub + } + public static Def create() { return USE_GENERATED_NODES ? new NodeUsagesTests_DefGen() : new Def(); } @@ -50,7 +54,7 @@ return USE_GENERATED_NODES ? new NodeUsagesTests_UseGen(in0, in1, in2) : new Use(in0, in1, in2); } - Use(Def in0, Def in1, Def in2) { + protected Use(Def in0, Def in1, Def in2) { this.in0 = in0; this.in1 = in1; this.in2 = in2; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/TypedNodeIteratorTest.java --- a/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/TypedNodeIteratorTest.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/TypedNodeIteratorTest.java Fri Oct 03 13:48:58 2014 +0200 @@ -36,13 +36,13 @@ @NodeInfo static class TestNode extends Node implements IterableNodeType, TestNodeInterface { - private final String name; + protected final String name; public static TestNode create(String name) { return USE_GENERATED_NODES ? new TypedNodeIteratorTest_TestNodeGen(name) : new TestNode(name); } - TestNode(String name) { + protected TestNode(String name) { this.name = name; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/TypedNodeIteratorTest2.java --- a/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/TypedNodeIteratorTest2.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/TypedNodeIteratorTest2.java Fri Oct 03 13:48:58 2014 +0200 @@ -34,13 +34,13 @@ @NodeInfo static class NodeA extends Node implements TestNodeInterface { - private final String name; + protected final String name; public static NodeA create(String name) { return USE_GENERATED_NODES ? new TypedNodeIteratorTest2_NodeAGen(name) : new NodeA(name); } - NodeA(String name) { + protected NodeA(String name) { this.name = name; } @@ -56,7 +56,7 @@ return USE_GENERATED_NODES ? new TypedNodeIteratorTest2_NodeBGen(name) : new NodeB(name); } - NodeB(String name) { + protected NodeB(String name) { super(name); } } @@ -67,7 +67,7 @@ return USE_GENERATED_NODES ? new TypedNodeIteratorTest2_NodeCGen(name) : new NodeC(name); } - NodeC(String name) { + protected NodeC(String name) { super(name); } } @@ -78,7 +78,7 @@ return USE_GENERATED_NODES ? new TypedNodeIteratorTest2_NodeDGen(name) : new NodeD(name); } - NodeD(String name) { + protected NodeD(String name) { super(name); } } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Edges.java Fri Oct 03 13:48:58 2014 +0200 @@ -28,7 +28,9 @@ import java.util.*; +import com.oracle.graal.compiler.common.FieldIntrospection.FieldInfo; import com.oracle.graal.compiler.common.*; +import com.oracle.graal.graph.NodeClass.EdgeInfo; /** * Describes {@link Node} fields representing the set of inputs for the node or the set of the @@ -47,12 +49,18 @@ private final int directCount; private final Type type; - public Edges(Class nodeClass, Type type, int directCount, long[] offsets, Map names, Map> types) { - super(nodeClass, offsets, names, types); + public Edges(Type type, int directCount, ArrayList edges) { + super(edges); this.type = type; this.directCount = directCount; } + public static void translateInto(Edges edges, ArrayList infos) { + for (int index = 0; index < edges.getCount(); index++) { + infos.add(new EdgeInfo(edges.offsets[index], edges.getName(index), edges.getType(index))); + } + } + private static Node getNode(Node node, long offset) { return (Node) unsafe.getObject(node, offset); } @@ -134,7 +142,7 @@ * @param toNode the node to which the edges should be copied. */ public void copy(Node fromNode, Node toNode) { - assert fromNode.getNodeClass().getClazz() == clazz && toNode.getNodeClass().getClazz() == clazz; + assert fromNode.getNodeClass().getClazz() == toNode.getNodeClass().getClazz(); int index = 0; while (index < getDirectCount()) { initializeNode(toNode, index, getNode(fromNode, index)); @@ -169,7 +177,7 @@ } while (index < getCount()) { NodeList list = getNodeList(node, index); - assert list != null : clazz; + assert list != null : this; if (list.replaceFirst(key, replacement)) { return true; } @@ -235,7 +243,7 @@ * Determines if the edges of two given nodes are the same. */ public boolean areEqualIn(Node node, Node other) { - assert node.getNodeClass().getClazz() == clazz && other.getNodeClass().getClazz() == clazz; + assert node.getNodeClass().getClazz() == other.getNodeClass().getClazz(); int index = 0; while (index < directCount) { if (getNode(other, index) != getNode(node, index)) { @@ -445,9 +453,4 @@ public Type type() { return type; } - - @Override - public String toString() { - return super.toString() + ":" + type; - } } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Fri Oct 03 13:48:58 2014 +0200 @@ -78,7 +78,12 @@ int compressions; NodeEventListener nodeEventListener; - private final HashMap cachedNodes = new HashMap<>(); + + /** + * Used to global value number {@link ValueNumberable} {@linkplain NodeClass#isLeafNode() leaf} + * nodes. + */ + private final HashMap cachedLeafNodes = new HashMap<>(); /* * Indicates that the graph should no longer be modified. Frozen graphs can be used my multiple @@ -86,19 +91,22 @@ */ private boolean isFrozen = false; + /** + * Entry in {@link Graph#cachedLeafNodes}. + */ private static final class CacheEntry { private final Node node; public CacheEntry(Node node) { assert node.getNodeClass().valueNumberable(); - assert node.isLeafNode(); + assert node.getNodeClass().isLeafNode(); this.node = node; } @Override public int hashCode() { - return node.getNodeClass().valueNumber(node); + return Node.USE_GENERATED_NODES ? node.valueNumberLeaf() : node.getNodeClass().valueNumber(node); } @Override @@ -108,9 +116,8 @@ } if (obj instanceof CacheEntry) { CacheEntry other = (CacheEntry) obj; - NodeClass nodeClass = node.getNodeClass(); if (other.node.getClass() == node.getClass()) { - return nodeClass.valueEqual(node, other.node); + return node.valueEquals(other.node); } } return false; @@ -447,7 +454,7 @@ return (T) other; } else { Node result = addIfMissing ? addHelper(node) : node; - if (node.isLeafNode()) { + if (node.getNodeClass().isLeafNode()) { putNodeIntoCache(result); } return (T) result; @@ -457,15 +464,15 @@ void putNodeIntoCache(Node node) { assert node.graph() == this || node.graph() == null; assert node.getNodeClass().valueNumberable(); - assert node.isLeafNode() : node.getClass(); - cachedNodes.put(new CacheEntry(node), node); + assert node.getNodeClass().isLeafNode() : node.getClass(); + cachedLeafNodes.put(new CacheEntry(node), node); } Node findNodeInCache(Node node) { CacheEntry key = new CacheEntry(node); - Node result = cachedNodes.get(key); + Node result = cachedLeafNodes.get(key); if (result != null && result.isDeleted()) { - cachedNodes.remove(key); + cachedLeafNodes.remove(key); return null; } return result; @@ -474,7 +481,8 @@ public Node findDuplicate(Node node) { NodeClass nodeClass = node.getNodeClass(); assert nodeClass.valueNumberable(); - if (node.isLeafNode()) { + if (nodeClass.isLeafNode()) { + // Leaf node: look up in cache Node cachedNode = findNodeInCache(node); if (cachedNode != null) { return cachedNode; @@ -482,6 +490,10 @@ return null; } } else { + // Non-leaf node: look for another usage of the node's inputs that + // has the same data, inputs and successors as the node. To reduce + // the cost of this computation, only the input with estimated highest + // usage count is considered. int minCount = Integer.MAX_VALUE; Node minCountNode = null; @@ -498,7 +510,7 @@ } if (minCountNode != null) { for (Node usage : minCountNode.usages()) { - if (usage != node && nodeClass == usage.getNodeClass() && nodeClass.valueEqual(node, usage) && nodeClass.getEdges(Inputs).areEqualIn(node, usage) && + if (usage != node && nodeClass == usage.getNodeClass() && node.valueEquals(usage) && nodeClass.getEdges(Inputs).areEqualIn(node, usage) && nodeClass.getEdges(Successors).areEqualIn(node, usage)) { return usage; } @@ -611,7 +623,7 @@ return new PlaceHolderNode(); } - PlaceHolderNode() { + protected PlaceHolderNode() { } } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/InputEdges.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/InputEdges.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/InputEdges.java Fri Oct 03 13:48:58 2014 +0200 @@ -26,6 +26,7 @@ import java.util.*; +import com.oracle.graal.graph.NodeClass.InputInfo; import com.oracle.graal.nodeinfo.*; public final class InputEdges extends Edges { @@ -33,14 +34,20 @@ private final InputType[] inputTypes; private final boolean[] isOptional; - public InputEdges(Class nodeClass, int directCount, long[] offsets, Map names, Map> types, Map inputTypes, Set isOptional) { - super(nodeClass, Inputs, directCount, offsets, names, types); + public InputEdges(int directCount, ArrayList edges) { + super(Inputs, directCount, edges); - this.inputTypes = new InputType[offsets.length]; - this.isOptional = new boolean[offsets.length]; - for (int i = 0; i < offsets.length; i++) { - this.inputTypes[i] = inputTypes.get(offsets[i]); - this.isOptional[i] = isOptional.contains(offsets[i]); + this.inputTypes = new InputType[edges.size()]; + this.isOptional = new boolean[edges.size()]; + for (int i = 0; i < edges.size(); i++) { + this.inputTypes[i] = edges.get(i).inputType; + this.isOptional[i] = edges.get(i).optional; + } + } + + public static void translateInto(InputEdges inputs, ArrayList infos) { + for (int index = 0; index < inputs.getCount(); index++) { + infos.add(new InputInfo(inputs.offsets[index], inputs.getName(index), inputs.getType(index), inputs.inputTypes[index], inputs.isOptional(index))); } } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Fri Oct 03 13:48:58 2014 +0200 @@ -143,6 +143,14 @@ boolean setStampFromReturnType() default false; } + /** + * Marker for a node that can be replaced by another node via global value numbering. A + * {@linkplain NodeClass#isLeafNode() leaf} node can be replaced by another node of the same + * type that has exactly the same {@linkplain NodeClass#getData() data} values. A non-leaf node + * can be replaced by another node of the same type that has exactly the same data values as + * well as the same {@linkplain Node#inputs() inputs} and {@linkplain Node#successors() + * successors}. + */ public interface ValueNumberable { } @@ -170,8 +178,7 @@ public static final int NOT_ITERABLE = -1; public Node() { - assert USE_GENERATED_NODES == (getClass().getAnnotation(GeneratedNode.class) != null) : getClass() + " is not a generated Node class - forgot @" + NodeInfo.class.getSimpleName() + - " on class declaration?"; + assert USE_GENERATED_NODES == this instanceof GeneratedNode : getClass() + " is not a generated Node class - forgot @" + NodeInfo.class.getSimpleName() + " on class declaration?"; init(); } @@ -740,7 +747,7 @@ final Node clone(Graph into, boolean clearInputsAndSuccessors) { NodeClass nodeClass = getNodeClass(); - if (into != null && nodeClass.valueNumberable() && isLeafNode()) { + if (into != null && nodeClass.valueNumberable() && nodeClass.isLeafNode()) { Node otherNode = into.findNodeInCache(this); if (otherNode != null) { return otherNode; @@ -768,20 +775,13 @@ newNode.extraUsages = NO_NODES; newNode.predecessor = null; - if (into != null && nodeClass.valueNumberable() && isLeafNode()) { + if (into != null && nodeClass.valueNumberable() && nodeClass.isLeafNode()) { into.putNodeIntoCache(newNode); } newNode.afterClone(this); return newNode; } - /** - * @returns true if this node has no inputs and no successors - */ - public boolean isLeafNode() { - return USE_GENERATED_NODES || getNodeClass().isLeafNode(); - } - protected void afterClone(@SuppressWarnings("unused") Node other) { } @@ -885,7 +885,7 @@ */ public Map getDebugProperties(Map map) { NodeClass nodeClass = getNodeClass(); - Fields properties = nodeClass.getProperties(); + Fields properties = nodeClass.getData(); for (int i = 0; i < properties.getCount(); i++) { map.put(properties.getName(i), properties.get(this, i)); } @@ -995,4 +995,38 @@ } } } + + /** + * If this node is a {@linkplain NodeClass#isLeafNode() leaf} node, returns a hash for this node + * based on its {@linkplain NodeClass#getData() data} fields otherwise return 0. + * + * Overridden by a method generated for leaf nodes. + */ + protected int valueNumberLeaf() { + assert !getNodeClass().isLeafNode(); + return 0; + } + + /** + * Overridden by a generated method. + * + * @param other + */ + protected boolean dataEquals(Node other) { + return true; + } + + /** + * Determines if this node's {@link NodeClass#getData() data} fields are equal to the data + * fields of another node of the same type. Primitive fields are compared by value and + * non-primitive fields are compared by {@link Objects#equals(Object, Object)}. + * + * The result of this method undefined if {@code other.getClass() != this.getClass()}. + * + * @param other a node of exactly the same type as this node + * @return true if the data fields of this object and {@code other} are equal + */ + public boolean valueEquals(Node other) { + return USE_GENERATED_NODES ? dataEquals(other) : getNodeClass().dataEquals(this, other); + } } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Oct 03 13:48:58 2014 +0200 @@ -22,16 +22,21 @@ */ package com.oracle.graal.graph; +import static com.oracle.graal.compiler.common.Fields.*; +import static com.oracle.graal.graph.Edges.*; +import static com.oracle.graal.graph.InputEdges.*; import static com.oracle.graal.graph.Node.*; import static com.oracle.graal.graph.util.CollectionsAccess.*; import static java.lang.reflect.Modifier.*; +import java.lang.annotation.*; import java.lang.reflect.*; import java.util.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.internal.*; +import com.oracle.graal.graph.Edges.Type; import com.oracle.graal.graph.Graph.DuplicationReplacement; import com.oracle.graal.graph.Node.Input; import com.oracle.graal.graph.Node.Successor; @@ -53,12 +58,19 @@ // Timers for creation of a NodeClass instance private static final DebugTimer Init = Debug.timer("NodeClass.Init"); private static final DebugTimer Init_FieldScanning = Debug.timer("NodeClass.Init.FieldScanning"); + private static final DebugTimer Init_FieldScanningInner = Debug.timer("NodeClass.Init.FieldScanning.Inner"); + private static final DebugTimer Init_AnnotationParsing = Debug.timer("NodeClass.Init.AnnotationParsing"); private static final DebugTimer Init_Edges = Debug.timer("NodeClass.Init.Edges"); private static final DebugTimer Init_Data = Debug.timer("NodeClass.Init.Data"); - private static final DebugTimer Init_Naming = Debug.timer("NodeClass.Init.Naming"); private static final DebugTimer Init_AllowedUsages = Debug.timer("NodeClass.Init.AllowedUsages"); private static final DebugTimer Init_IterableIds = Debug.timer("NodeClass.Init.IterableIds"); + private static T getAnnotationTimed(AnnotatedElement e, Class annotationClass) { + try (TimerCloseable s = Init_AnnotationParsing.start()) { + return e.getAnnotation(annotationClass); + } + } + /** * Gets the {@link NodeClass} associated with a given {@link Class}. */ @@ -76,9 +88,9 @@ try (TimerCloseable t = Init.start()) { value = (NodeClass) allClasses.get(key); if (value == null) { - GeneratedNode gen = c.getAnnotation(GeneratedNode.class); - if (gen != null) { - Class originalNodeClass = (Class) gen.value(); + Class superclass = c.getSuperclass(); + if (GeneratedNode.class.isAssignableFrom(c)) { + Class originalNodeClass = (Class) superclass; value = (NodeClass) allClasses.get(originalNodeClass); assert value != null; if (value.genClass == null) { @@ -87,12 +99,12 @@ assert value.genClass == c; } } else { - Class superclass = c.getSuperclass(); + NodeClass superNodeClass = null; if (superclass != NODE_CLASS) { // Ensure NodeClass for superclass exists - get(superclass); + superNodeClass = get(superclass); } - value = new NodeClass(key); + value = new NodeClass(key, superNodeClass); } Object old = allClasses.putIfAbsent(key, value); assert old == null : old + " " + key; @@ -109,13 +121,12 @@ private static int nextIterableId = 0; - private final Edges inputs; - private final Edges successors; - private final Fields properties; + private final InputEdges inputs; + private final SuccessorEdges successors; + private final NodeClass superNodeClass; private final boolean canGVN; private final int startGVNNumber; - private final String shortName; private final String nameTemplate; private final int iterableId; private final EnumSet allowedUsageTypes; @@ -142,19 +153,13 @@ private final boolean isSimplifiable; private final boolean isLeafNode; - public NodeClass(Class clazz) { - this(clazz, new DefaultCalcOffset(), null, 0); + public NodeClass(Class clazz, NodeClass superNodeClass) { + this(clazz, superNodeClass, new DefaultCalcOffset(), null, 0); } - private static long[] sortedOffsets(ArrayList list1, ArrayList list2) { - if (list1.isEmpty() && list2.isEmpty()) { - return new long[0]; - } - return sortedLongCopy(list1, list2); - } - - public NodeClass(Class clazz, CalcOffset calcOffset, int[] presetIterableIds, int presetIterableId) { + public NodeClass(Class clazz, NodeClass superNodeClass, CalcOffset calcOffset, int[] presetIterableIds, int presetIterableId) { super(clazz); + this.superNodeClass = superNodeClass; assert NODE_CLASS.isAssignableFrom(clazz); this.isCanonicalizable = Canonicalizable.class.isAssignableFrom(clazz); @@ -164,58 +169,32 @@ this.isSimplifiable = Simplifiable.class.isAssignableFrom(clazz); - FieldScanner fs = new FieldScanner(calcOffset); + FieldScanner fs = new FieldScanner(calcOffset, superNodeClass); try (TimerCloseable t = Init_FieldScanning.start()) { - fs.scan(clazz); + fs.scan(clazz, false); } try (TimerCloseable t1 = Init_Edges.start()) { - successors = new SuccessorEdges(clazz, fs.successorOffsets.size(), sortedOffsets(fs.successorOffsets, fs.successorListOffsets), fs.fieldNames, fs.fieldTypes); - inputs = new InputEdges(clazz, fs.inputOffsets.size(), sortedOffsets(fs.inputOffsets, fs.inputListOffsets), fs.fieldNames, fs.fieldTypes, fs.types, fs.optionalInputs); + successors = new SuccessorEdges(fs.directSuccessors, fs.successors); + inputs = new InputEdges(fs.directInputs, fs.inputs); } try (TimerCloseable t1 = Init_Data.start()) { - properties = new Fields(clazz, sortedLongCopy(fs.dataOffsets), fs.fieldNames, fs.fieldTypes); + data = new Fields(fs.data); } isLeafNode = inputs.getCount() + successors.getCount() == 0; - fieldNames = fs.fieldNames; - fieldTypes = fs.fieldTypes; canGVN = Node.ValueNumberable.class.isAssignableFrom(clazz); startGVNNumber = clazz.hashCode(); - String newNameTemplate = null; - String newShortName; - try (TimerCloseable t1 = Init_Naming.start()) { - newShortName = clazz.getSimpleName(); - if (newShortName.endsWith("Node") && !newShortName.equals("StartNode") && !newShortName.equals("EndNode")) { - newShortName = newShortName.substring(0, newShortName.length() - 4); - } - NodeInfo info = clazz.getAnnotation(NodeInfo.class); - assert info != null : "missing " + NodeInfo.class.getSimpleName() + " annotation on " + clazz; - if (!info.shortName().isEmpty()) { - newShortName = info.shortName(); - } - if (!info.nameTemplate().isEmpty()) { - newNameTemplate = info.nameTemplate(); - } + NodeInfo info = getAnnotationTimed(clazz, NodeInfo.class); + this.nameTemplate = info.nameTemplate(); + + try (TimerCloseable t1 = Init_AllowedUsages.start()) { + allowedUsageTypes = superNodeClass == null ? EnumSet.noneOf(InputType.class) : superNodeClass.allowedUsageTypes.clone(); + allowedUsageTypes.addAll(Arrays.asList(info.allowedUsageTypes())); } - EnumSet newAllowedUsageTypes = EnumSet.noneOf(InputType.class); - try (TimerCloseable t1 = Init_AllowedUsages.start()) { - Class current = clazz; - do { - NodeInfo currentInfo = current.getAnnotation(NodeInfo.class); - if (currentInfo != null) { - if (currentInfo.allowedUsageTypes().length > 0) { - newAllowedUsageTypes.addAll(Arrays.asList(currentInfo.allowedUsageTypes())); - } - } - current = current.getSuperclass(); - } while (current != Node.class); - } - this.nameTemplate = newNameTemplate == null ? newShortName : newNameTemplate; - this.allowedUsageTypes = newAllowedUsageTypes; - this.shortName = newShortName; + if (presetIterableIds != null) { this.iterableIds = presetIterableIds; this.iterableId = presetIterableId; @@ -224,15 +203,12 @@ try (TimerCloseable t1 = Init_IterableIds.start()) { this.iterableId = nextIterableId++; - Class superclass = clazz.getSuperclass(); - while (superclass != NODE_CLASS) { - if (IterableNodeType.class.isAssignableFrom(superclass)) { - NodeClass superNodeClass = NodeClass.get(superclass); - assert !containsId(this.iterableId, superNodeClass.iterableIds); - superNodeClass.iterableIds = Arrays.copyOf(superNodeClass.iterableIds, superNodeClass.iterableIds.length + 1); - superNodeClass.iterableIds[superNodeClass.iterableIds.length - 1] = this.iterableId; - } - superclass = superclass.getSuperclass(); + NodeClass snc = superNodeClass; + while (snc != null && IterableNodeType.class.isAssignableFrom(snc.getClazz())) { + assert !containsId(this.iterableId, snc.iterableIds); + snc.iterableIds = Arrays.copyOf(snc.iterableIds, snc.iterableIds.length + 1); + snc.iterableIds[snc.iterableIds.length - 1] = this.iterableId; + snc = snc.superNodeClass; } this.iterableIds = new int[]{iterableId}; @@ -241,7 +217,7 @@ this.iterableId = Node.NOT_ITERABLE; this.iterableIds = null; } - nodeIterableCount = Debug.metric("NodeIterable_%s", shortName); + nodeIterableCount = Debug.metric("NodeIterable_%s", clazz); } /** @@ -284,7 +260,7 @@ * *
      *     if (node.getNodeClass().is(BeginNode.class)) { ... }
-     * 
+     *
      *     // Due to generated Node classes, the test below
      *     // is *not* the same as the test above:
      *     if (node.getClass() == BeginNode.class) { ... }
@@ -293,11 +269,24 @@
      * @param nodeClass a {@linkplain GeneratedNode non-generated} {@link Node} class
      */
     public boolean is(Class nodeClass) {
-        assert nodeClass.getAnnotation(GeneratedNode.class) == null : "cannot test NodeClas against generated " + nodeClass;
+        assert !GeneratedNode.class.isAssignableFrom(nodeClass) : "cannot test NodeClass against generated " + nodeClass;
         return nodeClass == getClazz();
     }
 
+    private String shortName;
+
     public String shortName() {
+        if (shortName == null) {
+            NodeInfo info = getClazz().getAnnotation(NodeInfo.class);
+            if (!info.shortName().isEmpty()) {
+                shortName = info.shortName();
+            } else {
+                shortName = getClazz().getSimpleName();
+                if (shortName.endsWith("Node") && !shortName.equals("StartNode") && !shortName.equals("EndNode")) {
+                    shortName = shortName.substring(0, shortName.length() - 4);
+                }
+            }
+        }
         return shortName;
     }
 
@@ -336,60 +325,117 @@
         return allowedUsageTypes;
     }
 
-    protected static class FieldScanner extends BaseFieldScanner {
+    /**
+     * Describes a field representing an input or successor edge in a node.
+     */
+    protected static class EdgeInfo extends FieldInfo {
+
+        public EdgeInfo(long offset, String name, Class type) {
+            super(offset, name, type);
+        }
 
-        public final ArrayList inputOffsets = new ArrayList<>();
-        public final ArrayList inputListOffsets = new ArrayList<>();
-        public final ArrayList successorOffsets = new ArrayList<>();
-        public final ArrayList successorListOffsets = new ArrayList<>();
-        public final HashMap types = new HashMap<>();
-        public final HashSet optionalInputs = new HashSet<>();
+        /**
+         * Sorts non-list edges before list edges.
+         */
+        @Override
+        public int compareTo(FieldInfo o) {
+            if (NodeList.class.isAssignableFrom(o.type)) {
+                if (!NodeList.class.isAssignableFrom(type)) {
+                    return -1;
+                }
+            } else {
+                if (NodeList.class.isAssignableFrom(type)) {
+                    return 1;
+                }
+            }
+            return super.compareTo(o);
+        }
+    }
 
-        protected FieldScanner(CalcOffset calc) {
-            super(calc);
+    /**
+     * Describes a field representing an {@linkplain Type#Inputs input} edge in a node.
+     */
+    protected static class InputInfo extends EdgeInfo {
+        final InputType inputType;
+        final boolean optional;
+
+        public InputInfo(long offset, String name, Class type, InputType inputType, boolean optional) {
+            super(offset, name, type);
+            this.inputType = inputType;
+            this.optional = optional;
         }
 
         @Override
-        protected void scanField(Field field, Class type, long offset) {
-            if (field.isAnnotationPresent(Node.Input.class) || field.isAnnotationPresent(Node.OptionalInput.class)) {
-                assert !field.isAnnotationPresent(Node.Successor.class) : "field cannot be both input and successor";
-                assert field.isAnnotationPresent(Node.Input.class) ^ field.isAnnotationPresent(Node.OptionalInput.class) : "inputs can either be optional or non-optional";
-                if (INPUT_LIST_CLASS.isAssignableFrom(type)) {
-                    // NodeInputList fields should not be final since they are
-                    // written (via Unsafe) in clearInputs()
-                    GraalInternalError.guarantee(!Modifier.isFinal(field.getModifiers()), "NodeInputList input field %s should not be final", field);
-                    GraalInternalError.guarantee(!Modifier.isPublic(field.getModifiers()), "NodeInputList input field %s should not be public", field);
-                    inputListOffsets.add(offset);
+        public String toString() {
+            return super.toString() + "{inputType=" + inputType + ", optional=" + optional + "}";
+        }
+    }
+
+    protected static class FieldScanner extends BaseFieldScanner {
+
+        public final ArrayList inputs = new ArrayList<>();
+        public final ArrayList successors = new ArrayList<>();
+        int directInputs;
+        int directSuccessors;
+
+        protected FieldScanner(CalcOffset calc, NodeClass superNodeClass) {
+            super(calc);
+            if (superNodeClass != null) {
+                translateInto(superNodeClass.inputs, inputs);
+                translateInto(superNodeClass.successors, successors);
+                translateInto(superNodeClass.data, data);
+                directInputs = superNodeClass.inputs.getDirectCount();
+                directSuccessors = superNodeClass.successors.getDirectCount();
+            }
+        }
+
+        @Override
+        protected void scanField(Field field, long offset) {
+            Input inputAnnotation = getAnnotationTimed(field, Node.Input.class);
+            OptionalInput optionalInputAnnotation = getAnnotationTimed(field, Node.OptionalInput.class);
+            Successor successorAnnotation = getAnnotationTimed(field, Successor.class);
+            try (TimerCloseable s = Init_FieldScanningInner.start()) {
+                Class type = field.getType();
+                int modifiers = field.getModifiers();
+
+                if (inputAnnotation != null || optionalInputAnnotation != null) {
+                    assert successorAnnotation == null : "field cannot be both input and successor";
+                    if (INPUT_LIST_CLASS.isAssignableFrom(type)) {
+                        // NodeInputList fields should not be final since they are
+                        // written (via Unsafe) in clearInputs()
+                        GraalInternalError.guarantee(!Modifier.isFinal(modifiers), "NodeInputList input field %s should not be final", field);
+                        GraalInternalError.guarantee(!Modifier.isPublic(modifiers), "NodeInputList input field %s should not be public", field);
+                    } else {
+                        GraalInternalError.guarantee(NODE_CLASS.isAssignableFrom(type) || type.isInterface(), "invalid input type: %s", type);
+                        GraalInternalError.guarantee(!Modifier.isFinal(modifiers), "Node input field %s should not be final", field);
+                        directInputs++;
+                    }
+                    InputType inputType;
+                    if (inputAnnotation != null) {
+                        assert optionalInputAnnotation == null : "inputs can either be optional or non-optional";
+                        inputType = inputAnnotation.value();
+                    } else {
+                        inputType = optionalInputAnnotation.value();
+                    }
+                    inputs.add(new InputInfo(offset, field.getName(), type, inputType, field.isAnnotationPresent(Node.OptionalInput.class)));
+                } else if (successorAnnotation != null) {
+                    if (SUCCESSOR_LIST_CLASS.isAssignableFrom(type)) {
+                        // NodeSuccessorList fields should not be final since they are
+                        // written (via Unsafe) in clearSuccessors()
+                        GraalInternalError.guarantee(!Modifier.isFinal(modifiers), "NodeSuccessorList successor field % should not be final", field);
+                        GraalInternalError.guarantee(!Modifier.isPublic(modifiers), "NodeSuccessorList successor field %s should not be public", field);
+                    } else {
+                        GraalInternalError.guarantee(NODE_CLASS.isAssignableFrom(type), "invalid successor type: %s", type);
+                        GraalInternalError.guarantee(!Modifier.isFinal(modifiers), "Node successor field %s should not be final", field);
+                        directSuccessors++;
+                    }
+                    successors.add(new EdgeInfo(offset, field.getName(), type));
                 } else {
-                    GraalInternalError.guarantee(NODE_CLASS.isAssignableFrom(type) || type.isInterface(), "invalid input type: %s", type);
-                    GraalInternalError.guarantee(!Modifier.isFinal(field.getModifiers()), "Node input field %s should not be final", field);
-                    inputOffsets.add(offset);
-                }
-                if (field.isAnnotationPresent(Node.Input.class)) {
-                    types.put(offset, field.getAnnotation(Node.Input.class).value());
-                } else {
-                    types.put(offset, field.getAnnotation(Node.OptionalInput.class).value());
+                    GraalInternalError.guarantee(!NODE_CLASS.isAssignableFrom(type) || field.getName().equals("Null"), "suspicious node field: %s", field);
+                    GraalInternalError.guarantee(!INPUT_LIST_CLASS.isAssignableFrom(type), "suspicious node input list field: %s", field);
+                    GraalInternalError.guarantee(!SUCCESSOR_LIST_CLASS.isAssignableFrom(type), "suspicious node successor list field: %s", field);
+                    data.add(new FieldInfo(offset, field.getName(), type));
                 }
-                if (field.isAnnotationPresent(Node.OptionalInput.class)) {
-                    optionalInputs.add(offset);
-                }
-            } else if (field.isAnnotationPresent(Node.Successor.class)) {
-                if (SUCCESSOR_LIST_CLASS.isAssignableFrom(type)) {
-                    // NodeSuccessorList fields should not be final since they are
-                    // written (via Unsafe) in clearSuccessors()
-                    GraalInternalError.guarantee(!Modifier.isFinal(field.getModifiers()), "NodeSuccessorList successor field % should not be final", field);
-                    GraalInternalError.guarantee(!Modifier.isPublic(field.getModifiers()), "NodeSuccessorList successor field %s should not be public", field);
-                    successorListOffsets.add(offset);
-                } else {
-                    GraalInternalError.guarantee(NODE_CLASS.isAssignableFrom(type), "invalid successor type: %s", type);
-                    GraalInternalError.guarantee(!Modifier.isFinal(field.getModifiers()), "Node successor field %s should not be final", field);
-                    successorOffsets.add(offset);
-                }
-            } else {
-                GraalInternalError.guarantee(!NODE_CLASS.isAssignableFrom(type) || field.getName().equals("Null"), "suspicious node field: %s", field);
-                GraalInternalError.guarantee(!INPUT_LIST_CLASS.isAssignableFrom(type), "suspicious node input list field: %s", field);
-                GraalInternalError.guarantee(!SUCCESSOR_LIST_CLASS.isAssignableFrom(type), "suspicious node successor list field: %s", field);
-                dataOffsets.add(offset);
             }
         }
     }
@@ -402,7 +448,7 @@
         str.append("] [");
         successors.appendFields(str);
         str.append("] [");
-        properties.appendFields(str);
+        data.appendFields(str);
         str.append("]");
         return str.toString();
     }
@@ -437,41 +483,41 @@
         int number = 0;
         if (canGVN) {
             number = startGVNNumber;
-            for (int i = 0; i < properties.getCount(); ++i) {
-                Class type = properties.getType(i);
+            for (int i = 0; i < data.getCount(); ++i) {
+                Class type = data.getType(i);
                 if (type.isPrimitive()) {
                     if (type == Integer.TYPE) {
-                        int intValue = properties.getInt(n, i);
+                        int intValue = data.getInt(n, i);
                         number += intValue;
                     } else if (type == Long.TYPE) {
-                        long longValue = properties.getLong(n, i);
+                        long longValue = data.getLong(n, i);
                         number += longValue ^ (longValue >>> 32);
                     } else if (type == Boolean.TYPE) {
-                        boolean booleanValue = properties.getBoolean(n, i);
+                        boolean booleanValue = data.getBoolean(n, i);
                         if (booleanValue) {
                             number += 7;
                         }
                     } else if (type == Float.TYPE) {
-                        float floatValue = properties.getFloat(n, i);
+                        float floatValue = data.getFloat(n, i);
                         number += Float.floatToRawIntBits(floatValue);
                     } else if (type == Double.TYPE) {
-                        double doubleValue = properties.getDouble(n, i);
+                        double doubleValue = data.getDouble(n, i);
                         long longValue = Double.doubleToRawLongBits(doubleValue);
                         number += longValue ^ (longValue >>> 32);
                     } else if (type == Short.TYPE) {
-                        short shortValue = properties.getShort(n, i);
+                        short shortValue = data.getShort(n, i);
                         number += shortValue;
                     } else if (type == Character.TYPE) {
-                        char charValue = properties.getChar(n, i);
+                        char charValue = data.getChar(n, i);
                         number += charValue;
                     } else if (type == Byte.TYPE) {
-                        byte byteValue = properties.getByte(n, i);
+                        byte byteValue = data.getByte(n, i);
                         number += byteValue;
                     } else {
                         assert false : "unhandled property type: " + type;
                     }
                 } else {
-                    Object o = properties.getObject(n, i);
+                    Object o = data.getObject(n, i);
                     number += deepHashCode0(o);
                 }
                 number *= 13;
@@ -507,58 +553,56 @@
         return eq;
     }
 
-    public boolean valueEqual(Node a, Node b) {
-        if (a.getClass() != b.getClass()) {
-            return a == b;
-        }
-        for (int i = 0; i < properties.getCount(); ++i) {
-            Class type = properties.getType(i);
+    public boolean dataEquals(Node a, Node b) {
+        assert a.getClass() == b.getClass();
+        for (int i = 0; i < data.getCount(); ++i) {
+            Class type = data.getType(i);
             if (type.isPrimitive()) {
                 if (type == Integer.TYPE) {
-                    int aInt = properties.getInt(a, i);
-                    int bInt = properties.getInt(b, i);
+                    int aInt = data.getInt(a, i);
+                    int bInt = data.getInt(b, i);
                     if (aInt != bInt) {
                         return false;
                     }
                 } else if (type == Boolean.TYPE) {
-                    boolean aBoolean = properties.getBoolean(a, i);
-                    boolean bBoolean = properties.getBoolean(b, i);
+                    boolean aBoolean = data.getBoolean(a, i);
+                    boolean bBoolean = data.getBoolean(b, i);
                     if (aBoolean != bBoolean) {
                         return false;
                     }
                 } else if (type == Long.TYPE) {
-                    long aLong = properties.getLong(a, i);
-                    long bLong = properties.getLong(b, i);
+                    long aLong = data.getLong(a, i);
+                    long bLong = data.getLong(b, i);
                     if (aLong != bLong) {
                         return false;
                     }
                 } else if (type == Float.TYPE) {
-                    float aFloat = properties.getFloat(a, i);
-                    float bFloat = properties.getFloat(b, i);
+                    float aFloat = data.getFloat(a, i);
+                    float bFloat = data.getFloat(b, i);
                     if (aFloat != bFloat) {
                         return false;
                     }
                 } else if (type == Double.TYPE) {
-                    double aDouble = properties.getDouble(a, i);
-                    double bDouble = properties.getDouble(b, i);
+                    double aDouble = data.getDouble(a, i);
+                    double bDouble = data.getDouble(b, i);
                     if (aDouble != bDouble) {
                         return false;
                     }
                 } else if (type == Short.TYPE) {
-                    short aShort = properties.getShort(a, i);
-                    short bShort = properties.getShort(b, i);
+                    short aShort = data.getShort(a, i);
+                    short bShort = data.getShort(b, i);
                     if (aShort != bShort) {
                         return false;
                     }
                 } else if (type == Character.TYPE) {
-                    char aChar = properties.getChar(a, i);
-                    char bChar = properties.getChar(b, i);
+                    char aChar = data.getChar(a, i);
+                    char bChar = data.getChar(b, i);
                     if (aChar != bChar) {
                         return false;
                     }
                 } else if (type == Byte.TYPE) {
-                    byte aByte = properties.getByte(a, i);
-                    byte bByte = properties.getByte(b, i);
+                    byte aByte = data.getByte(a, i);
+                    byte bByte = data.getByte(b, i);
                     if (aByte != bByte) {
                         return false;
                     }
@@ -566,8 +610,8 @@
                     assert false : "unhandled type: " + type;
                 }
             } else {
-                Object objectA = properties.getObject(a, i);
-                Object objectB = properties.getObject(b, i);
+                Object objectA = data.getObject(a, i);
+                Object objectB = data.getObject(b, i);
                 if (objectA != objectB) {
                     if (objectA != null && objectB != null) {
                         if (!deepEquals0(objectA, objectB)) {
@@ -596,13 +640,6 @@
         return toEdges.isSame(fromEdges, pos.getIndex());
     }
 
-    /**
-     * Gets the non-edge properties defined by this node class.
-     */
-    public Fields getProperties() {
-        return properties;
-    }
-
     static void updateEdgesInPlace(Node node, InplaceUpdateClosure duplicationReplacement, Edges edges) {
         int index = 0;
         while (index < edges.getDirectCount()) {
@@ -677,11 +714,11 @@
     }
 
     /**
-     * The template used to build the {@link Verbosity#Name} version. Variable part are specified
+     * The template used to build the {@link Verbosity#Name} version. Variable parts are specified
      * using {i#inputName} or {p#propertyName}.
      */
     public String getNameTemplate() {
-        return nameTemplate;
+        return nameTemplate.isEmpty() ? shortName() : nameTemplate;
     }
 
     interface InplaceUpdateClosure {
@@ -790,6 +827,9 @@
         }
     }
 
+    /**
+     * @returns true if the node has no inputs and no successors
+     */
     public boolean isLeafNode() {
         return isLeafNode;
     }
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/SuccessorEdges.java
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/SuccessorEdges.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/SuccessorEdges.java	Fri Oct 03 13:48:58 2014 +0200
@@ -26,10 +26,12 @@
 
 import java.util.*;
 
+import com.oracle.graal.graph.NodeClass.EdgeInfo;
+
 public final class SuccessorEdges extends Edges {
 
-    public SuccessorEdges(Class nodeClass, int directCount, long[] offsets, Map names, Map> types) {
-        super(nodeClass, Successors, directCount, offsets, names, types);
+    public SuccessorEdges(int directCount, ArrayList edges) {
+        super(Successors, directCount, edges);
     }
 
     @Override
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Fri Oct 03 13:48:58 2014 +0200
@@ -51,6 +51,7 @@
 import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp;
 import com.oracle.graal.lir.amd64.AMD64Move.StoreOp;
 import com.oracle.graal.lir.gen.*;
+import com.oracle.graal.phases.util.*;
 
 /**
  * LIR generator specialized for AMD64 HotSpot.
@@ -459,6 +460,28 @@
         return result;
     }
 
+    /**
+     * Checks whether the supplied constant can be used without loading it into a register for store
+     * operations, i.e., on the right hand side of a memory access.
+     *
+     * @param c The constant to check.
+     * @return True if the constant can be used directly, false if the constant needs to be in a
+     *         register.
+     */
+    protected boolean canStoreConstant(Constant c) {
+        // there is no immediate move of 64-bit constants on Intel
+        switch (c.getKind()) {
+            case Long:
+                return Util.isInt(c.asLong()) && !getCodeCache().needsDataPatch(c);
+            case Double:
+                return false;
+            case Object:
+                return c.isNull();
+            default:
+                return true;
+        }
+    }
+
     @Override
     public void emitStore(LIRKind kind, Value address, Value inputVal, LIRFrameState state) {
         AMD64AddressValue storeAddress = asAddressValue(address);
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64RawNativeCallNode.java
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64RawNativeCallNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64RawNativeCallNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -35,7 +35,7 @@
 @NodeInfo
 public class AMD64RawNativeCallNode extends FixedWithNextNode implements LIRLowerable {
 
-    private final Constant functionPointer;
+    protected final Constant functionPointer;
     @Input NodeInputList args;
 
     public static AMD64RawNativeCallNode create(Kind returnType, Constant functionPointer, ValueNode[] args) {
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Fri Oct 03 13:48:58 2014 +0200
@@ -93,8 +93,7 @@
         return config.narrowKlassBase;
     }
 
-    @Override
-    public boolean canStoreConstant(Constant c) {
+    private static boolean canStoreConstant(Constant c) {
         return !(c instanceof HotSpotObjectConstant);
     }
 
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILDirectStoreReleaseNode.java
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILDirectStoreReleaseNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILDirectStoreReleaseNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -45,8 +45,8 @@
     public void generate(NodeLIRBuilderTool gen) {
         HSAILHotSpotLIRGenerator hsailgen = (HSAILHotSpotLIRGenerator) (gen.getLIRGeneratorTool());
         Value v = gen.operand(getValue());
-        LIRKind kind = hsailgen.getLIRKind(getValue().stamp());
-        hsailgen.emitStoreRelease(kind, gen.operand(getAddress()), v, null);
+        LIRKind lirKind = hsailgen.getLIRKind(getValue().stamp());
+        hsailgen.emitStoreRelease(lirKind, gen.operand(getAddress()), v, null);
     }
 
     @NodeIntrinsic
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Fri Oct 03 13:48:58 2014 +0200
@@ -224,7 +224,7 @@
         return kernel;
     }
 
-    static final class RegisterAnalysis extends ValueConsumer {
+    static final class RegisterAnalysis implements ValueConsumer {
         private final SortedSet signed32 = new TreeSet<>();
         private final SortedSet signed64 = new TreeSet<>();
 
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Fri Oct 03 13:48:58 2014 +0200
@@ -25,8 +25,8 @@
 import static com.oracle.graal.api.code.CallingConvention.Type.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
+import static com.oracle.graal.compiler.common.UnsafeAccess.*;
 import static com.oracle.graal.sparc.SPARC.*;
-import static com.oracle.graal.compiler.common.UnsafeAccess.*;
 
 import java.util.*;
 
@@ -345,16 +345,13 @@
         private final Set inputs = new HashSet<>(10);
         private boolean overlap = false;
 
-        private final InstructionValueConsumer valueConsumer = new InstructionValueConsumer() {
-            @Override
-            protected void visitValue(LIRInstruction instruction, Value value) {
-                Object valueObject = value;
-                if (isRegister(value)) { // Canonicalize registers
-                    valueObject = asRegister(value);
-                }
-                if (!inputs.add(valueObject)) {
-                    overlap = true;
-                }
+        private final InstructionValueConsumer valueConsumer = (instruction, value, mode, flags) -> {
+            Object valueObject = value;
+            if (isRegister(value)) { // Canonicalize registers
+                valueObject = asRegister(value);
+            }
+            if (!inputs.add(valueObject)) {
+                overlap = true;
             }
         };
 
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Fri Oct 03 13:48:58 2014 +0200
@@ -191,6 +191,17 @@
         return result;
     }
 
+    private static boolean canStoreConstant(Constant c) {
+        // SPARC can only store integer null constants (via g0)
+        switch (c.getKind()) {
+            case Float:
+            case Double:
+                return false;
+            default:
+                return c.isDefaultForKind();
+        }
+    }
+
     @Override
     public void emitStore(LIRKind kind, Value address, Value inputVal, LIRFrameState state) {
         SPARCAddressValue storeAddress = asAddressValue(address);
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/DebugValuesPrinter.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/DebugValuesPrinter.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/DebugValuesPrinter.java	Fri Oct 03 13:48:58 2014 +0200
@@ -37,77 +37,65 @@
  */
 public class DebugValuesPrinter {
 
-    public void printDebugValues(String phase, boolean reset) throws GraalInternalError {
-        if (Debug.areUnconditionalMetricsEnabled() || Debug.areUnconditionalTimersEnabled() || (Debug.isEnabled() && areMetricsOrTimersEnabled())) {
-            TTY.println();
-            if (phase != null) {
-                TTY.println("");
-            } else {
-                TTY.println("");
-            }
-            List topLevelMaps = DebugValueMap.getTopLevelMaps();
-            List debugValues = KeyRegistry.getDebugValues();
-            if (debugValues.size() > 0) {
-                try {
-                    ArrayList sortedValues = new ArrayList<>(debugValues);
-                    Collections.sort(sortedValues);
+    public void printDebugValues() throws GraalInternalError {
+        TTY.println();
+        TTY.println("");
+        List topLevelMaps = DebugValueMap.getTopLevelMaps();
+        List debugValues = KeyRegistry.getDebugValues();
+        if (debugValues.size() > 0) {
+            try {
+                ArrayList sortedValues = new ArrayList<>(debugValues);
+                Collections.sort(sortedValues);
 
-                    String summary = DebugValueSummary.getValue();
-                    if (summary == null) {
-                        summary = "Complete";
-                    }
-                    switch (summary) {
-                        case "Name":
-                            printSummary(topLevelMaps, sortedValues);
-                            break;
-                        case "Partial": {
-                            DebugValueMap globalMap = new DebugValueMap("Global");
-                            for (DebugValueMap map : topLevelMaps) {
-                                flattenChildren(map, globalMap);
-                            }
-                            globalMap.normalize();
-                            printMap(new DebugValueScope(null, globalMap), sortedValues);
-                            break;
+                String summary = DebugValueSummary.getValue();
+                if (summary == null) {
+                    summary = "Complete";
+                }
+                switch (summary) {
+                    case "Name":
+                        printSummary(topLevelMaps, sortedValues);
+                        break;
+                    case "Partial": {
+                        DebugValueMap globalMap = new DebugValueMap("Global");
+                        for (DebugValueMap map : topLevelMaps) {
+                            flattenChildren(map, globalMap);
                         }
-                        case "Complete": {
-                            DebugValueMap globalMap = new DebugValueMap("Global");
-                            for (DebugValueMap map : topLevelMaps) {
-                                globalMap.addChild(map);
-                            }
-                            globalMap.group();
-                            globalMap.normalize();
-                            printMap(new DebugValueScope(null, globalMap), sortedValues);
-                            break;
+                        globalMap.normalize();
+                        printMap(new DebugValueScope(null, globalMap), sortedValues);
+                        break;
+                    }
+                    case "Complete": {
+                        DebugValueMap globalMap = new DebugValueMap("Global");
+                        for (DebugValueMap map : topLevelMaps) {
+                            globalMap.addChild(map);
                         }
-                        case "Thread":
-                            for (DebugValueMap map : topLevelMaps) {
-                                TTY.println("Showing the results for thread: " + map.getName());
-                                map.group();
-                                map.normalize();
-                                printMap(new DebugValueScope(null, map), sortedValues);
-                            }
-                            break;
-                        default:
-                            throw new GraalInternalError("Unknown summary type: %s", summary);
+                        globalMap.group();
+                        globalMap.normalize();
+                        printMap(new DebugValueScope(null, globalMap), sortedValues);
+                        break;
                     }
-                    if (reset) {
-                        for (DebugValueMap topLevelMap : topLevelMaps) {
-                            topLevelMap.reset();
+                    case "Thread":
+                        for (DebugValueMap map : topLevelMaps) {
+                            TTY.println("Showing the results for thread: " + map.getName());
+                            map.group();
+                            map.normalize();
+                            printMap(new DebugValueScope(null, map), sortedValues);
                         }
-                    }
-                } catch (Throwable e) {
-                    // Don't want this to change the exit status of the VM
-                    PrintStream err = System.err;
-                    err.println("Error while printing debug values:");
-                    e.printStackTrace();
+                        break;
+                    default:
+                        throw new GraalInternalError("Unknown summary type: %s", summary);
                 }
-            }
-            if (phase != null) {
-                TTY.println("");
-            } else {
-                TTY.println("");
+                for (DebugValueMap topLevelMap : topLevelMaps) {
+                    topLevelMap.reset();
+                }
+            } catch (Throwable e) {
+                // Don't want this to change the exit status of the VM
+                PrintStream err = System.err;
+                err.println("Error while printing debug values:");
+                e.printStackTrace();
             }
         }
+        TTY.println("");
     }
 
     private void flattenChildren(DebugValueMap map, DebugValueMap globalMap) {
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Fri Oct 03 13:48:58 2014 +0200
@@ -36,6 +36,8 @@
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.LIRInstruction.OperandFlag;
+import com.oracle.graal.lir.LIRInstruction.OperandMode;
 import com.oracle.graal.lir.StandardOp.LabelOp;
 import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
 import com.oracle.graal.nodes.*;
@@ -154,7 +156,7 @@
         ValueConsumer defConsumer = new ValueConsumer() {
 
             @Override
-            public void visitValue(Value value) {
+            public void visitValue(Value value, OperandMode mode, EnumSet flags) {
                 if (ValueUtil.isRegister(value)) {
                     final Register reg = ValueUtil.asRegister(value);
                     definedRegisters.add(reg);
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Fri Oct 03 13:48:58 2014 +0200
@@ -134,6 +134,12 @@
             }
         }
 
+        if (Debug.areUnconditionalMetricsEnabled() || Debug.areUnconditionalTimersEnabled() || (Debug.isEnabled() && areMetricsOrTimersEnabled())) {
+            // This must be created here to avoid loading the DebugValuesPrinter class
+            // during shutdown() which in turn can cause a deadlock
+            debugValuesPrinter = new DebugValuesPrinter();
+        }
+
         // Complete initialization of backends
         try (InitTimer st = timer(hostBackend.getTarget().arch.getName(), ".completeInitialization")) {
             hostBackend.completeInitialization();
@@ -247,6 +253,7 @@
 
     protected final HotSpotVMConfig config;
     private final HotSpotBackend hostBackend;
+    private DebugValuesPrinter debugValuesPrinter;
 
     /**
      * Graal mirrors are stored as a {@link ClassValue} associated with the {@link Class} of the
@@ -581,7 +588,9 @@
      */
     @SuppressWarnings("unused")
     private void shutdown() throws Exception {
-        new DebugValuesPrinter().printDebugValues(ResetDebugValuesAfterBootstrap.getValue() ? "application" : null, false);
+        if (debugValuesPrinter != null) {
+            debugValuesPrinter.printDebugValues();
+        }
         phaseTransition("final");
 
         SnippetCounter.printGroups(TTY.out().out());
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java	Fri Oct 03 13:48:58 2014 +0200
@@ -38,11 +38,11 @@
     }
 
     @Override
-    protected Value processValue(LIRInstruction inst, InstructionValueProcedureBase proc, Value value) {
+    protected Value processValue(LIRInstruction inst, InstructionValueProcedure proc, Value value) {
         if (value instanceof HotSpotMonitorValue) {
             HotSpotMonitorValue monitor = (HotSpotMonitorValue) value;
             if (processed(monitor.getOwner())) {
-                monitor.setOwner(proc.processValue(inst, monitor.getOwner(), OperandMode.ALIVE, STATE_FLAGS));
+                monitor.setOwner(proc.doValue(inst, monitor.getOwner(), OperandMode.ALIVE, STATE_FLAGS));
             }
             return value;
         } else {
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSection.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSection.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSection.java	Fri Oct 03 13:48:58 2014 +0200
@@ -56,6 +56,8 @@
         int patchCount = 0;
         List externalDataList = new ArrayList<>();
 
+        Map dataMap = new HashMap<>();
+
         // find all external data items and determine total size of data section
         for (Site site : sites) {
             if (site instanceof DataPatch) {
@@ -64,12 +66,16 @@
                 if (dataPatch.inline) {
                     assert d instanceof PatchedData : "unnecessary data patch";
                 } else {
-                    size = NumUtil.roundUp(size, d.getAlignment());
-                    size += d.getSize(target);
+                    Integer existingPos = dataMap.get(d);
+                    if (existingPos == null) {
+                        size = NumUtil.roundUp(size, d.getAlignment());
+                        size += d.getSize(target);
+                        if (d instanceof PatchedData) {
+                            patchCount++;
+                        }
+                        dataMap.put(d, externalDataList.size());
+                    }
                     externalDataList.add(dataPatch);
-                    if (d instanceof PatchedData) {
-                        patchCount++;
-                    }
                 }
             }
         }
@@ -82,23 +88,29 @@
         int alignment = 0;
 
         // build data section
-        for (DataPatch dataPatch : externalDataList) {
+        for (int i = 0; i < externalDataList.size(); i++) {
+            DataPatch dataPatch = externalDataList.get(i);
             assert !dataPatch.inline;
             Data d = dataPatch.data;
 
-            alignment = Math.max(alignment, d.getAlignment());
-            index = NumUtil.roundUp(index, d.getAlignment());
-            buffer.position(index);
+            Integer existingPos = dataMap.get(d);
+            if (existingPos == i) {
+                alignment = Math.max(alignment, d.getAlignment());
+                index = NumUtil.roundUp(index, d.getAlignment());
+                buffer.position(index);
 
-            DataSectionReference reference = new DataSectionReference(index);
-            if (d instanceof PatchedData) {
-                // record patch location
-                patches[patchIndex++] = new DataPatch(index, d, true);
+                DataSectionReference reference = new DataSectionReference(index);
+                if (d instanceof PatchedData) {
+                    // record patch location
+                    patches[patchIndex++] = new DataPatch(index, d, true);
+                }
+                dataPatch.data = reference;
+
+                index += d.getSize(target);
+                d.emit(target, buffer);
+            } else {
+                dataPatch.data = externalDataList.get(existingPos).data;
             }
-            dataPatch.data = reference;
-
-            index += d.getSize(target);
-            d.emit(target, buffer);
         }
 
         this.sectionAlignment = alignment;
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/AllocaNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/AllocaNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/AllocaNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -42,14 +42,14 @@
     /**
      * The number of slots in block.
      */
-    private final int slots;
+    protected final int slots;
 
     /**
      * The indexes of the object pointer slots in the block. Each such object pointer slot must be
      * initialized before any safepoint in the method otherwise the garbage collector will see
      * garbage values when processing these slots.
      */
-    private final BitSet objects;
+    protected final BitSet objects;
 
     public static AllocaNode create(int slots, BitSet objects) {
         return USE_GENERATED_NODES ? new AllocaNodeGen(slots, objects) : new AllocaNode(slots, objects);
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -40,13 +40,13 @@
 @NodeInfo(allowedUsageTypes = {InputType.Memory})
 public class BeginLockScopeNode extends AbstractMemoryCheckpoint implements LIRLowerable, MonitorEnter, MemoryCheckpoint.Single {
 
-    private int lockDepth;
+    protected int lockDepth;
 
     public static BeginLockScopeNode create(int lockDepth) {
         return USE_GENERATED_NODES ? new BeginLockScopeNodeGen(lockDepth) : new BeginLockScopeNode(lockDepth);
     }
 
-    BeginLockScopeNode(int lockDepth) {
+    protected BeginLockScopeNode(int lockDepth) {
         super(null);
         this.lockDepth = lockDepth;
     }
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -34,13 +34,13 @@
 @NodeInfo
 public class CStringNode extends FloatingNode implements LIRLowerable {
 
-    private final String string;
+    protected final String string;
 
     public static CStringNode create(String string) {
         return USE_GENERATED_NODES ? new CStringNodeGen(string) : new CStringNode(string);
     }
 
-    CStringNode(String string) {
+    protected CStringNode(String string) {
         super(null);
         this.string = string;
     }
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -47,14 +47,14 @@
         Uncompress
     }
 
-    private final CompressionOp op;
-    private final CompressEncoding encoding;
+    protected final CompressionOp op;
+    protected final CompressEncoding encoding;
 
     public static CompressionNode create(CompressionOp op, ValueNode input, CompressEncoding encoding) {
         return USE_GENERATED_NODES ? new CompressionNodeGen(op, input, encoding) : new CompressionNode(op, input, encoding);
     }
 
-    CompressionNode(CompressionOp op, ValueNode input, CompressEncoding encoding) {
+    protected CompressionNode(CompressionOp op, ValueNode input, CompressEncoding encoding) {
         super(mkStamp(op, input.stamp(), encoding), input);
         this.op = op;
         this.encoding = encoding;
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -40,13 +40,13 @@
 @NodeInfo
 public class CurrentJavaThreadNode extends FloatingNode implements LIRLowerable {
 
-    private LIRKind wordKind;
+    protected LIRKind wordKind;
 
     public static CurrentJavaThreadNode create(Kind kind) {
         return USE_GENERATED_NODES ? new CurrentJavaThreadNodeGen(kind) : new CurrentJavaThreadNode(kind);
     }
 
-    CurrentJavaThreadNode(Kind kind) {
+    protected CurrentJavaThreadNode(Kind kind) {
         super(StampFactory.forKind(kind));
         this.wordKind = LIRKind.value(kind);
     }
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentLockNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentLockNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentLockNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -36,13 +36,13 @@
 @NodeInfo
 public class CurrentLockNode extends FixedWithNextNode implements LIRLowerable {
 
-    private int lockDepth;
+    protected int lockDepth;
 
     public static CurrentLockNode create(int lockDepth) {
         return USE_GENERATED_NODES ? new CurrentLockNodeGen(lockDepth) : new CurrentLockNode(lockDepth);
     }
 
-    CurrentLockNode(int lockDepth) {
+    protected CurrentLockNode(int lockDepth) {
         super(null);
         this.lockDepth = lockDepth;
     }
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -42,7 +42,7 @@
 public class DeoptimizationFetchUnrollInfoCallNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Multi {
 
     @Input SaveAllRegistersNode registerSaver;
-    private final ForeignCallsProvider foreignCalls;
+    protected final ForeignCallsProvider foreignCalls;
 
     public static DeoptimizationFetchUnrollInfoCallNode create(@InjectedNodeParameter ForeignCallsProvider foreignCalls, ValueNode registerSaver) {
         return USE_GENERATED_NODES ? new DeoptimizationFetchUnrollInfoCallNodeGen(foreignCalls, registerSaver) : new DeoptimizationFetchUnrollInfoCallNode(foreignCalls, registerSaver);
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizeCallerNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizeCallerNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizeCallerNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -35,8 +35,8 @@
 @NodeInfo(shortName = "DeoptCaller", nameTemplate = "DeoptCaller {p#reason/s}")
 public class DeoptimizeCallerNode extends ControlSinkNode implements LIRLowerable {
 
-    private final DeoptimizationAction action;
-    private final DeoptimizationReason reason;
+    protected final DeoptimizationAction action;
+    protected final DeoptimizationReason reason;
 
     public static DeoptimizeCallerNode create(DeoptimizationAction action, DeoptimizationReason reason) {
         return USE_GENERATED_NODES ? new DeoptimizeCallerNodeGen(action, reason) : new DeoptimizeCallerNode(action, reason);
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -41,13 +41,13 @@
 @NodeInfo
 public class DimensionsNode extends FixedWithNextNode implements LIRLowerable {
 
-    private final int rank;
+    protected final int rank;
 
     public static DimensionsNode create(int rank) {
         return USE_GENERATED_NODES ? new DimensionsNodeGen(rank) : new DimensionsNode(rank);
     }
 
-    DimensionsNode(int rank) {
+    protected DimensionsNode(int rank) {
         super(null);
         this.rank = rank;
     }
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -45,7 +45,7 @@
     @Input ValueNode expectedValue;
     @Input ValueNode newValue;
 
-    private final LocationIdentity locationIdentity;
+    protected final LocationIdentity locationIdentity;
 
     public static DirectCompareAndSwapNode create(ValueNode object, ValueNode offset, ValueNode expected, ValueNode newValue, LocationIdentity locationIdentity) {
         return USE_GENERATED_NODES ? new DirectCompareAndSwapNodeGen(object, offset, expected, newValue, locationIdentity) : new DirectCompareAndSwapNode(object, offset, expected, newValue,
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PostWriteBarrier.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PostWriteBarrier.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PostWriteBarrier.java	Fri Oct 03 13:48:58 2014 +0200
@@ -29,7 +29,7 @@
 @NodeInfo
 public class G1PostWriteBarrier extends WriteBarrier {
 
-    private final boolean alwaysNull;
+    protected final boolean alwaysNull;
 
     public static G1PostWriteBarrier create(ValueNode object, ValueNode value, LocationNode location, boolean precise, boolean alwaysNull) {
         return USE_GENERATED_NODES ? new G1PostWriteBarrierGen(object, value, location, precise, alwaysNull) : new G1PostWriteBarrier(object, value, location, precise, alwaysNull);
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java	Fri Oct 03 13:48:58 2014 +0200
@@ -30,8 +30,8 @@
 public class G1PreWriteBarrier extends WriteBarrier implements DeoptimizingNode.DeoptBefore {
 
     @OptionalInput(InputType.State) FrameState stateBefore;
-    private final boolean nullCheck;
-    private final boolean doLoad;
+    protected final boolean nullCheck;
+    protected final boolean doLoad;
 
     public static G1PreWriteBarrier create(ValueNode object, ValueNode expectedObject, LocationNode location, boolean doLoad, boolean nullCheck) {
         return USE_GENERATED_NODES ? new G1PreWriteBarrierGen(object, expectedObject, location, doLoad, nullCheck) : new G1PreWriteBarrier(object, expectedObject, location, doLoad, nullCheck);
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1ReferentFieldReadBarrier.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1ReferentFieldReadBarrier.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1ReferentFieldReadBarrier.java	Fri Oct 03 13:48:58 2014 +0200
@@ -35,7 +35,7 @@
 @NodeInfo
 public class G1ReferentFieldReadBarrier extends WriteBarrier {
 
-    private final boolean doLoad;
+    protected final boolean doLoad;
 
     public static G1ReferentFieldReadBarrier create(ValueNode object, ValueNode expectedObject, LocationNode location, boolean doLoad) {
         return USE_GENERATED_NODES ? new G1ReferentFieldReadBarrierGen(object, expectedObject, location, doLoad) : new G1ReferentFieldReadBarrier(object, expectedObject, location, doLoad);
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -41,7 +41,7 @@
         return USE_GENERATED_NODES ? new MonitorCounterNodeGen() : new MonitorCounterNode();
     }
 
-    MonitorCounterNode() {
+    protected MonitorCounterNode() {
         super(null);
     }
 
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java	Fri Oct 03 13:48:58 2014 +0200
@@ -44,7 +44,7 @@
 
     @Input ValueNode hub;
     @Input ValueNode dims;
-    private final int rank;
+    protected final int rank;
 
     public static NewMultiArrayStubCall create(@InjectedNodeParameter ForeignCallsProvider foreignCalls, ValueNode hub, int rank, ValueNode dims) {
         return USE_GENERATED_NODES ? new NewMultiArrayStubCallGen(foreignCalls, hub, rank, dims) : new NewMultiArrayStubCall(foreignCalls, hub, rank, dims);
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SaveAllRegistersNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SaveAllRegistersNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SaveAllRegistersNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -37,7 +37,7 @@
 @NodeInfo(allowedUsageTypes = {InputType.Memory})
 public class SaveAllRegistersNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Single {
 
-    private SaveRegistersOp saveRegistersOp;
+    protected SaveRegistersOp saveRegistersOp;
 
     public static SaveAllRegistersNode create() {
         return USE_GENERATED_NODES ? new SaveAllRegistersNodeGen() : new SaveAllRegistersNode();
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SerialWriteBarrier.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SerialWriteBarrier.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SerialWriteBarrier.java	Fri Oct 03 13:48:58 2014 +0200
@@ -29,7 +29,7 @@
 @NodeInfo
 public class SerialWriteBarrier extends WriteBarrier {
 
-    private final boolean alwaysNull;
+    protected final boolean alwaysNull;
 
     public static SerialWriteBarrier create(ValueNode object, LocationNode location, boolean precise, boolean alwaysNull) {
         return USE_GENERATED_NODES ? new SerialWriteBarrierGen(object, location, precise, alwaysNull) : new SerialWriteBarrier(object, location, precise, alwaysNull);
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -41,9 +41,9 @@
 public class StubForeignCallNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Multi {
 
     @Input NodeInputList arguments;
-    private final ForeignCallsProvider foreignCalls;
+    protected final ForeignCallsProvider foreignCalls;
 
-    private final ForeignCallDescriptor descriptor;
+    protected final ForeignCallDescriptor descriptor;
 
     public static StubForeignCallNode create(@InjectedNodeParameter ForeignCallsProvider foreignCalls, ForeignCallDescriptor descriptor, ValueNode... arguments) {
         return USE_GENERATED_NODES ? new StubForeignCallNodeGen(foreignCalls, descriptor, arguments) : new StubForeignCallNode(foreignCalls, descriptor, arguments);
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubStartNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubStartNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubStartNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -32,7 +32,7 @@
 @NodeInfo
 public class StubStartNode extends StartNode {
 
-    private final Stub stub;
+    protected final Stub stub;
 
     public static StubStartNode create(Stub stub) {
         return USE_GENERATED_NODES ? new StubStartNodeGen(stub) : new StubStartNode(stub);
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/UncommonTrapCallNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/UncommonTrapCallNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/UncommonTrapCallNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -43,7 +43,7 @@
 
     @Input ValueNode trapRequest;
     @Input SaveAllRegistersNode registerSaver;
-    private final ForeignCallsProvider foreignCalls;
+    protected final ForeignCallsProvider foreignCalls;
 
     public static UncommonTrapCallNode create(@InjectedNodeParameter ForeignCallsProvider foreignCalls, ValueNode registerSaver, ValueNode trapRequest) {
         return USE_GENERATED_NODES ? new UncommonTrapCallNodeGen(foreignCalls, registerSaver, trapRequest) : new UncommonTrapCallNode(foreignCalls, registerSaver, trapRequest);
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -40,7 +40,7 @@
 @NodeInfo
 public class VMErrorNode extends DeoptimizingStubCall implements LIRLowerable {
 
-    private final String format;
+    protected final String format;
     @Input ValueNode value;
 
     public static VMErrorNode create(String format, ValueNode value) {
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java	Fri Oct 03 13:48:58 2014 +0200
@@ -34,7 +34,7 @@
     @Input protected ValueNode object;
     @OptionalInput protected ValueNode value;
     @OptionalInput(InputType.Association) protected LocationNode location;
-    private final boolean precise;
+    protected final boolean precise;
 
     public WriteBarrier(ValueNode object, ValueNode value, LocationNode location, boolean precise) {
         super(StampFactory.forVoid());
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyCallNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyCallNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyCallNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -49,14 +49,14 @@
     @Input ValueNode destPos;
     @Input ValueNode length;
 
-    private Kind elementKind;
+    protected Kind elementKind;
 
     /**
      * Aligned means that the offset of the copy is heap word aligned.
      */
-    private boolean aligned;
-    private boolean disjoint;
-    private boolean uninitialized;
+    protected boolean aligned;
+    protected boolean disjoint;
+    protected boolean uninitialized;
 
     public static ArrayCopyCallNode create(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, Kind elementKind, boolean aligned, boolean disjoint,
                     boolean uninitialized) {
@@ -64,7 +64,7 @@
                         length, elementKind, aligned, disjoint, uninitialized);
     }
 
-    ArrayCopyCallNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, Kind elementKind, boolean aligned, boolean disjoint, boolean uninitialized) {
+    protected ArrayCopyCallNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, Kind elementKind, boolean aligned, boolean disjoint, boolean uninitialized) {
         super(StampFactory.forVoid());
         assert elementKind != null;
         this.src = src;
@@ -83,7 +83,7 @@
                         disjoint);
     }
 
-    ArrayCopyCallNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, Kind elementKind, boolean disjoint) {
+    protected ArrayCopyCallNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, Kind elementKind, boolean disjoint) {
         this(src, srcPos, dest, destPos, length, elementKind, false, disjoint, false);
     }
 
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -49,11 +49,11 @@
 public class MethodHandleNode extends MacroStateSplitNode implements Simplifiable {
 
     /** The method that this node is representing. */
-    private final IntrinsicMethod intrinsicMethod;
+    protected final IntrinsicMethod intrinsicMethod;
 
     // Replacement method data
-    private ResolvedJavaMethod replacementTargetMethod;
-    private JavaType replacementReturnType;
+    protected ResolvedJavaMethod replacementTargetMethod;
+    protected JavaType replacementReturnType;
     @Input NodeInputList replacementArguments;
 
     public static MethodHandleNode create(Invoke invoke) {
@@ -171,11 +171,11 @@
      * Helper function to get the {@link InvokeNode} for the targetMethod of a
      * java.lang.invoke.MemberName.
      *
-     * @param targetMethod the target, already loaded from the member name node
+     * @param target the target, already loaded from the member name node
      * @return invoke node for the member name target
      */
-    private InvokeNode getTargetInvokeNode(ResolvedJavaMethod targetMethod) {
-        if (targetMethod == null) {
+    private InvokeNode getTargetInvokeNode(ResolvedJavaMethod target) {
+        if (target == null) {
             return null;
         }
 
@@ -183,19 +183,19 @@
         // involving class loaders. When we optimize a method handle invoke
         // to a direct call we must cast the receiver and arguments to its
         // actual types.
-        Signature signature = targetMethod.getSignature();
-        final boolean isStatic = targetMethod.isStatic();
+        Signature signature = target.getSignature();
+        final boolean isStatic = target.isStatic();
         final int receiverSkip = isStatic ? 0 : 1;
 
         // Cast receiver to its type.
         if (!isStatic) {
-            JavaType receiverType = targetMethod.getDeclaringClass();
+            JavaType receiverType = target.getDeclaringClass();
             maybeCastArgument(0, receiverType);
         }
 
         // Cast reference arguments to its type.
         for (int index = 0; index < signature.getParameterCount(false); index++) {
-            JavaType parameterType = signature.getParameterType(index, targetMethod.getDeclaringClass());
+            JavaType parameterType = signature.getParameterType(index, target.getDeclaringClass());
             maybeCastArgument(receiverSkip + index, parameterType);
         }
 
@@ -203,18 +203,18 @@
         if (intrinsicMethod == IntrinsicMethod.LINK_TO_VIRTUAL || intrinsicMethod == IntrinsicMethod.LINK_TO_INTERFACE) {
             ResolvedJavaType receiverType = StampTool.typeOrNull(getReceiver().stamp());
             if (receiverType != null) {
-                ResolvedJavaMethod concreteMethod = receiverType.findUniqueConcreteMethod(targetMethod);
+                ResolvedJavaMethod concreteMethod = receiverType.findUniqueConcreteMethod(target);
                 if (concreteMethod != null) {
                     return createTargetInvokeNode(concreteMethod);
                 }
             }
         }
 
-        if (targetMethod.canBeStaticallyBound()) {
-            return createTargetInvokeNode(targetMethod);
+        if (target.canBeStaticallyBound()) {
+            return createTargetInvokeNode(target);
         }
 
-        ResolvedJavaMethod concreteMethod = targetMethod.getDeclaringClass().findUniqueConcreteMethod(targetMethod);
+        ResolvedJavaMethod concreteMethod = target.getDeclaringClass().findUniqueConcreteMethod(target);
         if (concreteMethod != null) {
             return createTargetInvokeNode(concreteMethod);
         }
@@ -247,12 +247,12 @@
      * Creates an {@link InvokeNode} for the given target method. The {@link CallTargetNode} passed
      * to the InvokeNode is in fact a {@link SelfReplacingMethodCallTargetNode}.
      *
-     * @param targetMethod the method the be called
+     * @param target the method to be called
      * @return invoke node for the member name target
      */
-    private InvokeNode createTargetInvokeNode(ResolvedJavaMethod targetMethod) {
-        InvokeKind invokeKind = targetMethod.isStatic() ? InvokeKind.Static : InvokeKind.Special;
-        JavaType returnType = targetMethod.getSignature().getReturnType(null);
+    private InvokeNode createTargetInvokeNode(ResolvedJavaMethod target) {
+        InvokeKind targetInvokeKind = target.isStatic() ? InvokeKind.Static : InvokeKind.Special;
+        JavaType targetReturnType = target.getSignature().getReturnType(null);
 
         // MethodHandleLinkTo* nodes have a trailing MemberName argument which
         // needs to be popped.
@@ -275,10 +275,10 @@
         // If there is already replacement information, use that instead.
         MethodCallTargetNode callTarget;
         if (replacementTargetMethod == null) {
-            callTarget = SelfReplacingMethodCallTargetNode.create(invokeKind, targetMethod, targetArguments, returnType, getTargetMethod(), originalArguments, getReturnType());
+            callTarget = SelfReplacingMethodCallTargetNode.create(targetInvokeKind, target, targetArguments, targetReturnType, getTargetMethod(), originalArguments, getReturnType());
         } else {
             ValueNode[] args = replacementArguments.toArray(new ValueNode[replacementArguments.size()]);
-            callTarget = SelfReplacingMethodCallTargetNode.create(invokeKind, targetMethod, targetArguments, returnType, replacementTargetMethod, args, replacementReturnType);
+            callTarget = SelfReplacingMethodCallTargetNode.create(targetInvokeKind, target, targetArguments, targetReturnType, replacementTargetMethod, args, replacementReturnType);
         }
         graph().add(callTarget);
 
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopyNode.java
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopyNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopyNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -42,14 +42,14 @@
     @Input ValueNode length;
     @OptionalInput ValueNode layoutHelper;
 
-    private Kind elementKind;
+    protected Kind elementKind;
 
     public static UnsafeArrayCopyNode create(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode layoutHelper, Kind elementKind) {
         return USE_GENERATED_NODES ? new UnsafeArrayCopyNodeGen(src, srcPos, dest, destPos, length, layoutHelper, elementKind) : new UnsafeArrayCopyNode(src, srcPos, dest, destPos, length,
                         layoutHelper, elementKind);
     }
 
-    UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode layoutHelper, Kind elementKind) {
+    protected UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode layoutHelper, Kind elementKind) {
         super(StampFactory.forVoid());
         assert layoutHelper == null || elementKind == null;
         this.src = src;
@@ -65,7 +65,7 @@
         return USE_GENERATED_NODES ? new UnsafeArrayCopyNodeGen(src, srcPos, dest, destPos, length, elementKind) : new UnsafeArrayCopyNode(src, srcPos, dest, destPos, length, elementKind);
     }
 
-    UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, Kind elementKind) {
+    protected UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, Kind elementKind) {
         this(src, srcPos, dest, destPos, length, null, elementKind);
     }
 
@@ -73,7 +73,7 @@
         return USE_GENERATED_NODES ? new UnsafeArrayCopyNodeGen(src, srcPos, dest, destPos, length, layoutHelper) : new UnsafeArrayCopyNode(src, srcPos, dest, destPos, length, layoutHelper);
     }
 
-    UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode layoutHelper) {
+    protected UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode layoutHelper) {
         this(src, srcPos, dest, destPos, length, layoutHelper, null);
     }
 
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Oct 03 13:48:58 2014 +0200
@@ -108,7 +108,7 @@
              * the !NODE_CLASS.isAssignableFrom(type) guarantee in
              * NodeClass.FieldScanner.scanField() to fail.
              */
-            private final Object nextPlaceholder;
+            protected final Object nextPlaceholder;
 
             public static BlockPlaceholderNode create(BytecodeParser builder) {
                 return USE_GENERATED_NODES ? new GraphBuilderPhase_Instance_BlockPlaceholderNodeGen(builder) : new BlockPlaceholderNode(builder);
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest1.java
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest1.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest1.java	Fri Oct 03 13:48:58 2014 +0200
@@ -126,35 +126,18 @@
         LIRInstruction op1 = new TestOp(compValue1);
         LIRInstruction op2 = new TestOp(compValue1);
 
-        op1.forEachInput(new InstructionValueProcedure() {
-            @Override
-            public Value doValue(LIRInstruction instruction, Value value) {
-                assertEquals(dummyValue1, value);
-                return dummyValue2;
-            }
+        op1.forEachInput((instruction, value, mode, flags) -> {
+            assertEquals(dummyValue1, value);
+            return dummyValue2;
         });
 
-        op2.forEachInput(new InstructionValueProcedure() {
-            @Override
-            public Value doValue(LIRInstruction instruction, Value value) {
-                assertEquals(dummyValue1, value);
-                return dummyValue3;
-            }
+        op2.forEachInput((instruction, value, mode, flags) -> {
+            assertEquals(dummyValue1, value);
+            return dummyValue3;
         });
 
-        op1.visitEachInput(new InstructionValueConsumer() {
-            @Override
-            public void visitValue(LIRInstruction instruction, Value value) {
-                assertEquals(dummyValue2, value);
-            }
-        });
-
-        op2.visitEachInput(new InstructionValueConsumer() {
-            @Override
-            public void visitValue(LIRInstruction instruction, Value value) {
-                assertEquals(dummyValue3, value);
-            }
-        });
+        op1.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue2, value));
+        op2.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue3, value));
     }
 
     @Test
@@ -166,34 +149,17 @@
         LIRInstruction op1 = new TestOp(compValue1);
         LIRInstruction op2 = new TestOp(compValue1);
 
-        op1.forEachInput(new InstructionValueProcedure() {
-            @Override
-            public Value doValue(LIRInstruction instruction, Value value) {
-                assertEquals(dummyValue1, value);
-                return dummyValue2;
-            }
-        });
-
-        op2.forEachInput(new InstructionValueProcedure() {
-            @Override
-            public Value doValue(LIRInstruction instruction, Value value) {
-                assertEquals(dummyValue1, value);
-                return dummyValue3;
-            }
+        op1.forEachInput((instruction, value, mode, flags) -> {
+            assertEquals(dummyValue1, value);
+            return dummyValue2;
         });
 
-        op1.visitEachInput(new InstructionValueConsumer() {
-            @Override
-            public void visitValue(LIRInstruction instruction, Value value) {
-                assertEquals(dummyValue2, value);
-            }
+        op2.forEachInput((instruction, value, mode, flags) -> {
+            assertEquals(dummyValue1, value);
+            return dummyValue3;
         });
 
-        op2.visitEachInput(new InstructionValueConsumer() {
-            @Override
-            public void visitValue(LIRInstruction instruction, Value value) {
-                assertEquals(dummyValue3, value);
-            }
-        });
+        op1.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue2, value));
+        op2.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue3, value));
     }
 }
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest2.java
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest2.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest2.java	Fri Oct 03 13:48:58 2014 +0200
@@ -127,35 +127,18 @@
         LIRInstruction op1 = new TestOp(compValue1);
         LIRInstruction op2 = new TestOp(compValue1);
 
-        op1.forEachInput(new InstructionValueProcedure() {
-            @Override
-            public Value doValue(LIRInstruction instruction, Value value) {
-                assertEquals(dummyValue1, value);
-                return dummyValue2;
-            }
+        op1.forEachInput((instruction, value, mode, flags) -> {
+            assertEquals(dummyValue1, value);
+            return dummyValue2;
         });
 
-        op2.forEachInput(new InstructionValueProcedure() {
-            @Override
-            public Value doValue(LIRInstruction instruction, Value value) {
-                assertEquals(dummyValue1, value);
-                return dummyValue3;
-            }
+        op2.forEachInput((instruction, value, mode, flags) -> {
+            assertEquals(dummyValue1, value);
+            return dummyValue3;
         });
 
-        op1.visitEachInput(new InstructionValueConsumer() {
-            @Override
-            public void visitValue(LIRInstruction instruction, Value value) {
-                assertEquals(dummyValue2, value);
-            }
-        });
-
-        op2.visitEachInput(new InstructionValueConsumer() {
-            @Override
-            public void visitValue(LIRInstruction instruction, Value value) {
-                assertEquals(dummyValue3, value);
-            }
-        });
+        op1.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue2, value));
+        op2.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue3, value));
     }
 
     @Test
@@ -167,34 +150,17 @@
         LIRInstruction op1 = new TestOp(compValue1);
         LIRInstruction op2 = new TestOp(compValue1);
 
-        op1.forEachInput(new InstructionValueProcedure() {
-            @Override
-            public Value doValue(LIRInstruction instruction, Value value) {
-                assertEquals(dummyValue1, value);
-                return dummyValue2;
-            }
-        });
-
-        op2.forEachInput(new InstructionValueProcedure() {
-            @Override
-            public Value doValue(LIRInstruction instruction, Value value) {
-                assertEquals(dummyValue1, value);
-                return dummyValue3;
-            }
+        op1.forEachInput((instruction, value, mode, flags) -> {
+            assertEquals(dummyValue1, value);
+            return dummyValue2;
         });
 
-        op1.visitEachInput(new InstructionValueConsumer() {
-            @Override
-            public void visitValue(LIRInstruction instruction, Value value) {
-                assertEquals(dummyValue2, value);
-            }
+        op2.forEachInput((instruction, value, mode, flags) -> {
+            assertEquals(dummyValue1, value);
+            return dummyValue3;
         });
 
-        op2.visitEachInput(new InstructionValueConsumer() {
-            @Override
-            public void visitValue(LIRInstruction instruction, Value value) {
-                assertEquals(dummyValue3, value);
-            }
-        });
+        op1.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue2, value));
+        op2.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue3, value));
     }
 }
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest3.java
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest3.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest3.java	Fri Oct 03 13:48:58 2014 +0200
@@ -127,39 +127,26 @@
         LIRInstruction op1 = new TestOp(compValue1);
         LIRInstruction op2 = new TestOp(compValue1);
 
-        op1.forEachInput(new ValuePositionProcedure() {
-
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                Value value = position.get(instruction);
-                assertEquals(dummyValue1, value);
-                position.set(instruction, dummyValue2);
-            }
+        op1.forEachInputPos((instruction, position) -> {
+            Value value = position.get(instruction);
+            assertEquals(dummyValue1, value);
+            position.set(instruction, dummyValue2);
         });
 
-        op2.forEachInput(new ValuePositionProcedure() {
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                Value value = position.get(instruction);
-                assertEquals(dummyValue1, value);
-                position.set(instruction, dummyValue3);
-            }
+        op2.forEachInputPos((instruction, position) -> {
+            Value value = position.get(instruction);
+            assertEquals(dummyValue1, value);
+            position.set(instruction, dummyValue3);
         });
 
-        op1.forEachInput(new ValuePositionProcedure() {
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                Value value = position.get(instruction);
-                assertEquals(dummyValue2, value);
-            }
+        op1.forEachInputPos((instruction, position) -> {
+            Value value = position.get(instruction);
+            assertEquals(dummyValue2, value);
         });
 
-        op2.forEachInput(new ValuePositionProcedure() {
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                Value value = position.get(instruction);
-                assertEquals(dummyValue3, value);
-            }
+        op2.forEachInputPos((instruction, position) -> {
+            Value value = position.get(instruction);
+            assertEquals(dummyValue3, value);
         });
     }
 
@@ -172,39 +159,26 @@
         LIRInstruction op1 = new TestOp(compValue1);
         LIRInstruction op2 = new TestOp(compValue1);
 
-        op1.forEachInput(new ValuePositionProcedure() {
-
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                Value value = position.get(instruction);
-                assertEquals(dummyValue1, value);
-                position.set(instruction, dummyValue2);
-            }
+        op1.forEachInputPos((instruction, position) -> {
+            Value value = position.get(instruction);
+            assertEquals(dummyValue1, value);
+            position.set(instruction, dummyValue2);
         });
 
-        op2.forEachInput(new ValuePositionProcedure() {
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                Value value = position.get(instruction);
-                assertEquals(dummyValue1, value);
-                position.set(instruction, dummyValue3);
-            }
+        op2.forEachInputPos((instruction, position) -> {
+            Value value = position.get(instruction);
+            assertEquals(dummyValue1, value);
+            position.set(instruction, dummyValue3);
         });
 
-        op1.forEachInput(new ValuePositionProcedure() {
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                Value value = position.get(instruction);
-                assertEquals(dummyValue2, value);
-            }
+        op1.forEachInputPos((instruction, position) -> {
+            Value value = position.get(instruction);
+            assertEquals(dummyValue2, value);
         });
 
-        op2.forEachInput(new ValuePositionProcedure() {
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                Value value = position.get(instruction);
-                assertEquals(dummyValue3, value);
-            }
+        op2.forEachInputPos((instruction, position) -> {
+            Value value = position.get(instruction);
+            assertEquals(dummyValue3, value);
         });
     }
 }
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest4.java
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest4.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest4.java	Fri Oct 03 13:48:58 2014 +0200
@@ -127,39 +127,26 @@
         LIRInstruction op1 = new TestOp(compValue1);
         LIRInstruction op2 = new TestOp(compValue1);
 
-        op1.forEachInput(new ValuePositionProcedure() {
-
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                Value value = position.get(instruction);
-                assertEquals(dummyValue1, value);
-                position.set(instruction, dummyValue2);
-            }
+        op1.forEachInputPos((instruction, position) -> {
+            Value value = position.get(instruction);
+            assertEquals(dummyValue1, value);
+            position.set(instruction, dummyValue2);
         });
 
-        op2.forEachInput(new ValuePositionProcedure() {
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                Value value = position.get(instruction);
-                assertEquals(dummyValue1, value);
-                position.set(instruction, dummyValue3);
-            }
+        op2.forEachInputPos((instruction, position) -> {
+            Value value = position.get(instruction);
+            assertEquals(dummyValue1, value);
+            position.set(instruction, dummyValue3);
         });
 
-        op1.forEachInput(new ValuePositionProcedure() {
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                Value value = position.get(instruction);
-                assertEquals(dummyValue2, value);
-            }
+        op1.forEachInputPos((instruction, position) -> {
+            Value value = position.get(instruction);
+            assertEquals(dummyValue2, value);
         });
 
-        op2.forEachInput(new ValuePositionProcedure() {
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                Value value = position.get(instruction);
-                assertEquals(dummyValue3, value);
-            }
+        op2.forEachInputPos((instruction, position) -> {
+            Value value = position.get(instruction);
+            assertEquals(dummyValue3, value);
         });
     }
 
@@ -172,39 +159,26 @@
         LIRInstruction op1 = new TestOp(compValue1);
         LIRInstruction op2 = new TestOp(compValue1);
 
-        op1.forEachInput(new ValuePositionProcedure() {
-
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                Value value = position.get(instruction);
-                assertEquals(dummyValue1, value);
-                position.set(instruction, dummyValue2);
-            }
+        op1.forEachInputPos((instruction, position) -> {
+            Value value = position.get(instruction);
+            assertEquals(dummyValue1, value);
+            position.set(instruction, dummyValue2);
         });
 
-        op2.forEachInput(new ValuePositionProcedure() {
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                Value value = position.get(instruction);
-                assertEquals(dummyValue1, value);
-                position.set(instruction, dummyValue3);
-            }
+        op2.forEachInputPos((instruction, position) -> {
+            Value value = position.get(instruction);
+            assertEquals(dummyValue1, value);
+            position.set(instruction, dummyValue3);
         });
 
-        op1.forEachInput(new ValuePositionProcedure() {
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                Value value = position.get(instruction);
-                assertEquals(dummyValue2, value);
-            }
+        op1.forEachInputPos((instruction, position) -> {
+            Value value = position.get(instruction);
+            assertEquals(dummyValue2, value);
         });
 
-        op2.forEachInput(new ValuePositionProcedure() {
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                Value value = position.get(instruction);
-                assertEquals(dummyValue3, value);
-            }
+        op2.forEachInputPos((instruction, position) -> {
+            Value value = position.get(instruction);
+            assertEquals(dummyValue3, value);
         });
     }
 }
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest1.java
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest1.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest1.java	Fri Oct 03 13:48:58 2014 +0200
@@ -117,13 +117,7 @@
 
         List positions = new ArrayList<>();
 
-        op.forEachInput(new ValuePositionProcedure() {
-
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                positions.add(position);
-            }
-        });
+        op.forEachInputPos((instruction, position) -> positions.add(position));
 
         assertEquals(1, positions.size());
         assertEquals(dummyValue, positions.get(0).get(op));
@@ -136,13 +130,7 @@
 
         List positions = new ArrayList<>();
 
-        op.forEachInput(new ValuePositionProcedure() {
-
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                positions.add(position);
-            }
-        });
+        op.forEachInputPos((instruction, position) -> positions.add(position));
 
         assertEquals(1, positions.size());
         assertEquals(dummyValue, positions.get(0).get(op));
@@ -155,13 +143,7 @@
 
         List positions = new ArrayList<>();
 
-        op.forEachInput(new ValuePositionProcedure() {
-
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                positions.add(position);
-            }
-        });
+        op.forEachInputPos((instruction, position) -> positions.add(position));
 
         assertEquals(1, positions.size());
         assertEquals(dummyValue, positions.get(0).get(op));
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest2.java
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest2.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest2.java	Fri Oct 03 13:48:58 2014 +0200
@@ -117,13 +117,7 @@
         LIRInstruction op = new TestOp(compValue2);
         List positions = new ArrayList<>();
 
-        op.forEachInput(new ValuePositionProcedure() {
-
-            @Override
-            public void doValue(LIRInstruction instruction, ValuePosition position) {
-                positions.add(position);
-            }
-        });
+        op.forEachInputPos((instruction, position) -> positions.add(position));
 
         assertEquals(4, positions.size());
 
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest3.java
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest3.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest3.java	Fri Oct 03 13:48:58 2014 +0200
@@ -131,11 +131,11 @@
         HashMap> positionMap = new HashMap<>();
         HashMap> normalMap = new HashMap<>();
 
-        op.forEachInput(new ValuePositionProcedure() {
+        op.forEachInputPos(new ValuePositionProcedure() {
 
             @Override
             public void doValue(LIRInstruction instruction, ValuePosition position) {
-                positionMap.put(position.get(instruction), position.getFlags(instruction));
+                positionMap.put(position.get(instruction), position.getFlags());
             }
         });
         op.visitEachInput(new InstructionValueConsumer() {
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java	Fri Oct 03 13:48:58 2014 +0200
@@ -54,7 +54,7 @@
         valueClass = CompositeValueClass.get(getClass());
     }
 
-    final CompositeValue forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedureBase proc) {
+    final CompositeValue forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc) {
         return valueClass.forEachComponent(inst, this, mode, proc);
     }
 
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java	Fri Oct 03 13:48:58 2014 +0200
@@ -57,46 +57,28 @@
         }
     }
 
-    private final int directComponentCount;
-    private final long[] componentOffsets;
-    private final EnumSet[] componentFlags;
-
     public CompositeValueClass(Class clazz) {
         this(clazz, new DefaultCalcOffset());
     }
 
-    @SuppressWarnings("unchecked")
     public CompositeValueClass(Class clazz, CalcOffset calcOffset) {
         super(clazz);
 
-        ValueFieldScanner scanner = new ValueFieldScanner(calcOffset);
-        scanner.scan(clazz);
+        ValueFieldScanner vfs = new ValueFieldScanner(calcOffset);
+        vfs.scan(clazz, true);
 
-        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;
+        values = new Values(vfs.valueAnnotations.get(CompositeValue.Component.class));
+        data = new Fields(vfs.data);
     }
 
     private static class ValueFieldScanner extends FieldScanner {
 
         public ValueFieldScanner(CalcOffset calc) {
             super(calc);
-
             valueAnnotations.put(CompositeValue.Component.class, new OperandModeAnnotation());
         }
 
         @Override
-        public 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)) {
@@ -111,57 +93,53 @@
     @Override
     public String toString() {
         StringBuilder str = new StringBuilder();
-        str.append(getClass().getSimpleName()).append(" ").append(getClazz().getSimpleName()).append(" component[");
-        for (int i = 0; i < componentOffsets.length; i++) {
-            str.append(i == 0 ? "" : ", ").append(componentOffsets[i]);
-        }
+        str.append(getClass().getSimpleName()).append(" ").append(getClazz().getSimpleName()).append(" components[");
+        values.appendFields(str);
         str.append("] data[");
-        for (int i = 0; i < dataOffsets.length; i++) {
-            str.append(i == 0 ? "" : ", ").append(dataOffsets[i]);
-        }
+        data.appendFields(str);
         str.append("]");
         return str.toString();
     }
 
-    final CompositeValue forEachComponent(LIRInstruction inst, CompositeValue obj, OperandMode mode, InstructionValueProcedureBase proc) {
-        return forEachComponent(inst, obj, directComponentCount, componentOffsets, mode, componentFlags, proc);
+    final CompositeValue forEachComponent(LIRInstruction inst, CompositeValue obj, OperandMode mode, InstructionValueProcedure proc) {
+        return super.forEachComponent(inst, obj, values, mode, proc);
     }
 
     final void forEachComponent(LIRInstruction inst, CompositeValue obj, OperandMode mode, ValuePositionProcedure proc, ValuePosition outerPosition) {
-        forEach(inst, obj, directComponentCount, componentOffsets, mode, componentFlags, proc, outerPosition);
+        forEach(inst, obj, values, mode, proc, outerPosition);
     }
 
     public String toString(CompositeValue obj) {
         StringBuilder result = new StringBuilder();
 
-        appendValues(result, obj, "", "", "{", "}", new String[]{""}, componentOffsets);
+        appendValues(result, obj, "", "", "{", "}", new String[]{""}, values);
 
-        for (int i = 0; i < dataOffsets.length; i++) {
-            result.append(" ").append(fieldNames.get(dataOffsets[i])).append(": ").append(getFieldString(obj, dataOffsets[i]));
+        for (int i = 0; i < data.getCount(); i++) {
+            result.append(" ").append(data.getName(i)).append(": ").append(getFieldString(obj, i, data));
         }
 
         return result.toString();
     }
 
     Value getValue(CompositeValue obj, ValuePosition pos) {
-        return getValueForPosition(obj, componentOffsets, directComponentCount, pos);
+        return getValueForPosition(obj, values, pos);
     }
 
     CompositeValue createUpdatedValue(CompositeValue compValue, ValuePosition pos, Value value) {
         CompositeValue newCompValue = compValue.clone();
-        setValueForPosition(newCompValue, componentOffsets, directComponentCount, pos, value);
+        setValueForPosition(newCompValue, values, pos, value);
         return newCompValue;
     }
 
     EnumSet getFlags(ValuePosition pos) {
-        return componentFlags[pos.getIndex()];
+        return values.getFlags(pos.getIndex());
     }
 
     void copyValueArrays(CompositeValue compositeValue) {
-        for (int i = directComponentCount; i < componentOffsets.length; i++) {
-            Value[] valueArray = getValueArray(compositeValue, componentOffsets[i]);
+        for (int i = values.getDirectCount(); i < values.getCount(); i++) {
+            Value[] valueArray = values.getValueArray(compositeValue, i);
             Value[] newValueArray = Arrays.copyOf(valueArray, valueArray.length);
-            setValueArray(compositeValue, componentOffsets[i], newValueArray);
+            values.setValueArray(compositeValue, i, newValueArray);
         }
     }
 }
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InstructionStateProcedure.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InstructionStateProcedure.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InstructionStateProcedure.java	Fri Oct 03 13:48:58 2014 +0200
@@ -22,7 +22,8 @@
  */
 package com.oracle.graal.lir;
 
-public abstract class InstructionStateProcedure {
+@FunctionalInterface
+public interface InstructionStateProcedure {
 
-    protected abstract void doState(LIRInstruction instruction, LIRFrameState state);
-}
\ No newline at end of file
+    void doState(LIRInstruction instruction, LIRFrameState state);
+}
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InstructionValueConsumer.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InstructionValueConsumer.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InstructionValueConsumer.java	Fri Oct 03 13:48:58 2014 +0200
@@ -25,42 +25,27 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.*;
-import com.oracle.graal.lir.LIRInstruction.*;
+import com.oracle.graal.lir.LIRInstruction.OperandFlag;
+import com.oracle.graal.lir.LIRInstruction.OperandMode;
 
 /**
  * Non-modifying version of {@link InstructionValueProcedure}.
  */
-public abstract class InstructionValueConsumer extends InstructionValueProcedureBase {
+@FunctionalInterface
+public interface InstructionValueConsumer extends InstructionValueProcedure {
 
     /**
-     * Iterator method to be overwritten. This version of the iterator does not take additional
-     * parameters to keep the signature short.
-     *
-     * @param instruction The current instruction.
-     * @param value The value that is iterated.
-     */
-    protected void visitValue(LIRInstruction instruction, Value value) {
-        throw GraalInternalError.shouldNotReachHere("One of the visitValue() methods must be overwritten");
-    }
-
-    /**
-     * Iterator method to be overwritten. This version of the iterator gets additional parameters
-     * about the processed value.
+     * Iterator method to be overwritten.
      *
      * @param instruction The current instruction.
      * @param value The value that is iterated.
      * @param mode The operand mode for the value.
      * @param flags A set of flags for the value.
      */
-    protected void visitValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet flags) {
-        visitValue(instruction, value);
-    }
+    void visitValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet flags);
 
-    @Override
-    public final Value processValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet flags) {
-        assert !(value instanceof CompositeValue) : String.format("Must not visit CompositeValues! Instruction: %s Value: %s", instruction, value);
+    default Value doValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet flags) {
         visitValue(instruction, value, mode, flags);
         return value;
     }
-}
\ No newline at end of file
+}
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InstructionValueProcedure.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InstructionValueProcedure.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InstructionValueProcedure.java	Fri Oct 03 13:48:58 2014 +0200
@@ -25,31 +25,17 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.*;
-import com.oracle.graal.lir.LIRInstruction.*;
+import com.oracle.graal.lir.LIRInstruction.OperandFlag;
+import com.oracle.graal.lir.LIRInstruction.OperandMode;
 
 /**
- * Iterator for iterating over a list of values. Subclasses must overwrite one of the doValue
- * methods. Clients should not use this class directly but call
- * {@link InstructionValueProcedureBase#processValue} instead.
+ * Functional interface for iterating over a list of values.
  */
-public abstract class InstructionValueProcedure extends InstructionValueProcedureBase {
+@FunctionalInterface
+public interface InstructionValueProcedure {
 
     /**
-     * Iterator method to be overwritten. This version of the iterator does not take additional
-     * parameters to keep the signature short.
-     *
-     * @param instruction The current instruction.
-     * @param value The value that is iterated.
-     * @return The new value to replace the value that was passed in.
-     */
-    protected Value doValue(LIRInstruction instruction, Value value) {
-        throw GraalInternalError.shouldNotReachHere("One of the doValue() methods must be overwritten");
-    }
-
-    /**
-     * Iterator method to be overwritten. This version of the iterator gets additional parameters
-     * about the processed value.
+     * Iterator method to be overwritten.
      *
      * @param instruction The current instruction.
      * @param value The value that is iterated.
@@ -57,13 +43,6 @@
      * @param flags A set of flags for the value.
      * @return The new value to replace the value that was passed in.
      */
-    protected Value doValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet flags) {
-        return doValue(instruction, value);
-    }
+    Value doValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet flags);
 
-    @Override
-    public final Value processValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet flags) {
-        assert !(value instanceof CompositeValue) : String.format("Must not visit CompositeValues! Instruction: %s Value: %s", instruction, value);
-        return doValue(instruction, value, mode, flags);
-    }
-}
\ No newline at end of file
+}
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InstructionValueProcedureBase.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InstructionValueProcedureBase.java	Fri Oct 03 11:07:44 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +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;
-
-import java.util.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.lir.LIRInstruction.*;
-
-/**
- * Common base class for modifying and non-modifying {@link Value value} iterators.
- *
- * This type should not be sub-classed directly. Use {@link InstructionValueProcedureBase} or
- * {@link InstructionValueConsumer} instead.
- *
- * @see InstructionValueProcedure
- * @see InstructionValueConsumer
- */
-public abstract class InstructionValueProcedureBase {
-
-    /**
-     * Iterator method to be overwritten. This version of the iterator gets additional parameters
-     * about the processed value.
-     *
-     * @param instruction The current instruction.
-     * @param value The value that is iterated.
-     * @param mode The operand mode for the value.
-     * @param flags A set of flags for the value.
-     * @return The new value to replace the value that was passed in.
-     */
-    abstract public Value processValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet flags);
-}
\ No newline at end of file
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Fri Oct 03 13:48:58 2014 +0200
@@ -144,13 +144,10 @@
      */
     public static LabelRef getExceptionEdge(LIRInstruction op) {
         final LabelRef[] exceptionEdge = {null};
-        op.forEachState(new StateProcedure() {
-            @Override
-            protected void doState(LIRFrameState state) {
-                if (state.exceptionEdge != null) {
-                    assert exceptionEdge[0] == null;
-                    exceptionEdge[0] = state.exceptionEdge;
-                }
+        op.forEachState(state -> {
+            if (state.exceptionEdge != null) {
+                assert exceptionEdge[0] == null;
+                exceptionEdge[0] = state.exceptionEdge;
             }
         });
         return exceptionEdge[0];
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java	Fri Oct 03 13:48:58 2014 +0200
@@ -62,7 +62,7 @@
      *
      * @param proc The procedure called for variables.
      */
-    public void forEachState(LIRInstruction inst, InstructionValueProcedureBase proc) {
+    public void forEachState(LIRInstruction inst, InstructionValueProcedure proc) {
         for (BytecodeFrame cur = topFrame; cur != null; cur = cur.caller()) {
             processValues(inst, cur.values, proc);
         }
@@ -79,16 +79,16 @@
      */
     protected static final EnumSet STATE_FLAGS = EnumSet.of(OperandFlag.REG, OperandFlag.STACK);
 
-    protected void processValues(LIRInstruction inst, Value[] values, InstructionValueProcedureBase proc) {
+    protected void processValues(LIRInstruction inst, Value[] values, InstructionValueProcedure proc) {
         for (int i = 0; i < values.length; i++) {
             Value value = values[i];
             values[i] = processValue(inst, proc, value);
         }
     }
 
-    protected Value processValue(LIRInstruction inst, InstructionValueProcedureBase proc, Value value) {
+    protected Value processValue(LIRInstruction inst, InstructionValueProcedure proc, Value value) {
         if (processed(value)) {
-            return proc.processValue(inst, value, OperandMode.ALIVE, STATE_FLAGS);
+            return proc.doValue(inst, value, OperandMode.ALIVE, STATE_FLAGS);
         }
         return value;
     }
diff -r 8a2a809110ba -r 5d4749f9c5f6 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	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java	Fri Oct 03 13:48:58 2014 +0200
@@ -218,20 +218,20 @@
     }
 
     // ValuePositionProcedures
-    public final void forEachInput(ValuePositionProcedure proc) {
-        instructionClass.forEachUse(this, proc);
+    public final void forEachInputPos(ValuePositionProcedure proc) {
+        instructionClass.forEachUsePos(this, proc);
     }
 
-    public final void forEachAlive(ValuePositionProcedure proc) {
-        instructionClass.forEachAlive(this, proc);
+    public final void forEachAlivePos(ValuePositionProcedure proc) {
+        instructionClass.forEachAlivePos(this, proc);
     }
 
     public final void forEachTemp(ValuePositionProcedure proc) {
-        instructionClass.forEachTemp(this, proc);
+        instructionClass.forEachTempPos(this, proc);
     }
 
     public final void forEachOutput(ValuePositionProcedure proc) {
-        instructionClass.forEachDef(this, proc);
+        instructionClass.forEachDefPos(this, proc);
     }
 
     // InstructionValueProcedures
@@ -251,16 +251,41 @@
         instructionClass.forEachDef(this, proc);
     }
 
-    // States
     public final void forEachState(InstructionValueProcedure proc) {
         instructionClass.forEachState(this, proc);
     }
 
+    // ValueProcedures
+    public final void forEachInput(ValueProcedure proc) {
+        instructionClass.forEachUse(this, proc);
+    }
+
+    public final void forEachAlive(ValueProcedure proc) {
+        instructionClass.forEachAlive(this, proc);
+    }
+
+    public final void forEachTemp(ValueProcedure proc) {
+        instructionClass.forEachTemp(this, proc);
+    }
+
+    public final void forEachOutput(ValueProcedure proc) {
+        instructionClass.forEachDef(this, proc);
+    }
+
+    public final void forEachState(ValueProcedure proc) {
+        instructionClass.forEachState(this, proc);
+    }
+
+    // States
     public final void forEachState(InstructionStateProcedure proc) {
         instructionClass.forEachState(this, proc);
     }
 
-    // Consumers
+    public final void forEachState(StateProcedure proc) {
+        instructionClass.forEachState(this, proc);
+    }
+
+    // InstructionValueConsumers
     public final void visitEachInput(InstructionValueConsumer proc) {
         instructionClass.forEachUse(this, proc);
     }
@@ -281,6 +306,27 @@
         instructionClass.forEachState(this, proc);
     }
 
+    // ValueConsumers
+    public final void visitEachInput(ValueConsumer proc) {
+        instructionClass.forEachUse(this, proc);
+    }
+
+    public final void visitEachAlive(ValueConsumer proc) {
+        instructionClass.forEachAlive(this, proc);
+    }
+
+    public final void visitEachTemp(ValueConsumer proc) {
+        instructionClass.forEachTemp(this, proc);
+    }
+
+    public final void visitEachOutput(ValueConsumer proc) {
+        instructionClass.forEachDef(this, proc);
+    }
+
+    public final void visitEachState(ValueConsumer proc) {
+        instructionClass.forEachState(this, proc);
+    }
+
     /**
      * Iterates all register hints for the specified value, i.e., all preferred candidates for the
      * register to be assigned to the value.
@@ -300,6 +346,19 @@
         return instructionClass.forEachRegisterHint(this, mode, proc);
     }
 
+    /**
+     * @see #forEachRegisterHint(Value, OperandMode, InstructionValueProcedure)
+     * @param value The value the hints are needed for.
+     * @param mode The operand mode of the value.
+     * @param proc The procedure invoked for all the hints. If the procedure returns a non-null
+     *            value, the iteration is stopped and the value is returned by this method, i.e.,
+     *            clients can stop the iteration once a suitable hint has been found.
+     * @return The non-null value returned by the procedure, or null.
+     */
+    public Value forEachRegisterHint(Value value, OperandMode mode, ValueProcedure proc) {
+        return instructionClass.forEachRegisterHint(this, mode, proc);
+    }
+
     protected void verify() {
     }
 
diff -r 8a2a809110ba -r 5d4749f9c5f6 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	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java	Fri Oct 03 13:48:58 2014 +0200
@@ -53,70 +53,50 @@
     private static final Class INSTRUCTION_CLASS = LIRInstruction.class;
     private static final Class STATE_CLASS = LIRFrameState.class;
 
-    private final int directUseCount;
-    private final long[] useOffsets;
-    private final EnumSet[] useFlags;
-    private final int directAliveCount;
-    private final long[] aliveOffsets;
-    private final EnumSet[] aliveFlags;
-    private final int directTempCount;
-    private final long[] tempOffsets;
-    private final EnumSet[] tempFlags;
-    private final int directDefCount;
-    private final long[] defOffsets;
-    private final EnumSet[] defFlags;
-
-    private final long[] stateOffsets;
+    private final Values uses;
+    private final Values alives;
+    private final Values temps;
+    private final Values defs;
+    private final Fields states;
 
     private String opcodeConstant;
-    private long opcodeOffset;
+    private int opcodeIndex;
 
     private LIRInstructionClass(Class clazz) {
         this(clazz, new DefaultCalcOffset());
     }
 
-    @SuppressWarnings("unchecked")
     public LIRInstructionClass(Class clazz, CalcOffset calcOffset) {
         super(clazz);
         assert INSTRUCTION_CLASS.isAssignableFrom(clazz);
 
-        InstructionFieldScanner scanner = new InstructionFieldScanner(calcOffset);
-        scanner.scan(clazz);
+        InstructionFieldScanner ifs = new InstructionFieldScanner(calcOffset);
+        ifs.scan(clazz);
 
-        OperandModeAnnotation mode = scanner.valueAnnotations.get(LIRInstruction.Use.class);
-        directUseCount = mode.scalarOffsets.size();
-        useOffsets = sortedLongCopy(mode.scalarOffsets, mode.arrayOffsets);
-        useFlags = arrayUsingSortedOffsets(mode.flags, useOffsets, new EnumSet[useOffsets.length]);
-
-        mode = scanner.valueAnnotations.get(LIRInstruction.Alive.class);
-        directAliveCount = mode.scalarOffsets.size();
-        aliveOffsets = sortedLongCopy(mode.scalarOffsets, mode.arrayOffsets);
-        aliveFlags = arrayUsingSortedOffsets(mode.flags, aliveOffsets, new EnumSet[aliveOffsets.length]);
+        uses = new Values(ifs.valueAnnotations.get(LIRInstruction.Use.class));
+        alives = new Values(ifs.valueAnnotations.get(LIRInstruction.Alive.class));
+        temps = new Values(ifs.valueAnnotations.get(LIRInstruction.Temp.class));
+        defs = new Values(ifs.valueAnnotations.get(LIRInstruction.Def.class));
 
-        mode = scanner.valueAnnotations.get(LIRInstruction.Temp.class);
-        directTempCount = mode.scalarOffsets.size();
-        tempOffsets = sortedLongCopy(mode.scalarOffsets, mode.arrayOffsets);
-        tempFlags = arrayUsingSortedOffsets(mode.flags, tempOffsets, new EnumSet[tempOffsets.length]);
+        states = new Fields(ifs.states);
+        data = new Fields(ifs.data);
 
-        mode = scanner.valueAnnotations.get(LIRInstruction.Def.class);
-        directDefCount = mode.scalarOffsets.size();
-        defOffsets = sortedLongCopy(mode.scalarOffsets, mode.arrayOffsets);
-        defFlags = arrayUsingSortedOffsets(mode.flags, defOffsets, new EnumSet[defOffsets.length]);
-
-        stateOffsets = sortedLongCopy(scanner.stateOffsets);
-        dataOffsets = sortedLongCopy(scanner.dataOffsets);
-
-        fieldNames = scanner.fieldNames;
-        fieldTypes = scanner.fieldTypes;
-
-        opcodeConstant = scanner.opcodeConstant;
-        opcodeOffset = scanner.opcodeOffset;
+        opcodeConstant = ifs.opcodeConstant;
+        if (ifs.opcodeField == null) {
+            opcodeIndex = -1;
+        } else {
+            opcodeIndex = ifs.data.indexOf(ifs.opcodeField);
+        }
     }
 
     private static class InstructionFieldScanner extends FieldScanner {
 
         private String opcodeConstant;
-        private long opcodeOffset;
+
+        /**
+         * Field (if any) annotated by {@link Opcode}.
+         */
+        private FieldInfo opcodeField;
 
         public InstructionFieldScanner(CalcOffset calc) {
             super(calc);
@@ -148,16 +128,15 @@
             return result;
         }
 
-        @Override
         public void scan(Class clazz) {
             if (clazz.getAnnotation(Opcode.class) != null) {
                 opcodeConstant = clazz.getAnnotation(Opcode.class).value();
             }
-            opcodeOffset = -1;
+            opcodeField = null;
 
-            super.scan(clazz);
+            super.scan(clazz, true);
 
-            if (opcodeConstant == null && opcodeOffset == -1) {
+            if (opcodeConstant == null && opcodeField == null) {
                 opcodeConstant = clazz.getSimpleName();
                 if (opcodeConstant.endsWith("Op")) {
                     opcodeConstant = opcodeConstant.substring(0, opcodeConstant.length() - 2);
@@ -166,18 +145,20 @@
         }
 
         @Override
-        protected void scanField(Field field, Class type, long offset) {
+        protected void scanField(Field field, long offset) {
+            Class type = field.getType();
             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);
+                states.add(new FieldInfo(offset, field.getName(), type));
             } else {
-                super.scanField(field, type, offset);
+                super.scanField(field, offset);
             }
 
             if (field.getAnnotation(Opcode.class) != null) {
-                assert opcodeConstant == null && opcodeOffset == -1 : "Can have only one Opcode definition: " + field.getType();
-                opcodeOffset = offset;
+                assert opcodeConstant == null && opcodeField == null : "Can have only one Opcode definition: " + type;
+                assert data.get(data.size() - 1).offset == offset;
+                opcodeField = data.get(data.size() - 1);
             }
         }
     }
@@ -186,97 +167,33 @@
     public String toString() {
         StringBuilder str = new StringBuilder();
         str.append(getClass().getSimpleName()).append(" ").append(getClazz().getSimpleName()).append(" use[");
-        for (int i = 0; i < useOffsets.length; i++) {
-            str.append(i == 0 ? "" : ", ").append(useOffsets[i]);
-        }
+        uses.appendFields(str);
         str.append("] alive[");
-        for (int i = 0; i < aliveOffsets.length; i++) {
-            str.append(i == 0 ? "" : ", ").append(aliveOffsets[i]);
-        }
+        alives.appendFields(str);
         str.append("] temp[");
-        for (int i = 0; i < tempOffsets.length; i++) {
-            str.append(i == 0 ? "" : ", ").append(tempOffsets[i]);
-        }
+        temps.appendFields(str);
         str.append("] def[");
-        for (int i = 0; i < defOffsets.length; i++) {
-            str.append(i == 0 ? "" : ", ").append(defOffsets[i]);
-        }
+        defs.appendFields(str);
         str.append("] state[");
-        for (int i = 0; i < stateOffsets.length; i++) {
-            str.append(i == 0 ? "" : ", ").append(stateOffsets[i]);
-        }
+        states.appendFields(str);
         str.append("] data[");
-        for (int i = 0; i < dataOffsets.length; i++) {
-            str.append(i == 0 ? "" : ", ").append(dataOffsets[i]);
-        }
+        data.appendFields(str);
         str.append("]");
         return str.toString();
     }
 
-    Value getValue(LIRInstruction obj, ValuePosition pos) {
-        long[] offsets;
-        int directCount;
-        switch (pos.getMode()) {
-            case USE:
-                directCount = directUseCount;
-                offsets = useOffsets;
-                break;
-            case ALIVE:
-                directCount = directAliveCount;
-                offsets = aliveOffsets;
-                break;
-            case TEMP:
-                directCount = directTempCount;
-                offsets = tempOffsets;
-                break;
-            case DEF:
-                directCount = directDefCount;
-                offsets = defOffsets;
-                break;
-            default:
-                throw GraalInternalError.shouldNotReachHere("unkown OperandMode: " + pos.getMode());
-        }
-        return getValueForPosition(obj, offsets, directCount, pos);
-    }
-
-    void setValue(LIRInstruction obj, ValuePosition pos, Value value) {
-        long[] offsets;
-        int directCount;
-        switch (pos.getMode()) {
+    Values getValues(OperandMode mode) {
+        switch (mode) {
             case USE:
-                directCount = directUseCount;
-                offsets = useOffsets;
-                break;
+                return uses;
             case ALIVE:
-                directCount = directAliveCount;
-                offsets = aliveOffsets;
-                break;
+                return alives;
             case TEMP:
-                directCount = directTempCount;
-                offsets = tempOffsets;
-                break;
+                return temps;
             case DEF:
-                directCount = directDefCount;
-                offsets = defOffsets;
-                break;
+                return defs;
             default:
-                throw GraalInternalError.shouldNotReachHere("unkown OperandMode: " + pos.getMode());
-        }
-        setValueForPosition(obj, offsets, directCount, pos, value);
-    }
-
-    EnumSet getFlags(ValuePosition pos) {
-        switch (pos.getMode()) {
-            case USE:
-                return useFlags[pos.getIndex()];
-            case ALIVE:
-                return aliveFlags[pos.getIndex()];
-            case TEMP:
-                return tempFlags[pos.getIndex()];
-            case DEF:
-                return defFlags[pos.getIndex()];
-            default:
-                throw GraalInternalError.shouldNotReachHere("unkown OperandMode: " + pos.getMode());
+                throw GraalInternalError.shouldNotReachHere("unknown OperandMode: " + mode);
         }
     }
 
@@ -284,58 +201,58 @@
         if (opcodeConstant != null) {
             return opcodeConstant;
         }
-        assert opcodeOffset != -1;
-        return unsafe.getObject(obj, opcodeOffset).toString();
+        assert opcodeIndex != -1;
+        return data.getObject(obj, opcodeIndex).toString();
     }
 
     final boolean hasOperands() {
-        return useOffsets.length > 0 || aliveOffsets.length > 0 || tempOffsets.length > 0 || defOffsets.length > 0;
+        return uses.getCount() > 0 || alives.getCount() > 0 || temps.getCount() > 0 || defs.getCount() > 0;
     }
 
     final boolean hasState(LIRInstruction obj) {
-        for (int i = 0; i < stateOffsets.length; i++) {
-            if (getState(obj, stateOffsets[i]) != null) {
+        for (int i = 0; i < states.getCount(); i++) {
+            if (states.getObject(obj, i) != null) {
                 return true;
             }
         }
         return false;
     }
 
-    final void forEachUse(LIRInstruction obj, ValuePositionProcedure proc) {
-        forEach(obj, obj, directUseCount, useOffsets, OperandMode.USE, useFlags, proc, ValuePosition.ROOT_VALUE_POSITION);
+    final void forEachUsePos(LIRInstruction obj, ValuePositionProcedure proc) {
+        forEach(obj, obj, uses, OperandMode.USE, proc, ValuePosition.ROOT_VALUE_POSITION);
     }
 
-    final void forEachAlive(LIRInstruction obj, ValuePositionProcedure proc) {
-        forEach(obj, obj, directAliveCount, aliveOffsets, OperandMode.ALIVE, aliveFlags, proc, ValuePosition.ROOT_VALUE_POSITION);
+    final void forEachAlivePos(LIRInstruction obj, ValuePositionProcedure proc) {
+        forEach(obj, obj, alives, OperandMode.ALIVE, proc, ValuePosition.ROOT_VALUE_POSITION);
     }
 
-    final void forEachTemp(LIRInstruction obj, ValuePositionProcedure proc) {
-        forEach(obj, obj, directTempCount, tempOffsets, OperandMode.TEMP, tempFlags, proc, ValuePosition.ROOT_VALUE_POSITION);
+    final void forEachTempPos(LIRInstruction obj, ValuePositionProcedure proc) {
+        forEach(obj, obj, temps, OperandMode.TEMP, proc, ValuePosition.ROOT_VALUE_POSITION);
     }
 
-    final void forEachDef(LIRInstruction obj, ValuePositionProcedure proc) {
-        forEach(obj, obj, directDefCount, defOffsets, OperandMode.DEF, defFlags, proc, ValuePosition.ROOT_VALUE_POSITION);
+    final void forEachDefPos(LIRInstruction obj, ValuePositionProcedure proc) {
+        forEach(obj, obj, defs, OperandMode.DEF, proc, ValuePosition.ROOT_VALUE_POSITION);
     }
 
-    final void forEachUse(LIRInstruction obj, InstructionValueProcedureBase proc) {
-        forEach(obj, directUseCount, useOffsets, OperandMode.USE, useFlags, proc);
+    final void forEachUse(LIRInstruction obj, InstructionValueProcedure proc) {
+        forEach(obj, uses, OperandMode.USE, proc);
     }
 
-    final void forEachAlive(LIRInstruction obj, InstructionValueProcedureBase proc) {
-        forEach(obj, directAliveCount, aliveOffsets, OperandMode.ALIVE, aliveFlags, proc);
+    final void forEachAlive(LIRInstruction obj, InstructionValueProcedure proc) {
+        forEach(obj, alives, OperandMode.ALIVE, proc);
     }
 
-    final void forEachTemp(LIRInstruction obj, InstructionValueProcedureBase proc) {
-        forEach(obj, directTempCount, tempOffsets, OperandMode.TEMP, tempFlags, proc);
+    final void forEachTemp(LIRInstruction obj, InstructionValueProcedure proc) {
+        forEach(obj, temps, OperandMode.TEMP, proc);
     }
 
-    final void forEachDef(LIRInstruction obj, InstructionValueProcedureBase proc) {
-        forEach(obj, directDefCount, defOffsets, OperandMode.DEF, defFlags, proc);
+    final void forEachDef(LIRInstruction obj, InstructionValueProcedure proc) {
+        forEach(obj, defs, OperandMode.DEF, proc);
     }
 
-    final void forEachState(LIRInstruction obj, InstructionValueProcedureBase proc) {
-        for (int i = 0; i < stateOffsets.length; i++) {
-            LIRFrameState state = getState(obj, stateOffsets[i]);
+    final void forEachState(LIRInstruction obj, InstructionValueProcedure proc) {
+        for (int i = 0; i < states.getCount(); i++) {
+            LIRFrameState state = (LIRFrameState) states.getObject(obj, i);
             if (state != null) {
                 state.forEachState(obj, proc);
             }
@@ -343,8 +260,8 @@
     }
 
     final void forEachState(LIRInstruction obj, InstructionStateProcedure proc) {
-        for (int i = 0; i < stateOffsets.length; i++) {
-            LIRFrameState state = getState(obj, stateOffsets[i]);
+        for (int i = 0; i < states.getCount(); i++) {
+            LIRFrameState state = (LIRFrameState) states.getObject(obj, i);
             if (state != null) {
                 proc.doState(obj, state);
             }
@@ -352,30 +269,27 @@
     }
 
     final Value forEachRegisterHint(LIRInstruction obj, OperandMode mode, InstructionValueProcedure proc) {
-        int hintDirectCount = 0;
-        long[] hintOffsets = null;
+        Values hints;
         if (mode == OperandMode.USE) {
-            hintDirectCount = directDefCount;
-            hintOffsets = defOffsets;
+            hints = defs;
         } else if (mode == OperandMode.DEF) {
-            hintDirectCount = directUseCount;
-            hintOffsets = useOffsets;
+            hints = uses;
         } else {
             return null;
         }
 
-        for (int i = 0; i < hintOffsets.length; i++) {
-            if (i < hintDirectCount) {
-                Value hintValue = getValue(obj, hintOffsets[i]);
-                Value result = proc.processValue(obj, hintValue, null, null);
+        for (int i = 0; i < hints.getCount(); i++) {
+            if (i < hints.getDirectCount()) {
+                Value hintValue = hints.getValue(obj, i);
+                Value result = proc.doValue(obj, hintValue, null, null);
                 if (result != null) {
                     return result;
                 }
             } else {
-                Value[] hintValues = getValueArray(obj, hintOffsets[i]);
+                Value[] hintValues = hints.getValueArray(obj, i);
                 for (int j = 0; j < hintValues.length; j++) {
                     Value hintValue = hintValues[j];
-                    Value result = proc.processValue(obj, hintValue, null, null);
+                    Value result = proc.doValue(obj, hintValue, null, null);
                     if (result != null) {
                         return result;
                     }
@@ -385,29 +299,25 @@
         return null;
     }
 
-    private static LIRFrameState getState(LIRInstruction obj, long offset) {
-        return (LIRFrameState) unsafe.getObject(obj, offset);
-    }
-
     String toString(LIRInstruction obj) {
         StringBuilder result = new StringBuilder();
 
-        appendValues(result, obj, "", " = ", "(", ")", new String[]{""}, defOffsets);
-        result.append(getOpcode(obj).toUpperCase());
-        appendValues(result, obj, " ", "", "(", ")", new String[]{"", "~"}, useOffsets, aliveOffsets);
-        appendValues(result, obj, " ", "", "{", "}", new String[]{""}, tempOffsets);
+        appendValues(result, obj, "", " = ", "(", ")", new String[]{""}, defs);
+        result.append(String.valueOf(getOpcode(obj)).toUpperCase());
+        appendValues(result, obj, " ", "", "(", ")", new String[]{"", "~"}, uses, alives);
+        appendValues(result, obj, " ", "", "{", "}", new String[]{""}, temps);
 
-        for (int i = 0; i < dataOffsets.length; i++) {
-            if (dataOffsets[i] == opcodeOffset) {
+        for (int i = 0; i < data.getCount(); i++) {
+            if (i == opcodeIndex) {
                 continue;
             }
-            result.append(" ").append(fieldNames.get(dataOffsets[i])).append(": ").append(getFieldString(obj, dataOffsets[i]));
+            result.append(" ").append(data.getName(i)).append(": ").append(getFieldString(obj, i, data));
         }
 
-        for (int i = 0; i < stateOffsets.length; i++) {
-            LIRFrameState state = getState(obj, stateOffsets[i]);
+        for (int i = 0; i < states.getCount(); i++) {
+            LIRFrameState state = (LIRFrameState) states.getObject(obj, i);
             if (state != null) {
-                result.append(" ").append(fieldNames.get(stateOffsets[i])).append(" [bci:");
+                result.append(" ").append(states.getName(i)).append(" [bci:");
                 String sep = "";
                 for (BytecodeFrame cur = state.topFrame; cur != null; cur = cur.caller()) {
                     result.append(sep).append(cur.getBCI());
diff -r 8a2a809110ba -r 5d4749f9c5f6 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	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java	Fri Oct 03 13:48:58 2014 +0200
@@ -48,21 +48,117 @@
         super(clazz);
     }
 
+    protected static class Values extends Fields {
+        private final int directCount;
+        private final OperandMode mode;
+        private final EnumSet[] flags;
+
+        public Values(OperandModeAnnotation mode) {
+            this(mode.directCount, null, mode.values);
+        }
+
+        @SuppressWarnings("unchecked")
+        public Values(int directCount, OperandMode mode, ArrayList fields) {
+            super(fields);
+            this.mode = mode;
+            this.directCount = directCount;
+            flags = new EnumSet[fields.size()];
+            for (int i = 0; i < fields.size(); i++) {
+                flags[i] = fields.get(i).flags;
+            }
+        }
+
+        public int getDirectCount() {
+            return directCount;
+        }
+
+        public OperandMode getMode() {
+            return mode;
+        }
+
+        public EnumSet getFlags(int i) {
+            return flags[i];
+        }
+
+        protected Value getValue(Object obj, int index) {
+            return (Value) getObject(obj, index);
+        }
+
+        protected void setValue(Object obj, int index, Value value) {
+            putObject(obj, index, value);
+        }
+
+        protected Value[] getValueArray(Object obj, int index) {
+            return (Value[]) getObject(obj, index);
+        }
+
+        protected void setValueArray(Object obj, int index, Value[] valueArray) {
+            putObject(obj, index, valueArray);
+        }
+
+        @Override
+        public String toString() {
+            if (mode != null) {
+                return super.toString() + ":" + mode;
+            }
+            return super.toString();
+        }
+    }
+
+    /**
+     * The component values in an {@link LIRInstruction} or {@link CompositeValue}.
+     */
+    protected Values values;
+
+    protected static class ValueFieldInfo extends FieldInfo {
+
+        final EnumSet flags;
+
+        public ValueFieldInfo(long offset, String name, Class type, EnumSet flags) {
+            super(offset, name, type);
+            assert VALUE_ARRAY_CLASS.isAssignableFrom(type) || VALUE_CLASS.isAssignableFrom(type);
+            this.flags = flags;
+        }
+
+        /**
+         * Sorts non-array fields before array fields.
+         */
+        @Override
+        public int compareTo(FieldInfo o) {
+            if (VALUE_ARRAY_CLASS.isAssignableFrom(o.type)) {
+                if (!VALUE_ARRAY_CLASS.isAssignableFrom(type)) {
+                    return -1;
+                }
+            } else {
+                if (VALUE_ARRAY_CLASS.isAssignableFrom(type)) {
+                    return 1;
+                }
+            }
+            return super.compareTo(o);
+        }
+
+        @Override
+        public String toString() {
+            return super.toString() + flags;
+        }
+    }
+
     protected static class OperandModeAnnotation {
 
-        public final ArrayList scalarOffsets = new ArrayList<>();
-        public final ArrayList arrayOffsets = new ArrayList<>();
-        public final Map> flags = new HashMap<>();
+        /**
+         * Number of non-array fields in {@link #values}.
+         */
+        public int directCount;
+        public final ArrayList values = new ArrayList<>();
     }
 
     protected abstract static class FieldScanner extends BaseFieldScanner {
 
         public final Map, OperandModeAnnotation> valueAnnotations;
-        public final ArrayList stateOffsets = new ArrayList<>();
+        public final ArrayList states = new ArrayList<>();
 
         public FieldScanner(CalcOffset calc) {
             super(calc);
-
             valueAnnotations = new HashMap<>();
         }
 
@@ -81,26 +177,26 @@
         protected abstract EnumSet getFlags(Field field);
 
         @Override
-        protected void scanField(Field field, Class type, long offset) {
+        protected void scanField(Field field, long offset) {
+            Class type = field.getType();
             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);
                 EnumSet flags = getFlags(field);
                 assert verifyFlags(field, type, flags);
-                annotation.flags.put(offset, getFlags(field));
+                annotation.values.add(new ValueFieldInfo(offset, field.getName(), type, flags));
+                annotation.directCount++;
             } 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);
                 EnumSet flags = getFlags(field);
                 assert verifyFlags(field, type.getComponentType(), flags);
-                annotation.flags.put(offset, getFlags(field));
+                annotation.values.add(new ValueFieldInfo(offset, field.getName(), type, flags));
             } 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);
+                data.add(new FieldInfo(offset, field.getName(), type));
             }
         }
 
@@ -118,74 +214,73 @@
         }
     }
 
-    protected static void forEach(LIRInstruction inst, int directCount, long[] offsets, OperandMode mode, EnumSet[] flags, InstructionValueProcedureBase proc) {
-        for (int i = 0; i < offsets.length; i++) {
-            assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(flags[i]);
+    protected static void forEach(LIRInstruction inst, Values values, OperandMode mode, InstructionValueProcedure proc) {
+        for (int i = 0; i < values.getCount(); i++) {
+            assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(values.getFlags(i));
 
-            if (i < directCount) {
-                Value value = getValue(inst, offsets[i]);
+            if (i < values.getDirectCount()) {
+                Value value = values.getValue(inst, i);
                 Value newValue;
                 if (value instanceof CompositeValue) {
                     CompositeValue composite = (CompositeValue) value;
                     newValue = composite.forEachComponent(inst, mode, proc);
                 } else {
-                    newValue = proc.processValue(inst, value, mode, flags[i]);
+                    newValue = proc.doValue(inst, value, mode, values.getFlags(i));
                 }
                 if (!value.identityEquals(newValue)) {
-                    setValue(inst, offsets[i], newValue);
+                    values.setValue(inst, i, newValue);
                 }
             } else {
-                Value[] values = getValueArray(inst, offsets[i]);
-                for (int j = 0; j < values.length; j++) {
-                    Value value = values[j];
+                Value[] valueArray = values.getValueArray(inst, i);
+                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.processValue(inst, value, mode, flags[i]);
+                        newValue = proc.doValue(inst, value, mode, values.getFlags(i));
                     }
                     if (!value.identityEquals(newValue)) {
-                        values[j] = newValue;
+                        valueArray[j] = newValue;
                     }
                 }
             }
         }
     }
 
-    protected static CompositeValue forEachComponent(LIRInstruction inst, CompositeValue obj, int directCount, long[] offsets, OperandMode mode, EnumSet[] flags,
-                    InstructionValueProcedureBase proc) {
+    protected static CompositeValue forEachComponent(LIRInstruction inst, CompositeValue obj, Values values, OperandMode mode, InstructionValueProcedure proc) {
         CompositeValue newCompValue = null;
-        for (int i = 0; i < offsets.length; i++) {
-            assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(flags[i]);
+        for (int i = 0; i < values.getCount(); i++) {
+            assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(values.getFlags(i));
 
-            if (i < directCount) {
-                Value value = getValue(obj, offsets[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.processValue(inst, value, mode, flags[i]);
+                    newValue = proc.doValue(inst, value, mode, values.getFlags(i));
                 }
                 if (!value.identityEquals(newValue)) {
                     // lazy initialize
                     if (newCompValue == null) {
                         newCompValue = obj.clone();
                     }
-                    setValue(newCompValue, offsets[i], newValue);
+                    values.setValue(newCompValue, i, newValue);
                 }
             } else {
-                Value[] values = getValueArray(obj, offsets[i]);
+                Value[] valueArray = values.getValueArray(obj, i);
                 Value[] newValues = null;
-                for (int j = 0; j < values.length; j++) {
-                    Value value = values[j];
+                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.processValue(inst, value, mode, flags[i]);
+                        newValue = proc.doValue(inst, value, mode, values.getFlags(i));
                     }
                     if (!value.identityEquals(newValue)) {
                         // lazy initialize
@@ -193,7 +288,7 @@
                             if (newCompValue == null) {
                                 newCompValue = obj.clone();
                             }
-                            newValues = getValueArray(newCompValue, offsets[i]);
+                            newValues = values.getValueArray(newCompValue, i);
                         }
                         newValues[j] = newValue;
                     }
@@ -203,18 +298,17 @@
         return newCompValue != null ? newCompValue : obj;
     }
 
-    protected static void forEach(LIRInstruction inst, Object obj, int directCount, long[] offsets, OperandMode mode, EnumSet[] flags, ValuePositionProcedure proc,
-                    ValuePosition outerPosition) {
-        for (int i = 0; i < offsets.length; i++) {
-            assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(flags[i]);
+    protected static void forEach(LIRInstruction inst, Object obj, Values values, OperandMode mode, ValuePositionProcedure proc, ValuePosition outerPosition) {
+        for (int i = 0; i < values.getCount(); i++) {
+            assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(values.getFlags(i));
 
-            if (i < directCount) {
-                Value value = getValue(obj, offsets[i]);
+            if (i < values.getDirectCount()) {
+                Value value = values.getValue(obj, i);
                 doForValue(inst, mode, proc, outerPosition, i, ValuePosition.NO_SUBINDEX, value);
             } else {
-                Value[] values = getValueArray(obj, offsets[i]);
-                for (int j = 0; j < values.length; j++) {
-                    Value value = values[j];
+                Value[] valueArray = values.getValueArray(obj, i);
+                for (int j = 0; j < valueArray.length; j++) {
+                    Value value = valueArray[j];
                     doForValue(inst, mode, proc, outerPosition, i, j, value);
                 }
             }
@@ -222,7 +316,8 @@
     }
 
     private static void doForValue(LIRInstruction inst, OperandMode mode, ValuePositionProcedure proc, ValuePosition outerPosition, int index, int subIndex, Value value) {
-        ValuePosition position = new ValuePosition(mode, index, subIndex, outerPosition);
+        Values values = inst.getLIRInstructionClass().getValues(mode);
+        ValuePosition position = new ValuePosition(values, index, subIndex, outerPosition);
         if (value instanceof CompositeValue) {
             CompositeValue composite = (CompositeValue) value;
             composite.forEachComponent(inst, mode, proc, position);
@@ -231,102 +326,72 @@
         }
     }
 
-    protected static Value getValueForPosition(Object obj, long[] offsets, int directCount, ValuePosition pos) {
-        if (pos.getIndex() < directCount) {
-            return getValue(obj, offsets[pos.getIndex()]);
+    protected static Value getValueForPosition(Object obj, Values values, ValuePosition pos) {
+        if (pos.getIndex() < values.getDirectCount()) {
+            return values.getValue(obj, pos.getIndex());
         }
-        return getValueArray(obj, offsets[pos.getIndex()])[pos.getSubIndex()];
+        return values.getValueArray(obj, pos.getIndex())[pos.getSubIndex()];
     }
 
-    protected static void setValueForPosition(Object obj, long[] offsets, int directCount, ValuePosition pos, Value value) {
-        if (pos.getIndex() < directCount) {
-            setValue(obj, offsets[pos.getIndex()], value);
+    protected static void setValueForPosition(Object obj, Values values, ValuePosition pos, Value value) {
+        if (pos.getIndex() < values.getDirectCount()) {
+            values.setValue(obj, pos.getIndex(), value);
         } else {
-            getValueArray(obj, offsets[pos.getIndex()])[pos.getSubIndex()] = value;
+            values.getValueArray(obj, pos.getIndex())[pos.getSubIndex()] = value;
         }
     }
 
-    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 static void setValueArray(Object obj, long offset, Value[] valueArray) {
-        unsafe.putObject(obj, offset, valueArray);
-    }
-
-    protected void appendValues(StringBuilder result, Object obj, String start, String end, String startMultiple, String endMultiple, String[] prefix, long[]... moffsets) {
+    protected void appendValues(StringBuilder sb, Object obj, String start, String end, String startMultiple, String endMultiple, String[] prefix, Fields... fieldsList) {
         int total = 0;
-        for (long[] offsets : moffsets) {
-            total += offsets.length;
+        for (Fields fields : fieldsList) {
+            total += fields.getCount();
         }
         if (total == 0) {
             return;
         }
 
-        result.append(start);
+        sb.append(start);
         if (total > 1) {
-            result.append(startMultiple);
+            sb.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];
+        int i = 0;
+        for (Fields fields : fieldsList) {
+            for (int j = 0; j < fields.getCount(); j++) {
+                sb.append(sep).append(prefix[i]);
                 if (total > 1) {
-                    result.append(fieldNames.get(offset)).append(": ");
+                    sb.append(fields.getName(j)).append(": ");
                 }
-                result.append(getFieldString(obj, offset));
+                sb.append(getFieldString(obj, j, fields));
                 sep = ", ";
             }
+            i++;
         }
         if (total > 1) {
-            result.append(endMultiple);
+            sb.append(endMultiple);
         }
-        result.append(end);
+        sb.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 == byte.class) {
-            return String.valueOf(unsafe.getByte(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 == byte[].class) {
-                byte[] byteValue = (byte[]) value;
-                if (isPrintableAsciiString(byteValue)) {
-                    return toString(byteValue);
-                } else {
-                    return Arrays.toString(byteValue);
-                }
-            } else if (!type.getComponentType().isPrimitive()) {
-                return Arrays.toString((Object[]) value);
+    protected 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()) {
+            return String.valueOf(value);
+        }
+        if (type == int[].class) {
+            return Arrays.toString((int[]) value);
+        } else if (type == double[].class) {
+            return Arrays.toString((double[]) value);
+        } else if (type == byte[].class) {
+            byte[] byteValue = (byte[]) value;
+            if (isPrintableAsciiString(byteValue)) {
+                return toString(byteValue);
+            } else {
+                return Arrays.toString(byteValue);
             }
+        } else if (!type.getComponentType().isPrimitive()) {
+            return Arrays.toString((Object[]) value);
         }
         assert false : "unhandled field type: " + type;
         return "";
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java	Fri Oct 03 13:48:58 2014 +0200
@@ -61,21 +61,13 @@
         return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable();
     }
 
-    private static InstructionValueConsumer allowedConsumer = new InstructionValueConsumer() {
-
-        @Override
-        public void visitValue(LIRInstruction op, Value value, OperandMode mode, EnumSet flags) {
-            allowed(op, value, mode, flags);
-        }
-    };
-
     public static boolean verify(final LIRInstruction op) {
 
-        op.visitEachInput(allowedConsumer);
-        op.visitEachAlive(allowedConsumer);
-        op.visitEachState(allowedConsumer);
-        op.visitEachTemp(allowedConsumer);
-        op.visitEachOutput(allowedConsumer);
+        op.visitEachInput(LIRVerifier::allowed);
+        op.visitEachAlive(LIRVerifier::allowed);
+        op.visitEachState(LIRVerifier::allowed);
+        op.visitEachTemp(LIRVerifier::allowed);
+        op.visitEachOutput(LIRVerifier::allowed);
 
         op.verify();
         return true;
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java	Fri Oct 03 13:48:58 2014 +0200
@@ -362,7 +362,7 @@
             /*
              * Value procedure for the instruction's output and temp values
              */
-            class OutputValueConsumer extends ValueConsumer {
+            class OutputValueConsumer implements ValueConsumer {
 
                 int opValueNum;
 
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StateProcedure.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StateProcedure.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StateProcedure.java	Fri Oct 03 13:48:58 2014 +0200
@@ -22,12 +22,13 @@
  */
 package com.oracle.graal.lir;
 
-public abstract class StateProcedure extends InstructionStateProcedure {
+@FunctionalInterface
+public interface StateProcedure extends InstructionStateProcedure {
 
-    protected abstract void doState(LIRFrameState state);
+    void doState(LIRFrameState state);
 
     @Override
-    protected final void doState(LIRInstruction instruction, LIRFrameState state) {
+    default void doState(LIRInstruction instruction, LIRFrameState state) {
         doState(state);
     }
 }
\ No newline at end of file
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValueConsumer.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValueConsumer.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValueConsumer.java	Fri Oct 03 13:48:58 2014 +0200
@@ -25,43 +25,26 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.*;
-import com.oracle.graal.lir.LIRInstruction.*;
+import com.oracle.graal.lir.LIRInstruction.OperandFlag;
+import com.oracle.graal.lir.LIRInstruction.OperandMode;
 
 /**
  * Non-modifying version of {@link ValueProcedure}.
  */
-public abstract class ValueConsumer extends InstructionValueConsumer {
+@FunctionalInterface
+public interface ValueConsumer extends InstructionValueProcedure {
 
     /**
-     * Iterator method to be overwritten. This version of the iterator does not take additional
-     * parameters to keep the signature short.
-     *
-     * @param value The value that is iterated.
-     */
-    protected void visitValue(Value value) {
-        throw GraalInternalError.shouldNotReachHere("One of the visitValue() methods must be overwritten");
-    }
-
-    /**
-     * Iterator method to be overwritten. This version of the iterator gets additional parameters
-     * about the processed value.
+     * Iterator method to be overwritten.
      *
      * @param value The value that is iterated.
      * @param mode The operand mode for the value.
      * @param flags A set of flags for the value.
      */
-    protected void visitValue(Value value, OperandMode mode, EnumSet flags) {
-        visitValue(value);
-    }
+    void visitValue(Value value, OperandMode mode, EnumSet flags);
 
-    @Override
-    protected final void visitValue(LIRInstruction instruction, Value value) {
-        throw GraalInternalError.shouldNotReachHere("This visitValue() method should never be called");
+    default Value doValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet flags) {
+        visitValue(value, mode, flags);
+        return value;
     }
-
-    @Override
-    protected void visitValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet flags) {
-        visitValue(value, mode, flags);
-    }
-}
\ No newline at end of file
+}
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValuePosition.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValuePosition.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValuePosition.java	Fri Oct 03 13:48:58 2014 +0200
@@ -25,14 +25,15 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.lir.LIRInstruction.*;
+import com.oracle.graal.lir.LIRInstruction.OperandFlag;
+import com.oracle.graal.lir.LIRIntrospection.Values;
 
 /**
  * Describes an operand slot for a {@link LIRInstructionClass}.
  */
 public final class ValuePosition {
 
-    private final OperandMode mode;
+    private final Values values;
     private final int index;
     private final int subIndex;
     private final ValuePosition outerPosition;
@@ -40,8 +41,8 @@
     public static final int NO_SUBINDEX = -1;
     public static final ValuePosition ROOT_VALUE_POSITION = null;
 
-    public ValuePosition(OperandMode mode, int index, int subIndex, ValuePosition outerPosition) {
-        this.mode = mode;
+    public ValuePosition(Values values, int index, int subIndex, ValuePosition outerPosition) {
+        this.values = values;
         this.index = index;
         this.subIndex = subIndex;
         this.outerPosition = outerPosition;
@@ -51,20 +52,12 @@
         return outerPosition != ROOT_VALUE_POSITION;
     }
 
-    public Value get(LIRInstruction inst) {
+    public Value get(Object inst) {
         if (isCompositePosition()) {
             CompositeValue compValue = (CompositeValue) outerPosition.get(inst);
             return compValue.getValueClass().getValue(compValue, this);
         }
-        return inst.getLIRInstructionClass().getValue(inst, this);
-    }
-
-    public EnumSet getFlags(LIRInstruction inst) {
-        if (isCompositePosition()) {
-            CompositeValue compValue = (CompositeValue) outerPosition.get(inst);
-            return compValue.getValueClass().getFlags(this);
-        }
-        return inst.getLIRInstructionClass().getFlags(this);
+        return getValue(inst);
     }
 
     public void set(LIRInstruction inst, Value value) {
@@ -73,7 +66,7 @@
             CompositeValue newCompValue = compValue.getValueClass().createUpdatedValue(compValue, this, value);
             outerPosition.set(inst, newCompValue);
         } else {
-            inst.getLIRInstructionClass().setValue(inst, this, value);
+            setValue(inst, value);
         }
     }
 
@@ -85,8 +78,23 @@
         return index;
     }
 
-    public OperandMode getMode() {
-        return mode;
+    public EnumSet getFlags() {
+        return values.getFlags(index);
+    }
+
+    public Value getValue(Object obj) {
+        if (index < values.getDirectCount()) {
+            return values.getValue(obj, index);
+        }
+        return values.getValueArray(obj, index)[subIndex];
+    }
+
+    public void setValue(Object obj, Value value) {
+        if (index < values.getDirectCount()) {
+            values.setValue(obj, index, value);
+        } else {
+            values.getValueArray(obj, index)[subIndex] = value;
+        }
     }
 
     public ValuePosition getSuperPosition() {
@@ -96,9 +104,9 @@
     @Override
     public String toString() {
         if (outerPosition == ROOT_VALUE_POSITION) {
-            return mode.toString() + "(" + index + (subIndex < 0 ? "" : "/" + subIndex) + ")";
+            return values.getMode() + "(" + index + (subIndex < 0 ? "" : "/" + subIndex) + ")";
         }
-        return outerPosition.toString() + "[" + mode.toString() + "(" + index + (subIndex < 0 ? "" : "/" + subIndex) + ")]";
+        return outerPosition.toString() + "[" + values.getMode() + "(" + index + (subIndex < 0 ? "" : "/" + subIndex) + ")]";
     }
 
     @Override
@@ -106,7 +114,7 @@
         final int prime = 31;
         int result = 1;
         result = prime * result + index;
-        result = prime * result + ((mode == null) ? 0 : mode.hashCode());
+        result = prime * result + ((values.getMode() == null) ? 0 : values.getMode().hashCode());
         result = prime * result + subIndex;
         result = prime * result + ((outerPosition == null) ? 0 : outerPosition.hashCode());
         return result;
@@ -127,7 +135,7 @@
         if (index != other.index) {
             return false;
         }
-        if (mode != other.mode) {
+        if (values.getMode() != other.values.getMode()) {
             return false;
         }
         if (subIndex != other.subIndex) {
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValuePositionProcedure.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValuePositionProcedure.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValuePositionProcedure.java	Fri Oct 03 13:48:58 2014 +0200
@@ -25,7 +25,8 @@
 /**
  * Iterator for iterating over a list of {@linkplain ValuePosition value positions}.
  */
-public abstract class ValuePositionProcedure {
+@FunctionalInterface
+public interface ValuePositionProcedure {
 
     /**
      * Iterator method to be overwritten. This version of the iterator does not take additional
@@ -34,6 +35,5 @@
      * @param instruction The current instruction.
      * @param position The position of the value that is iterated.
      */
-
-    public abstract void doValue(LIRInstruction instruction, ValuePosition position);
-}
\ No newline at end of file
+    void doValue(LIRInstruction instruction, ValuePosition position);
+}
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValueProcedure.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValueProcedure.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValueProcedure.java	Fri Oct 03 13:48:58 2014 +0200
@@ -25,45 +25,26 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.*;
-import com.oracle.graal.lir.LIRInstruction.*;
+import com.oracle.graal.lir.LIRInstruction.OperandFlag;
+import com.oracle.graal.lir.LIRInstruction.OperandMode;
 
 /**
  * Similar to {@link InstructionValueProcedure} but without an {@link LIRInstruction} parameter.
  */
-public abstract class ValueProcedure extends InstructionValueProcedure {
+@FunctionalInterface
+public interface ValueProcedure extends InstructionValueProcedure {
 
     /**
-     * Iterator method to be overwritten. This version of the iterator does not take additional
-     * parameters to keep the signature short.
-     *
-     * @param value The value that is iterated.
-     * @return The new value to replace the value that was passed in.
-     */
-    protected Value doValue(Value value) {
-        throw GraalInternalError.shouldNotReachHere("One of the doValue() methods must be overwritten");
-    }
-
-    /**
-     * Iterator method to be overwritten. This version of the iterator gets additional parameters
-     * about the processed value.
+     * Iterator method to be overwritten.
      *
      * @param value The value that is iterated.
      * @param mode The operand mode for the value.
      * @param flags A set of flags for the value.
      * @return The new value to replace the value that was passed in.
      */
-    protected Value doValue(Value value, OperandMode mode, EnumSet flags) {
-        return doValue(value);
-    }
+    Value doValue(Value value, OperandMode mode, EnumSet flags);
 
-    @Override
-    protected final Value doValue(LIRInstruction instruction, Value value) {
-        throw GraalInternalError.shouldNotReachHere("This doValue() method should never be called");
-    }
-
-    @Override
-    public final Value doValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet flags) {
+    default Value doValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet flags) {
         return doValue(value, mode, flags);
     }
-}
\ No newline at end of file
+}
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java	Fri Oct 03 13:48:58 2014 +0200
@@ -32,6 +32,8 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.LIRInstruction.OperandFlag;
+import com.oracle.graal.lir.LIRInstruction.OperandMode;
 import com.oracle.graal.lir.StandardOp.MoveOp;
 import com.oracle.graal.lir.constopt.ConstantTree.Flags;
 import com.oracle.graal.lir.constopt.ConstantTree.NodeCost;
@@ -125,7 +127,7 @@
         ValueConsumer stateConsumer = new ValueConsumer() {
 
             @Override
-            public void visitValue(Value operand) {
+            public void visitValue(Value operand, OperandMode mode, EnumSet flags) {
                 assert !operand.equals(var) : "constant usage through variable in frame state " + var;
             }
         };
@@ -161,55 +163,46 @@
     private void analyzeBlock(AbstractBlock block) {
         try (Indent indent = Debug.logAndIndent("Block: %s", block)) {
 
-            InstructionValueConsumer loadConsumer = new InstructionValueConsumer() {
-                @Override
-                public void visitValue(LIRInstruction instruction, Value value) {
-                    if (isVariable(value)) {
-                        Variable var = (Variable) value;
+            InstructionValueConsumer loadConsumer = (instruction, value, mode, flags) -> {
+                if (isVariable(value)) {
+                    Variable var = (Variable) value;
 
-                        if (!phiConstants.get(var.index)) {
-                            if (!defined.get(var.index)) {
-                                defined.set(var.index);
-                                if (isConstantLoad(instruction)) {
-                                    Debug.log("constant load: %s", instruction);
-                                    map.put(var, new DefUseTree(instruction, block));
-                                    constantsTotal.increment();
-                                }
-                            } else {
-                                // Variable is redefined, this only happens for constant loads
-                                // introduced by phi resolution -> ignore.
-                                DefUseTree removed = map.remove(var);
-                                if (removed != null) {
-                                    phiConstantsSkipped.increment();
-                                }
-                                phiConstants.set(var.index);
-                                Debug.log(3, "Removing phi variable: %s", var);
+                    if (!phiConstants.get(var.index)) {
+                        if (!defined.get(var.index)) {
+                            defined.set(var.index);
+                            if (isConstantLoad(instruction)) {
+                                Debug.log("constant load: %s", instruction);
+                                map.put(var, new DefUseTree(instruction, block));
+                                constantsTotal.increment();
                             }
                         } else {
-                            assert defined.get(var.index) : "phi but not defined? " + var;
+                            // Variable is redefined, this only happens for constant loads
+                            // introduced by phi resolution -> ignore.
+                            DefUseTree removed = map.remove(var);
+                            if (removed != null) {
+                                phiConstantsSkipped.increment();
+                            }
+                            phiConstants.set(var.index);
+                            Debug.log(3, "Removing phi variable: %s", var);
                         }
-
+                    } else {
+                        assert defined.get(var.index) : "phi but not defined? " + var;
                     }
                 }
-
             };
 
-            ValuePositionProcedure useProcedure = new ValuePositionProcedure() {
-                @Override
-                public void doValue(LIRInstruction instruction, ValuePosition position) {
-                    Value value = position.get(instruction);
-                    if (isVariable(value)) {
-                        Variable var = (Variable) value;
-                        if (!phiConstants.get(var.index)) {
-                            DefUseTree tree = map.get(var);
-                            if (tree != null) {
-                                tree.addUsage(block, instruction, position);
-                                Debug.log("usage of %s : %s", var, instruction);
-                            }
+            ValuePositionProcedure useProcedure = (instruction, position) -> {
+                Value value = position.get(instruction);
+                if (isVariable(value)) {
+                    Variable var = (Variable) value;
+                    if (!phiConstants.get(var.index)) {
+                        DefUseTree tree = map.get(var);
+                        if (tree != null) {
+                            tree.addUsage(block, instruction, position);
+                            Debug.log("usage of %s : %s", var, instruction);
                         }
                     }
                 }
-
             };
 
             int opId = 0;
@@ -217,8 +210,8 @@
                 // set instruction id to the index in the lir instruction list
                 inst.setId(opId++);
                 inst.visitEachOutput(loadConsumer);
-                inst.forEachInput(useProcedure);
-                inst.forEachAlive(useProcedure);
+                inst.forEachInputPos(useProcedure);
+                inst.forEachAlivePos(useProcedure);
 
             }
         }
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java	Fri Oct 03 13:48:58 2014 +0200
@@ -111,7 +111,20 @@
     }
 
     @Override
-    public abstract Variable emitMove(Value input);
+    public Variable emitMove(Value input) {
+        Variable result = newVariable(input.getLIRKind());
+        emitMove(result, input);
+        return result;
+    }
+
+    @Override
+    public Value emitLoadConstant(Constant constant) {
+        if (canInlineConstant(constant)) {
+            return constant;
+        } else {
+            return emitMove(constant);
+        }
+    }
 
     public AllocatableValue asAllocatable(Value value) {
         if (isAllocatableValue(value)) {
@@ -128,6 +141,16 @@
         return (Variable) value;
     }
 
+    /**
+     * Checks whether the supplied constant can be used without loading it into a register for most
+     * operations, i.e., for commonly used arithmetic, logical, and comparison operations.
+     *
+     * @param c The constant to check.
+     * @return True if the constant can be used directly, false if the constant needs to be in a
+     *         register.
+     */
+    protected abstract boolean canInlineConstant(Constant c);
+
     public Value loadNonConst(Value value) {
         if (isConstant(value) && !canInlineConstant((Constant) value)) {
             return emitMove(value);
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java	Fri Oct 03 13:48:58 2014 +0200
@@ -52,6 +52,8 @@
 
     void doBlockEnd(AbstractBlock block);
 
+    Value emitLoadConstant(Constant constant);
+
     Value emitLoad(LIRKind kind, Value address, LIRFrameState state);
 
     void emitStore(LIRKind kind, Value address, Value input, LIRFrameState state);
@@ -84,26 +86,6 @@
 
     Variable emitForeignCall(ForeignCallLinkage linkage, LIRFrameState state, Value... args);
 
-    /**
-     * Checks whether the supplied constant can be used without loading it into a register for most
-     * operations, i.e., for commonly used arithmetic, logical, and comparison operations.
-     *
-     * @param c The constant to check.
-     * @return True if the constant can be used directly, false if the constant needs to be in a
-     *         register.
-     */
-    boolean canInlineConstant(Constant c);
-
-    /**
-     * Checks whether the supplied constant can be used without loading it into a register for store
-     * operations, i.e., on the right hand side of a memory access.
-     *
-     * @param c The constant to check.
-     * @return True if the constant can be used directly, false if the constant needs to be in a
-     *         register.
-     */
-    boolean canStoreConstant(Constant c);
-
     RegisterAttributes attributes(Register register);
 
     /**
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java	Fri Oct 03 13:48:58 2014 +0200
@@ -50,7 +50,7 @@
         List bivs = new LinkedList<>();
         LoopBeginNode loopBegin = loop.loopBegin();
         AbstractEndNode forwardEnd = loopBegin.forwardEnd();
-        for (PhiNode phi : loopBegin.phis()) {
+        for (PhiNode phi : loopBegin.phis().filter(ValuePhiNode.class)) {
             ValueNode backValue = phi.singleBackValue();
             if (backValue == PhiNode.MULTIPLE_VALUES) {
                 continue;
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodeinfo.processor/src/com/oracle/graal/nodeinfo/processor/GraphNodeGenerator.java
--- a/graal/com.oracle.graal.nodeinfo.processor/src/com/oracle/graal/nodeinfo/processor/GraphNodeGenerator.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.nodeinfo.processor/src/com/oracle/graal/nodeinfo/processor/GraphNodeGenerator.java	Fri Oct 03 13:48:58 2014 +0200
@@ -46,8 +46,6 @@
  */
 public class GraphNodeGenerator {
 
-    @SuppressWarnings("unused") private static final boolean GENERATE_ASSERTIONS = false;
-
     private final GraphNodeProcessor env;
     private final Types types;
     private final Elements elements;
@@ -57,10 +55,9 @@
     private final TypeElement Successor;
 
     final TypeElement Node;
-    @SuppressWarnings("unused") private final TypeElement NodeList;
     private final TypeElement NodeInputList;
     private final TypeElement NodeSuccessorList;
-    @SuppressWarnings("unused") private final TypeElement Position;
+    private final TypeElement ValueNumberable;
 
     private final List inputFields = new ArrayList<>();
     private final List inputListFields = new ArrayList<>();
@@ -83,10 +80,9 @@
         this.OptionalInput = getTypeElement("com.oracle.graal.graph.Node.OptionalInput");
         this.Successor = getTypeElement("com.oracle.graal.graph.Node.Successor");
         this.Node = getTypeElement("com.oracle.graal.graph.Node");
-        this.NodeList = getTypeElement("com.oracle.graal.graph.NodeList");
         this.NodeInputList = getTypeElement("com.oracle.graal.graph.NodeInputList");
         this.NodeSuccessorList = getTypeElement("com.oracle.graal.graph.NodeSuccessorList");
-        this.Position = getTypeElement("com.oracle.graal.graph.Position");
+        this.ValueNumberable = getTypeElement("com.oracle.graal.graph.Node.ValueNumberable");
     }
 
     @SafeVarargs
@@ -243,6 +239,13 @@
                     if (isAssignableWithErasure(field, NodeSuccessorList)) {
                         throw new ElementException(field, "NodeSuccessorList field must be annotated with @" + Successor.getSimpleName());
                     }
+                    if (modifiers.contains(PUBLIC)) {
+                        if (!modifiers.contains(FINAL)) {
+                            throw new ElementException(field, "Data field must be final if public otherwise it must be protected");
+                        }
+                    } else if (!modifiers.contains(PROTECTED)) {
+                        throw new ElementException(field, "Data field must be protected");
+                    }
                     dataFields.add(field);
                 }
             }
@@ -311,6 +314,8 @@
         for (ExecutableElement constructor : ElementFilter.constructorsIn(node.getEnclosedElements())) {
             if (constructor.getModifiers().contains(PUBLIC)) {
                 throw new ElementException(constructor, "Node class constructor must not be public");
+            } else if (!constructor.getModifiers().contains(PROTECTED)) {
+                throw new ElementException(constructor, "Node class constructor must be protected");
             }
 
             checkFactoryMethodExists(node, constructor);
@@ -322,18 +327,19 @@
 
         if (!constructorsOnly) {
             DeclaredType generatedNode = (DeclaredType) getType(GeneratedNode.class);
-            CodeAnnotationMirror generatedNodeMirror = new CodeAnnotationMirror(generatedNode);
-            generatedNodeMirror.setElementValue(generatedNodeMirror.findExecutableElement("value"), new CodeAnnotationValue(node.asType()));
-            genClass.getAnnotationMirrors().add(generatedNodeMirror);
+            genClass.getImplements().add(generatedNode);
 
             scanFields(node);
 
             boolean hasInputs = !inputFields.isEmpty() || !inputListFields.isEmpty();
             boolean hasSuccessors = !successorFields.isEmpty() || !successorListFields.isEmpty();
 
-            if (hasInputs || hasSuccessors) {
-                createIsLeafNodeMethod();
+            boolean isLeaf = !(hasInputs || hasSuccessors);
+
+            if (isLeaf && isAssignableWithErasure(node, ValueNumberable)) {
+                createValueNumberLeafMethod(node);
             }
+            createDataEqualsMethod();
         }
         compilationUnit.add(genClass);
         return compilationUnit;
@@ -395,7 +401,6 @@
         genClassName = null;
     }
 
-    @SuppressWarnings("unused")
     private CodeVariableElement addParameter(CodeExecutableElement method, TypeMirror type, String name) {
         return addParameter(method, type, name, true);
     }
@@ -425,9 +430,95 @@
         }
     }
 
-    private void createIsLeafNodeMethod() {
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getType(boolean.class), "isLeafNode");
-        method.createBuilder().startReturn().string("false").end();
+    private void createValueNumberLeafMethod(TypeElement node) {
+        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getType(int.class), "valueNumberLeaf");
+        CodeTreeBuilder b = method.createBuilder();
+        b.startStatement().string("int number = " + node.hashCode()).end();
+        for (VariableElement f : dataFields) {
+            String fname = f.getSimpleName().toString();
+            switch (f.asType().getKind()) {
+                case BOOLEAN:
+                    b.startIf().string(fname).end().startBlock();
+                    b.startStatement().string("number += 7").end();
+                    b.end();
+                    break;
+                case BYTE:
+                case SHORT:
+                case CHAR:
+                case INT:
+                    b.startStatement().string("number += 13 * ", fname).end();
+                    break;
+                case FLOAT:
+                    b.startStatement().string("number += 17 * Float.floatToRawIntBits(", fname, ")").end();
+                    break;
+                case LONG:
+                    b.startStatement().string("number += 19 * ", fname + " ^ (", fname, " >>> 32)").end();
+                    break;
+                case DOUBLE:
+                    b.startStatement().string("long longValue = Double.doubleToRawLongBits(", fname, ")").end();
+                    b.startStatement().string("number += 23 * longValue ^ (longValue >>> 32)").end();
+                    break;
+                case ARRAY:
+                    if (((ArrayType) f.asType()).getComponentType().getKind().isPrimitive()) {
+                        b.startStatement().string("number += 31 * Arrays.hashCode(", fname, ")").end();
+                    } else {
+                        b.startStatement().string("number += 31 * Arrays.deepHashCode(", fname, ")").end();
+                    }
+                    break;
+                default:
+                    b.startIf().string(fname, " != null").end().startBlock();
+                    b.startStatement().string("number += 29 * ", fname + ".hashCode()").end();
+                    b.end();
+                    break;
+            }
+        }
+        b.end();
+        b.startReturn().string("number").end();
+        genClass.add(method);
+        checkOnlyInGenNode(method);
+    }
+
+    private void createDataEqualsMethod() {
+        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getType(boolean.class), "dataEquals");
+        addParameter(method, Node.asType(), "other");
+        CodeTreeBuilder b = method.createBuilder();
+        if (!dataFields.isEmpty()) {
+            String other = "o";
+            b.declaration(genClassName, other, "(" + genClassName + ") other");
+
+            for (VariableElement f : dataFields) {
+                String fname = f.getSimpleName().toString();
+                switch (f.asType().getKind()) {
+                    case BOOLEAN:
+                    case BYTE:
+                    case SHORT:
+                    case CHAR:
+                    case INT:
+                    case FLOAT:
+                    case LONG:
+                    case DOUBLE:
+                        b.startIf().string(other, ".", fname, " != ", fname).end().startBlock();
+                        b.startStatement().string("return false").end();
+                        b.end();
+                        break;
+                    case ARRAY:
+                        if (((ArrayType) f.asType()).getComponentType().getKind().isPrimitive()) {
+                            b.startIf().string("!").type(getType(Arrays.class)).string(".equals(", other, ".", fname, ", ", fname, ")").end().startBlock();
+                        } else {
+                            b.startIf().string("!").type(getType(Arrays.class)).string(".deepEquals(", other, ".", fname, ", ", fname, ")").end().startBlock();
+                        }
+                        b.startStatement().string("return false").end();
+                        b.end();
+                        break;
+                    default:
+                        b.startIf().string("!").type(getType(Objects.class)).string(".equals(", other, ".", fname, ", ", fname, ")").end().startBlock();
+                        b.startStatement().string("return false").end();
+                        b.end();
+                        break;
+                }
+            }
+        }
+        b.startReturn().string("true").end();
         genClass.add(method);
         checkOnlyInGenNode(method);
     }
diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodeinfo/src/com/oracle/graal/nodeinfo/GeneratedNode.java
--- a/graal/com.oracle.graal.nodeinfo/src/com/oracle/graal/nodeinfo/GeneratedNode.java	Fri Oct 03 11:07:44 2014 +0200
+++ b/graal/com.oracle.graal.nodeinfo/src/com/oracle/graal/nodeinfo/GeneratedNode.java	Fri Oct 03 13:48:58 2014 +0200
@@ -22,17 +22,27 @@
  */
 package com.oracle.graal.nodeinfo;
 
-import java.lang.annotation.*;
-
 /**
- * Denotes a Node subclass generated on the basis of a {@link NodeInfo} annotation on a Node type.
+ * Marker for a Node class generated on the basis of a {@link NodeInfo} annotation on its super
+ * class.
+ *
+ * Testing whether a node class is generated:
+ *
+ * 
+ * Class c = ...;
+ * if (GeneratedNode.class.isAssignableFrom(c)) { ... }
+ * 
+ * + * Since a generated node class always subclasses the node from which it is generated: + * + *
+ * if (GeneratedNode.class.isAssignableFrom(c)) {
+ *     Class<?> original = c.getSuperclass();
+ * }
+ * 
+ * + * Note: This used to be an annotation but was converted to an interface to avoid annotation parsing + * when creating a NodeClass instance. */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE}) -public @interface GeneratedNode { - - /** - * The Node class from which the annotated type was generated. - */ - Class value(); +public interface GeneratedNode { } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -33,9 +33,9 @@ public abstract class AbstractFixedGuardNode extends DeoptimizingFixedWithNextNode implements Simplifiable, GuardingNode { @Input(InputType.Condition) protected LogicNode condition; - private final DeoptimizationReason reason; - private final DeoptimizationAction action; - private boolean negated; + protected final DeoptimizationReason reason; + protected final DeoptimizationAction action; + protected boolean negated; public LogicNode condition() { return condition; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractLocalNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractLocalNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractLocalNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -29,7 +29,7 @@ @NodeInfo public abstract class AbstractLocalNode extends FloatingNode { - private final int index; + protected final int index; public AbstractLocalNode(int index, Stamp stamp) { super(stamp); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -44,8 +44,8 @@ } @Input protected NodeInputList arguments; - private ResolvedJavaMethod targetMethod; - private InvokeKind invokeKind; + protected ResolvedJavaMethod targetMethod; + protected InvokeKind invokeKind; public CallTargetNode(ValueNode[] arguments, ResolvedJavaMethod targetMethod, InvokeKind invokeKind) { super(StampFactory.forVoid()); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -33,7 +33,7 @@ public class ConditionAnchorNode extends FixedWithNextNode implements Canonicalizable.Unary, Lowerable, GuardingNode { @Input(InputType.Condition) LogicNode condition; - private boolean negated; + protected boolean negated; public static ConditionAnchorNode create(LogicNode condition) { return USE_GENERATED_NODES ? new ConditionAnchorNodeGen(condition) : new ConditionAnchorNode(condition); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -43,7 +43,7 @@ private static final DebugMetric ConstantNodes = Debug.metric("ConstantNodes"); - private final Constant value; + protected final Constant value; private static ConstantNode createPrimitive(Constant value) { assert value.getKind() != Kind.Object; @@ -91,10 +91,10 @@ @Override public void generate(NodeLIRBuilderTool gen) { - if (gen.getLIRGeneratorTool().canInlineConstant(value) || onlyUsedInVirtualState()) { + if (onlyUsedInVirtualState()) { gen.setResult(this, value); } else { - gen.setResult(this, gen.getLIRGeneratorTool().emitMove(value)); + gen.setResult(this, gen.getLIRGeneratorTool().emitLoadConstant(value)); } } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -29,10 +29,10 @@ @NodeInfo(shortName = "Deopt", nameTemplate = "Deopt {p#reason/s}") public class DeoptimizeNode extends AbstractDeoptimizeNode implements Lowerable, LIRLowerable { - private final DeoptimizationAction action; - private final DeoptimizationReason reason; - private final int debugId; - private final Constant speculation; + protected final DeoptimizationAction action; + protected final DeoptimizationReason reason; + protected final int debugId; + protected final Constant speculation; public static DeoptimizeNode create(DeoptimizationAction action, DeoptimizationReason reason) { return USE_GENERATED_NODES ? new DeoptimizeNodeGen(action, reason) : new DeoptimizeNode(action, reason); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EndNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EndNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EndNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -30,6 +30,6 @@ return USE_GENERATED_NODES ? new EndNodeGen() : new EndNode(); } - EndNode() { + protected EndNode() { } } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -39,7 +39,7 @@ return USE_GENERATED_NODES ? new EntryMarkerNodeGen() : new EntryMarkerNode(); } - EntryMarkerNode() { + protected EntryMarkerNode() { } @Override diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Fri Oct 03 13:48:58 2014 +0200 @@ -51,9 +51,9 @@ /** * @see BytecodeFrame#rethrowException */ - private boolean rethrowException; + protected boolean rethrowException; - private boolean duringCall; + protected boolean duringCall; @OptionalInput(value = InputType.State) FrameState outerFrameState; @@ -71,7 +71,7 @@ */ public final int bci; - private final ResolvedJavaMethod method; + protected final ResolvedJavaMethod method; /** * Creates a {@code FrameState} with the given locals, stack expressions and locked monitors. diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -45,10 +45,10 @@ public class GuardNode extends FloatingAnchoredNode implements Canonicalizable, IterableNodeType, GuardingNode { @Input(InputType.Condition) protected LogicNode condition; - private final DeoptimizationReason reason; - private Constant speculation; - private DeoptimizationAction action; - private boolean negated; + protected final DeoptimizationReason reason; + protected Constant speculation; + protected DeoptimizationAction action; + protected boolean negated; public static GuardNode create(LogicNode condition, AnchoringNode anchor, DeoptimizationReason reason, DeoptimizationAction action, boolean negated, Constant speculation) { return USE_GENERATED_NODES ? new GuardNodeGen(condition, anchor, reason, action, negated, speculation) : new GuardNode(condition, anchor, reason, action, negated, speculation); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -40,7 +40,7 @@ public class GuardedValueNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, IterableNodeType, Canonicalizable, ValueProxy { @Input ValueNode object; - private final Stamp piStamp; + protected final Stamp piStamp; public static GuardedValueNode create(ValueNode object, GuardingNode guard, Stamp stamp) { return USE_GENERATED_NODES ? new GuardedValueNodeGen(object, guard, stamp) : new GuardedValueNode(object, guard, stamp); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -40,10 +40,10 @@ @Input ValueNode object; @Input(InputType.Condition) LogicNode condition; - private final DeoptimizationReason reason; - private final DeoptimizationAction action; - private final Stamp piStamp; - private boolean negated; + protected final DeoptimizationReason reason; + protected final DeoptimizationAction action; + protected final Stamp piStamp; + protected boolean negated; public ValueNode object() { return object; @@ -72,7 +72,7 @@ return USE_GENERATED_NODES ? new GuardingPiNodeGen(object) : new GuardingPiNode(object); } - GuardingPiNode(ValueNode object) { + protected GuardingPiNode(ValueNode object) { this(object, object.graph().unique(IsNullNode.create(object)), true, DeoptimizationReason.NullCheckException, DeoptimizationAction.None, object.stamp().join(StampFactory.objectNonNull())); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -52,7 +52,7 @@ @Successor BeginNode trueSuccessor; @Successor BeginNode falseSuccessor; @Input(InputType.Condition) LogicNode condition; - private double trueSuccessorProbability; + protected double trueSuccessorProbability; public LogicNode condition() { return condition; @@ -228,14 +228,15 @@ FixedWithNextNode falseNext = (FixedWithNextNode) falseSucc.next(); NodeClass nodeClass = trueNext.getNodeClass(); if (trueNext.getClass() == falseNext.getClass()) { - if (nodeClass.getEdges(Inputs).areEqualIn(trueNext, falseNext) && nodeClass.valueEqual(trueNext, falseNext)) { + if (nodeClass.getEdges(Inputs).areEqualIn(trueNext, falseNext) && trueNext.valueEquals(falseNext)) { falseNext.replaceAtUsages(trueNext); graph().removeFixed(falseNext); GraphUtil.unlinkFixedNode(trueNext); graph().addBeforeFixed(this, trueNext); for (Node usage : trueNext.usages().snapshot()) { if (usage.isAlive()) { - if (usage.getNodeClass().valueNumberable() && !usage.isLeafNode()) { + NodeClass usageNodeClass = usage.getNodeClass(); + if (usageNodeClass.valueNumberable() && !usageNodeClass.isLeafNode()) { Node newNode = graph().findDuplicate(usage); if (newNode != null) { usage.replaceAtUsages(newNode); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -28,7 +28,7 @@ @NodeInfo public abstract class InfopointNode extends FixedWithNextNode { - private final InfopointReason reason; + protected final InfopointReason reason; public InfopointNode(InfopointReason reason) { super(StampFactory.forVoid()); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -42,9 +42,9 @@ @Input(InputType.Extension) CallTargetNode callTarget; @OptionalInput(InputType.State) FrameState stateDuring; @OptionalInput(InputType.Guard) GuardingNode guard; - private final int bci; - private boolean polymorphic; - private boolean useForInlining; + protected final int bci; + protected boolean polymorphic; + protected boolean useForInlining; /** * Constructs a new Invoke instruction. diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -43,10 +43,10 @@ @OptionalInput(InputType.State) FrameState stateDuring; @OptionalInput(InputType.State) FrameState stateAfter; @OptionalInput(InputType.Guard) GuardingNode guard; - private final int bci; - private boolean polymorphic; - private boolean useForInlining; - private double exceptionProbability; + protected final int bci; + protected boolean polymorphic; + protected boolean useForInlining; + protected double exceptionProbability; public static InvokeWithExceptionNode create(CallTargetNode callTarget, BeginNode exceptionEdge, int bci) { return USE_GENERATED_NODES ? new InvokeWithExceptionNodeGen(callTarget, exceptionEdge, bci) : new InvokeWithExceptionNode(callTarget, exceptionEdge, bci); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -29,7 +29,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public class KillingBeginNode extends BeginNode implements MemoryCheckpoint.Single { - private LocationIdentity locationIdentity; + protected LocationIdentity locationIdentity; public static KillingBeginNode create(LocationIdentity locationIdentity) { return USE_GENERATED_NODES ? new KillingBeginNodeGen(locationIdentity) : new KillingBeginNode(locationIdentity); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConstantNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConstantNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConstantNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -32,7 +32,7 @@ @NodeInfo(nameTemplate = "{p#value}") public class LogicConstantNode extends LogicNode implements LIRLowerable { - public final boolean value; + protected final boolean value; public static LogicConstantNode create(boolean value) { return USE_GENERATED_NODES ? new LogicConstantNodeGen(value) : new LogicConstantNode(value); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -39,9 +39,9 @@ @NodeInfo public class LoopBeginNode extends MergeNode implements IterableNodeType, LIRLowerable { - private double loopFrequency; - private int nextEndIndex; - private int unswitches; + protected double loopFrequency; + protected int nextEndIndex; + protected int unswitches; @OptionalInput(InputType.Guard) GuardingNode overflowGuard; public static LoopBeginNode create() { @@ -283,7 +283,7 @@ if (phi != null) { nextPhi: for (int otherPhiIndex = phiIndex + 1; otherPhiIndex < phiCount; otherPhiIndex++) { PhiNode otherPhi = phis[otherPhiIndex]; - if (otherPhi == null || phi.getNodeClass() != otherPhi.getNodeClass() || !phi.getNodeClass().valueEqual(phi, otherPhi)) { + if (otherPhi == null || phi.getNodeClass() != otherPhi.getNodeClass() || !phi.valueEquals(otherPhi)) { continue nextPhi; } if (selfIncrement[phiIndex] == null) { diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopEndNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopEndNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopEndNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -32,8 +32,8 @@ public class LoopEndNode extends AbstractEndNode { @Input(InputType.Association) LoopBeginNode loopBegin; - private boolean canSafepoint; - private int endIndex; + protected boolean canSafepoint; + protected int endIndex; public static LoopEndNode create(LoopBeginNode begin) { return USE_GENERATED_NODES ? new LoopEndNodeGen(begin) : new LoopEndNode(begin); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoweredCallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoweredCallTargetNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoweredCallTargetNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -32,9 +32,9 @@ @NodeInfo public abstract class LoweredCallTargetNode extends CallTargetNode { - private final Stamp returnStamp; - private final JavaType[] signature; - private final CallingConvention.Type callType; + protected final Stamp returnStamp; + protected final JavaType[] signature; + protected final CallingConvention.Type callType; public LoweredCallTargetNode(List arguments, Stamp returnStamp, JavaType[] signature, ResolvedJavaMethod target, CallingConvention.Type callType, InvokeKind invokeKind) { super(arguments, target, invokeKind); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -37,7 +37,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Extension}) public class MemoryMapNode extends FloatingNode implements MemoryMap, LIRLowerable { - private final List locationIdentities; + protected final List locationIdentities; @Input(InputType.Memory) NodeInputList nodes; private boolean checkOrder(Map mmap) { diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -35,7 +35,7 @@ public class MemoryPhiNode extends PhiNode implements MemoryNode { @Input(InputType.Memory) NodeInputList values; - private final LocationIdentity locationIdentity; + protected final LocationIdentity locationIdentity; public static MemoryPhiNode create(MergeNode merge, LocationIdentity locationIdentity) { return USE_GENERATED_NODES ? new MemoryPhiNodeGen(merge, locationIdentity) : new MemoryPhiNode(merge, locationIdentity); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -45,7 +45,7 @@ public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, IterableNodeType, Canonicalizable, ValueProxy { @Input ValueNode object; - private final Stamp piStamp; + protected final Stamp piStamp; public ValueNode object() { return object; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -31,9 +31,9 @@ @Input(InputType.Condition) LogicNode x; @Input(InputType.Condition) LogicNode y; - private boolean xNegated; - private boolean yNegated; - private double shortCircuitProbability; + protected boolean xNegated; + protected boolean yNegated; + protected double shortCircuitProbability; public static ShortCircuitOrNode create(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, double shortCircuitProbability) { return USE_GENERATED_NODES ? new ShortCircuitOrNodeGen(x, xNegated, y, yNegated, shortCircuitProbability) : new ShortCircuitOrNode(x, xNegated, y, yNegated, shortCircuitProbability); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimpleInfopointNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimpleInfopointNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SimpleInfopointNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -30,7 +30,7 @@ @NodeInfo public class SimpleInfopointNode extends InfopointNode implements LIRLowerable, IterableNodeType, Simplifiable { - private BytecodePosition position; + protected BytecodePosition position; public static SimpleInfopointNode create(InfopointReason reason, BytecodePosition position) { return USE_GENERATED_NODES ? new SimpleInfopointNodeGen(reason, position) : new SimpleInfopointNode(reason, position); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -39,9 +39,9 @@ @NodeInfo public class TypeProfileProxyNode extends UnaryNode implements IterableNodeType, ValueProxy { - private final JavaTypeProfile profile; - private transient ResolvedJavaType lastCheckedType; - private transient JavaTypeProfile lastCheckedProfile; + protected final JavaTypeProfile profile; + protected transient ResolvedJavaType lastCheckedType; + protected transient JavaTypeProfile lastCheckedProfile; public static ValueNode proxify(ValueNode object, JavaTypeProfile profile) { if (StampTool.isExactType(object)) { @@ -62,7 +62,7 @@ return USE_GENERATED_NODES ? new TypeProfileProxyNodeGen(object, profile) : new TypeProfileProxyNode(object, profile); } - TypeProfileProxyNode(ValueNode value, JavaTypeProfile profile) { + protected TypeProfileProxyNode(ValueNode value, JavaTypeProfile profile) { super(value.stamp(), value); this.profile = profile; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -38,7 +38,7 @@ * The kind of this value. This is {@link Kind#Void} for instructions that produce no value. * This kind is guaranteed to be a {@linkplain Kind#getStackKind() stack kind}. */ - private Stamp stamp; + protected Stamp stamp; public ValueNode(Stamp stamp) { this.stamp = stamp; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -95,9 +95,9 @@ assert op1 != null : getX() + ", this=" + this; Value op2 = builder.operand(getY()); if (!getY().isConstant() && !BinaryArithmeticNode.livesLonger(this, getY(), builder)) { - Value op = op1; + Value tmp = op1; op1 = op2; - op2 = op; + op2 = tmp; } builder.setResult(this, gen.emitAdd(op1, op2)); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -39,7 +39,7 @@ return USE_GENERATED_NODES ? new AndNodeGen(x, y) : new AndNode(x, y); } - AndNode(ValueNode x, ValueNode y) { + protected AndNode(ValueNode x, ValueNode y) { super(ArithmeticOpTable.forStamp(x.stamp()).getAnd(), x, y); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -35,7 +35,7 @@ @NodeInfo public abstract class BinaryArithmeticNode extends BinaryNode implements ArithmeticLIRLowerable { - private final BinaryOp op; + protected final BinaryOp op; public BinaryArithmeticNode(BinaryOp op, ValueNode x, ValueNode y) { super(op.foldStamp(x.stamp(), y.stamp()), x, y); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -131,7 +131,7 @@ return USE_GENERATED_NODES ? new ConditionalNodeGen(graph, condition, x, y) : new ConditionalNode(graph, condition, x, y); } - ConditionalNode(StructuredGraph graph, Condition condition, ValueNode x, ValueNode y) { + protected ConditionalNode(StructuredGraph graph, Condition condition, ValueNode x, ValueNode y) { this(createCompareNode(graph, condition, x, y)); } @@ -139,7 +139,7 @@ return USE_GENERATED_NODES ? new ConditionalNodeGen(type, object) : new ConditionalNode(type, object); } - ConditionalNode(ValueNode type, ValueNode object) { + protected ConditionalNode(ValueNode type, ValueNode object) { this(type.graph().unique(InstanceOfDynamicNode.create(type, object))); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -39,7 +39,7 @@ @NodeInfo public class FloatConvertNode extends ConvertNode implements Lowerable, ArithmeticLIRLowerable { - private final FloatConvert op; + protected final FloatConvert op; public static FloatConvertNode create(FloatConvert op, ValueNode input) { return USE_GENERATED_NODES ? new FloatConvertNodeGen(op, input) : new FloatConvertNode(op, input); @@ -83,10 +83,12 @@ return StampFactory.forKind(Kind.Long); case I2F: case L2F: + return StampFactory.forFloat(Kind.Float, ((IntegerStamp) input.stamp()).lowerBound(), ((IntegerStamp) input.stamp()).upperBound(), true); case D2F: return StampFactory.forKind(Kind.Float); case I2D: case L2D: + return StampFactory.forFloat(Kind.Double, ((IntegerStamp) input.stamp()).lowerBound(), ((IntegerStamp) input.stamp()).upperBound(), true); case F2D: return StampFactory.forKind(Kind.Double); default: diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -33,7 +33,7 @@ @NodeInfo(shortName = "<") public class FloatLessThanNode extends CompareNode { - private final boolean unorderedIsTrue; + protected final boolean unorderedIsTrue; /** * Constructs a new floating point comparison node. diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -33,7 +33,7 @@ @NodeInfo public abstract class IntegerConvertNode extends ConvertNode implements ArithmeticLIRLowerable { - private final int resultBits; + protected final int resultBits; protected IntegerConvertNode(Stamp stamp, ValueNode input, int resultBits) { super(stamp, input); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -99,7 +99,7 @@ if (next() instanceof IntegerDivNode) { NodeClass nodeClass = getNodeClass(); - if (next().getClass() == this.getClass() && nodeClass.getEdges(Inputs).areEqualIn(this, next()) && nodeClass.valueEqual(this, next())) { + if (next().getClass() == this.getClass() && nodeClass.getEdges(Inputs).areEqualIn(this, next()) && valueEquals(next())) { return next(); } } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -103,9 +103,9 @@ Value op1 = builder.operand(getX()); Value op2 = builder.operand(getY()); if (!getY().isConstant() && !BinaryArithmeticNode.livesLonger(this, getY(), builder)) { - Value op = op1; + Value tmp = op1; op1 = op2; - op2 = op; + op2 = tmp; } builder.setResult(this, gen.emitMul(op1, op2)); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -44,7 +44,7 @@ return USE_GENERATED_NODES ? new NegateNodeGen(value) : new NegateNode(value); } - NegateNode(ValueNode value) { + protected NegateNode(ValueNode value) { super(ArithmeticOpTable.forStamp(value.stamp()).getNeg(), value); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -37,7 +37,7 @@ @NodeInfo public class NormalizeCompareNode extends BinaryNode implements Lowerable { - public final boolean isUnorderedLess; + protected final boolean isUnorderedLess; /** * Creates a new compare operation. diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -39,7 +39,7 @@ return USE_GENERATED_NODES ? new OrNodeGen(x, y) : new OrNode(x, y); } - OrNode(ValueNode x, ValueNode y) { + protected OrNode(ValueNode x, ValueNode y) { super(ArithmeticOpTable.forStamp(x.stamp()).getOr(), x, y); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -43,7 +43,7 @@ return USE_GENERATED_NODES ? new ReinterpretNodeGen(to, value) : new ReinterpretNode(to, value); } - ReinterpretNode(Kind to, ValueNode value) { + protected ReinterpretNode(Kind to, ValueNode value) { this(StampFactory.forKind(to), value); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnaryArithmeticNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnaryArithmeticNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnaryArithmeticNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -32,7 +32,7 @@ @NodeInfo public abstract class UnaryArithmeticNode extends UnaryNode implements ArithmeticLIRLowerable { - private final UnaryOp op; + protected final UnaryOp op; protected UnaryArithmeticNode(UnaryOp op, ValueNode value) { super(op.foldStamp(value.stamp()), value); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -40,15 +40,15 @@ @Input ValueNode increment; - private final String name; - private final String group; - private final boolean withContext; + protected final String name; + protected final String group; + protected final boolean withContext; public static DynamicCounterNode create(String name, String group, ValueNode increment, boolean withContext) { return USE_GENERATED_NODES ? new DynamicCounterNodeGen(name, group, increment, withContext) : new DynamicCounterNode(name, group, increment, withContext); } - DynamicCounterNode(String name, String group, ValueNode increment, boolean withContext) { + protected DynamicCounterNode(String name, String group, ValueNode increment, boolean withContext) { super(StampFactory.forVoid()); this.name = name; this.group = group; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/WeakCounterNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/WeakCounterNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/WeakCounterNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -42,7 +42,7 @@ return USE_GENERATED_NODES ? new WeakCounterNodeGen(group, name, increment, addContext, checkedValue) : new WeakCounterNode(group, name, increment, addContext, checkedValue); } - WeakCounterNode(String group, String name, ValueNode increment, boolean addContext, ValueNode checkedValue) { + protected WeakCounterNode(String group, String name, ValueNode increment, boolean addContext, ValueNode checkedValue) { super(group, name, increment, addContext); this.checkedValue = checkedValue; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -35,7 +35,7 @@ @OptionalInput(InputType.State) FrameState stateAfter; @OptionalInput(InputType.Memory) Node lastLocationAccess; - private final boolean initialization; + protected final boolean initialization; public FrameState stateAfter() { return stateAfter; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -59,7 +59,7 @@ return USE_GENERATED_NODES ? new AddLocationNodeGen(x, y) : new AddLocationNode(x, y); } - AddLocationNode(ValueNode x, ValueNode y) { + protected AddLocationNode(ValueNode x, ValueNode y) { super(StampFactory.forVoid()); this.x = x; this.y = y; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -42,13 +42,13 @@ @NodeInfo public class BoxNode extends UnaryNode implements VirtualizableAllocation, Lowerable { - private final Kind boxingKind; + protected final Kind boxingKind; public static BoxNode create(ValueNode value, ResolvedJavaType resultType, Kind boxingKind) { return USE_GENERATED_NODES ? new BoxNodeGen(value, resultType, boxingKind) : new BoxNode(value, resultType, boxingKind); } - BoxNode(ValueNode value, ResolvedJavaType resultType, Kind boxingKind) { + protected BoxNode(ValueNode value, ResolvedJavaType resultType, Kind boxingKind) { super(StampFactory.exactNonNull(resultType), value); this.boxingKind = boxingKind; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -57,7 +57,7 @@ return USE_GENERATED_NODES ? new BranchProbabilityNodeGen(probability, condition) : new BranchProbabilityNode(probability, condition); } - BranchProbabilityNode(ValueNode probability, ValueNode condition) { + protected BranchProbabilityNode(ValueNode probability, ValueNode condition) { super(condition.stamp()); this.probability = probability; this.condition = condition; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BytecodeExceptionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BytecodeExceptionNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BytecodeExceptionNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -36,14 +36,14 @@ @NodeInfo public class BytecodeExceptionNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single { - private final Class exceptionClass; + protected final Class exceptionClass; @Input NodeInputList arguments; public static BytecodeExceptionNode create(MetaAccessProvider metaAccess, Class exceptionClass, ValueNode... arguments) { return USE_GENERATED_NODES ? new BytecodeExceptionNodeGen(metaAccess, exceptionClass, arguments) : new BytecodeExceptionNode(metaAccess, exceptionClass, arguments); } - BytecodeExceptionNode(MetaAccessProvider metaAccess, Class exceptionClass, ValueNode... arguments) { + protected BytecodeExceptionNode(MetaAccessProvider metaAccess, Class exceptionClass, ValueNode... arguments) { super(StampFactory.exactNonNull(metaAccess.lookupJavaType(exceptionClass))); this.exceptionClass = exceptionClass; this.arguments = new NodeInputList<>(this, arguments); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ComputeAddressNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ComputeAddressNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ComputeAddressNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -47,7 +47,7 @@ return USE_GENERATED_NODES ? new ComputeAddressNodeGen(object, location, stamp) : new ComputeAddressNode(object, location, stamp); } - ComputeAddressNode(ValueNode object, ValueNode location, Stamp stamp) { + protected ComputeAddressNode(ValueNode object, ValueNode location, Stamp stamp) { super(stamp); this.object = object; this.location = location; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -36,9 +36,9 @@ @NodeInfo(nameTemplate = "Loc {p#locationIdentity/s}") public class ConstantLocationNode extends LocationNode { - private final Kind valueKind; - private final LocationIdentity locationIdentity; - private final long displacement; + protected final Kind valueKind; + protected final LocationIdentity locationIdentity; + protected final long displacement; public static ConstantLocationNode create(LocationIdentity identity, Kind kind, long displacement, Graph graph) { return graph.unique(ConstantLocationNode.create(identity, kind, displacement)); @@ -48,7 +48,7 @@ return USE_GENERATED_NODES ? new ConstantLocationNodeGen(identity, kind, displacement) : new ConstantLocationNode(identity, kind, displacement); } - ConstantLocationNode(LocationIdentity identity, Kind kind, long displacement) { + protected ConstantLocationNode(LocationIdentity identity, Kind kind, long displacement) { super(StampFactory.forVoid()); assert kind != Kind.Illegal && kind != Kind.Void; this.valueKind = kind; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -36,8 +36,8 @@ @OptionalInput(InputType.Guard) protected GuardingNode guard; @Input protected ValueNode object; @Input(InputType.Association) protected ValueNode location; - private boolean nullCheck; - private BarrierType barrierType; + protected boolean nullCheck; + protected BarrierType barrierType; public ValueNode object() { return object; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedValueAnchorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedValueAnchorNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedValueAnchorNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -40,7 +40,7 @@ return USE_GENERATED_NODES ? new FixedValueAnchorNodeGen(object) : new FixedValueAnchorNode(object); } - FixedValueAnchorNode(ValueNode object) { + protected FixedValueAnchorNode(ValueNode object) { super(StampFactory.forNodeIntrinsic()); this.object = object; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -32,7 +32,7 @@ @Input ValueNode object; @Input(InputType.Association) LocationNode location; - private BarrierType barrierType; + protected BarrierType barrierType; public ValueNode object() { return object; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -43,7 +43,7 @@ return USE_GENERATED_NODES ? new FloatingReadNodeGen(object, location, lastLocationAccess, stamp) : new FloatingReadNode(object, location, lastLocationAccess, stamp); } - FloatingReadNode(ValueNode object, LocationNode location, MemoryNode lastLocationAccess, Stamp stamp) { + protected FloatingReadNode(ValueNode object, LocationNode location, MemoryNode lastLocationAccess, Stamp stamp) { this(object, location, lastLocationAccess, stamp, null, BarrierType.NONE); } @@ -51,7 +51,7 @@ return USE_GENERATED_NODES ? new FloatingReadNodeGen(object, location, lastLocationAccess, stamp, guard) : new FloatingReadNode(object, location, lastLocationAccess, stamp, guard); } - FloatingReadNode(ValueNode object, LocationNode location, MemoryNode lastLocationAccess, Stamp stamp, GuardingNode guard) { + protected FloatingReadNode(ValueNode object, LocationNode location, MemoryNode lastLocationAccess, Stamp stamp, GuardingNode guard) { this(object, location, lastLocationAccess, stamp, guard, BarrierType.NONE); } @@ -60,7 +60,7 @@ guard, barrierType); } - FloatingReadNode(ValueNode object, LocationNode location, MemoryNode lastLocationAccess, Stamp stamp, GuardingNode guard, BarrierType barrierType) { + protected FloatingReadNode(ValueNode object, LocationNode location, MemoryNode lastLocationAccess, Stamp stamp, GuardingNode guard, BarrierType barrierType) { super(object, location, stamp, guard, barrierType); this.lastLocationAccess = lastLocationAccess; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -40,9 +40,9 @@ @Input protected NodeInputList arguments; @OptionalInput(InputType.State) protected FrameState stateDuring; - private final ForeignCallsProvider foreignCalls; + protected final ForeignCallsProvider foreignCalls; - private final ForeignCallDescriptor descriptor; + protected final ForeignCallDescriptor descriptor; public static ForeignCallNode create(@InjectedNodeParameter ForeignCallsProvider foreignCalls, ForeignCallDescriptor descriptor, ValueNode... arguments) { return USE_GENERATED_NODES ? new ForeignCallNodeGen(foreignCalls, descriptor, arguments) : new ForeignCallNode(foreignCalls, descriptor, arguments); @@ -59,7 +59,7 @@ return USE_GENERATED_NODES ? new ForeignCallNodeGen(foreignCalls, descriptor, arguments) : new ForeignCallNode(foreignCalls, descriptor, arguments); } - ForeignCallNode(ForeignCallsProvider foreignCalls, ForeignCallDescriptor descriptor, List arguments) { + protected ForeignCallNode(ForeignCallsProvider foreignCalls, ForeignCallDescriptor descriptor, List arguments) { this(foreignCalls, descriptor, StampFactory.forKind(Kind.fromJavaClass(descriptor.getResultType())), arguments); } @@ -67,7 +67,7 @@ return USE_GENERATED_NODES ? new ForeignCallNodeGen(foreignCalls, descriptor, stamp, arguments) : new ForeignCallNode(foreignCalls, descriptor, stamp, arguments); } - ForeignCallNode(ForeignCallsProvider foreignCalls, ForeignCallDescriptor descriptor, Stamp stamp, List arguments) { + protected ForeignCallNode(ForeignCallsProvider foreignCalls, ForeignCallDescriptor descriptor, Stamp stamp, List arguments) { super(stamp); this.arguments = new NodeInputList<>(this, arguments); this.descriptor = descriptor; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -41,11 +41,11 @@ @NodeInfo(nameTemplate = "IdxLoc {p#locationIdentity/s}") public class IndexedLocationNode extends LocationNode implements Canonicalizable { - private final Kind valueKind; - private final LocationIdentity locationIdentity; - private final long displacement; + protected final Kind valueKind; + protected final LocationIdentity locationIdentity; + protected final long displacement; @Input ValueNode index; - private final int indexScaling; + protected final int indexScaling; /** * Gets the index or offset of this location. @@ -73,7 +73,7 @@ return USE_GENERATED_NODES ? new IndexedLocationNodeGen(identity, kind, displacement, index, indexScaling) : new IndexedLocationNode(identity, kind, displacement, index, indexScaling); } - IndexedLocationNode(LocationIdentity identity, Kind kind, long displacement, ValueNode index, int indexScaling) { + protected IndexedLocationNode(LocationIdentity identity, Kind kind, long displacement, ValueNode index, int indexScaling) { super(StampFactory.forVoid()); assert index != null; assert indexScaling != 0; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -39,7 +39,7 @@ @NodeInfo public class IntegerSwitchNode extends SwitchNode implements LIRLowerable, Simplifiable { - private final int[] keys; + protected final int[] keys; /** * Constructs a integer switch instruction. The keyProbabilities and keySuccessors array contain @@ -56,7 +56,7 @@ keySuccessors); } - IntegerSwitchNode(ValueNode value, BeginNode[] successors, int[] keys, double[] keyProbabilities, int[] keySuccessors) { + protected IntegerSwitchNode(ValueNode value, BeginNode[] successors, int[] keys, double[] keyProbabilities, int[] keySuccessors) { super(value, successors, keySuccessors, keyProbabilities); assert keySuccessors.length == keys.length + 1; assert keySuccessors.length == keyProbabilities.length; @@ -87,7 +87,7 @@ keySuccessors); } - IntegerSwitchNode(ValueNode value, int successorCount, int[] keys, double[] keyProbabilities, int[] keySuccessors) { + protected IntegerSwitchNode(ValueNode value, int successorCount, int[] keys, double[] keyProbabilities, int[] keySuccessors) { this(value, new BeginNode[successorCount], keys, keyProbabilities, keySuccessors); } @@ -148,11 +148,11 @@ tool.addToWorkList(blockSuccessor(survivingEdge)); graph().removeSplit(this, blockSuccessor(survivingEdge)); } else if (value().stamp() instanceof IntegerStamp) { - IntegerStamp stamp = (IntegerStamp) value().stamp(); - if (!stamp.isUnrestricted()) { + IntegerStamp integerStamp = (IntegerStamp) value().stamp(); + if (!integerStamp.isUnrestricted()) { int validKeys = 0; for (int i = 0; i < keyCount(); i++) { - if (stamp.contains(keys[i])) { + if (integerStamp.contains(keys[i])) { validKeys++; } } @@ -167,7 +167,7 @@ double totalProbability = 0; int current = 0; for (int i = 0; i < keyCount() + 1; i++) { - if (i == keyCount() || stamp.contains(keys[i])) { + if (i == keyCount() || integerStamp.contains(keys[i])) { int index = newSuccessors.indexOf(keySuccessor(i)); if (index == -1) { index = newSuccessors.size(); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -34,13 +34,13 @@ @NodeInfo public class JavaReadNode extends FixedAccessNode implements Lowerable, GuardingNode { - private final boolean compressible; + protected final boolean compressible; public static JavaReadNode create(ValueNode object, LocationNode location, BarrierType barrierType, boolean compressible) { return USE_GENERATED_NODES ? new JavaReadNodeGen(object, location, barrierType, compressible) : new JavaReadNode(object, location, barrierType, compressible); } - JavaReadNode(ValueNode object, LocationNode location, BarrierType barrierType, boolean compressible) { + protected JavaReadNode(ValueNode object, LocationNode location, BarrierType barrierType, boolean compressible) { super(object, location, StampFactory.forKind(location.getValueKind()), barrierType); this.compressible = compressible; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaWriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaWriteNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaWriteNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -33,14 +33,14 @@ @NodeInfo public class JavaWriteNode extends AbstractWriteNode implements Lowerable, StateSplit, MemoryAccess, MemoryCheckpoint.Single { - private final boolean compressible; + protected final boolean compressible; public static JavaWriteNode create(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean compressible, boolean initialization) { return USE_GENERATED_NODES ? new JavaWriteNodeGen(object, value, location, barrierType, compressible, initialization) : new JavaWriteNode(object, value, location, barrierType, compressible, initialization); } - JavaWriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean compressible, boolean initialization) { + protected JavaWriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean compressible, boolean initialization) { super(object, value, location, barrierType, initialization); this.compressible = compressible; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -47,7 +47,7 @@ return USE_GENERATED_NODES ? new LoadHubNodeGen(value, kind) : new LoadHubNode(value, kind); } - LoadHubNode(ValueNode value, Kind kind) { + protected LoadHubNode(ValueNode value, Kind kind) { super(getKind(kind), null); this.value = value; } @@ -56,7 +56,7 @@ return USE_GENERATED_NODES ? new LoadHubNodeGen(value, kind, guard) : new LoadHubNode(value, kind, guard); } - LoadHubNode(ValueNode value, Kind kind, ValueNode guard) { + protected LoadHubNode(ValueNode value, Kind kind, ValueNode guard) { super(getKind(kind), (GuardingNode) guard); assert value != guard; this.value = value; @@ -75,15 +75,15 @@ public ValueNode canonical(CanonicalizerTool tool) { MetaAccessProvider metaAccess = tool.getMetaAccess(); if (metaAccess != null && getValue().stamp() instanceof ObjectStamp) { - ObjectStamp stamp = (ObjectStamp) getValue().stamp(); + ObjectStamp objectStamp = (ObjectStamp) getValue().stamp(); ResolvedJavaType exactType; - if (stamp.isExactType()) { - exactType = stamp.type(); - } else if (stamp.type() != null && tool.assumptions().useOptimisticAssumptions()) { - exactType = stamp.type().findUniqueConcreteSubtype(); + if (objectStamp.isExactType()) { + exactType = objectStamp.type(); + } else if (objectStamp.type() != null && tool.assumptions().useOptimisticAssumptions()) { + exactType = objectStamp.type().findUniqueConcreteSubtype(); if (exactType != null) { - tool.assumptions().recordConcreteSubtype(stamp.type(), exactType); + tool.assumptions().recordConcreteSubtype(objectStamp.type(), exactType); } } else { exactType = null; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -38,8 +38,8 @@ public class LoadMethodNode extends FixedWithNextNode implements Lowerable, Canonicalizable { @Input ValueNode hub; - private final ResolvedJavaMethod method; - private final ResolvedJavaType receiverType; + protected final ResolvedJavaMethod method; + protected final ResolvedJavaType receiverType; public ValueNode getHub() { return hub; @@ -49,7 +49,7 @@ return USE_GENERATED_NODES ? new LoadMethodNodeGen(method, receiverType, hub, kind) : new LoadMethodNode(method, receiverType, hub, kind); } - LoadMethodNode(ResolvedJavaMethod method, ResolvedJavaType receiverType, ValueNode hub, Kind kind) { + protected LoadMethodNode(ResolvedJavaMethod method, ResolvedJavaType receiverType, ValueNode hub, Kind kind) { super(kind == Kind.Object ? StampFactory.objectNonNull() : StampFactory.forKind(kind)); this.receiverType = receiverType; this.hub = hub; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -42,7 +42,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public class MembarNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Single { - private final int barriers; + protected final int barriers; /** * @param barriers a mask of the barrier constants defined in {@link MemoryBarriers} @@ -51,7 +51,7 @@ return USE_GENERATED_NODES ? new MembarNodeGen(barriers) : new MembarNode(barriers); } - MembarNode(int barriers) { + protected MembarNode(int barriers) { super(StampFactory.forVoid()); this.barriers = barriers; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -36,7 +36,7 @@ return USE_GENERATED_NODES ? new NullCheckNodeGen(object) : new NullCheckNode(object); } - NullCheckNode(ValueNode object) { + protected NullCheckNode(ValueNode object) { super(StampFactory.forVoid()); this.object = object; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRLocalNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRLocalNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRLocalNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -34,7 +34,7 @@ return USE_GENERATED_NODES ? new OSRLocalNodeGen(index, stamp) : new OSRLocalNode(index, stamp); } - OSRLocalNode(int index, Stamp stamp) { + protected OSRLocalNode(int index, Stamp stamp) { super(index, stamp); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -33,7 +33,7 @@ return USE_GENERATED_NODES ? new OSRStartNodeGen() : new OSRStartNode(); } - OSRStartNode() { + protected OSRStartNode() { } @Override diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -42,7 +42,7 @@ return USE_GENERATED_NODES ? new ReadNodeGen(object, location, stamp, barrierType) : new ReadNode(object, location, stamp, barrierType); } - ReadNode(ValueNode object, ValueNode location, Stamp stamp, BarrierType barrierType) { + protected ReadNode(ValueNode object, ValueNode location, Stamp stamp, BarrierType barrierType) { super(object, location, stamp, null, barrierType); } @@ -50,7 +50,7 @@ return USE_GENERATED_NODES ? new ReadNodeGen(object, location, stamp, guard, barrierType) : new ReadNode(object, location, stamp, guard, barrierType); } - ReadNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType) { + protected ReadNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType) { super(object, location, stamp, guard, barrierType); } @@ -59,7 +59,7 @@ stateBefore); } - ReadNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean nullCheck, FrameState stateBefore) { + protected ReadNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean nullCheck, FrameState stateBefore) { super(object, location, stamp, guard, barrierType, nullCheck, stateBefore); } @@ -67,7 +67,7 @@ return USE_GENERATED_NODES ? new ReadNodeGen(object, location, guard, barrierType) : new ReadNode(object, location, guard, barrierType); } - ReadNode(ValueNode object, ValueNode location, ValueNode guard, BarrierType barrierType) { + protected ReadNode(ValueNode object, ValueNode location, ValueNode guard, BarrierType barrierType) { /* * Used by node intrinsics. Really, you can trust me on that! Since the initial value for * location is a parameter, i.e., a ParameterNode, the constructor cannot use the declared diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/StoreHubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/StoreHubNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/StoreHubNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -45,7 +45,7 @@ return USE_GENERATED_NODES ? new StoreHubNodeGen(object, value) : new StoreHubNode(object, value); } - StoreHubNode(ValueNode object, ValueNode value) { + protected StoreHubNode(ValueNode object, ValueNode value) { super(StampFactory.forVoid()); this.value = value; this.object = object; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -41,8 +41,8 @@ @Input protected ValueNode value; // do not change the contents of these arrays: - private final double[] keyProbabilities; - private final int[] keySuccessors; + protected final double[] keyProbabilities; + protected final int[] keySuccessors; /** * Constructs a new Switch. diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -33,13 +33,13 @@ @NodeInfo public class UnboxNode extends UnaryNode implements Virtualizable, Lowerable { - private final Kind boxingKind; + protected final Kind boxingKind; public static UnboxNode create(ValueNode value, Kind boxingKind) { return USE_GENERATED_NODES ? new UnboxNodeGen(value, boxingKind) : new UnboxNode(value, boxingKind); } - UnboxNode(ValueNode value, Kind boxingKind) { + protected UnboxNode(ValueNode value, Kind boxingKind) { super(StampFactory.forKind(boxingKind.getStackKind()), value); this.boxingKind = boxingKind; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -35,8 +35,8 @@ @Input ValueNode object; @Input ValueNode offset; - private final Kind accessKind; - private final LocationIdentity locationIdentity; + protected final Kind accessKind; + protected final LocationIdentity locationIdentity; public UnsafeAccessNode(Stamp stamp, ValueNode object, ValueNode offset, Kind accessKind, LocationIdentity locationIdentity) { super(stamp); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -46,7 +46,7 @@ return USE_GENERATED_NODES ? new UnsafeCastNodeGen(object, stamp) : new UnsafeCastNode(object, stamp); } - UnsafeCastNode(ValueNode object, Stamp stamp) { + protected UnsafeCastNode(ValueNode object, Stamp stamp) { super(stamp); this.object = object; } @@ -55,7 +55,7 @@ return USE_GENERATED_NODES ? new UnsafeCastNodeGen(object, stamp, anchor) : new UnsafeCastNode(object, stamp, anchor); } - UnsafeCastNode(ValueNode object, Stamp stamp, ValueNode anchor) { + protected UnsafeCastNode(ValueNode object, Stamp stamp, ValueNode anchor) { super(stamp, (GuardingNode) anchor); this.object = object; } @@ -64,7 +64,7 @@ return USE_GENERATED_NODES ? new UnsafeCastNodeGen(object, toType, exactType, nonNull) : new UnsafeCastNode(object, toType, exactType, nonNull); } - UnsafeCastNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) { + protected UnsafeCastNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) { this(object, toType.getKind() == Kind.Object ? StampFactory.object(toType, exactType, nonNull || StampTool.isObjectNonNull(object.stamp()), true) : StampFactory.forKind(toType.getKind())); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -43,7 +43,7 @@ return USE_GENERATED_NODES ? new UnsafeLoadNodeGen(object, offset, accessKind, locationIdentity) : new UnsafeLoadNode(object, offset, accessKind, locationIdentity); } - UnsafeLoadNode(ValueNode object, ValueNode offset, Kind accessKind, LocationIdentity locationIdentity) { + protected UnsafeLoadNode(ValueNode object, ValueNode offset, Kind accessKind, LocationIdentity locationIdentity) { this(object, offset, accessKind, locationIdentity, null); } @@ -51,7 +51,7 @@ return USE_GENERATED_NODES ? new UnsafeLoadNodeGen(object, offset, accessKind, locationIdentity, condition) : new UnsafeLoadNode(object, offset, accessKind, locationIdentity, condition); } - UnsafeLoadNode(ValueNode object, ValueNode offset, Kind accessKind, LocationIdentity locationIdentity, LogicNode condition) { + protected UnsafeLoadNode(ValueNode object, ValueNode offset, Kind accessKind, LocationIdentity locationIdentity, LogicNode condition) { super(StampFactory.forKind(accessKind.getStackKind()), object, offset, accessKind, locationIdentity); this.guardingCondition = condition; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -45,7 +45,7 @@ return USE_GENERATED_NODES ? new UnsafeStoreNodeGen(object, offset, value, accessKind, locationIdentity) : new UnsafeStoreNode(object, offset, value, accessKind, locationIdentity); } - UnsafeStoreNode(ValueNode object, ValueNode offset, ValueNode value, Kind accessKind, LocationIdentity locationIdentity) { + protected UnsafeStoreNode(ValueNode object, ValueNode offset, ValueNode value, Kind accessKind, LocationIdentity locationIdentity) { this(object, offset, value, accessKind, locationIdentity, null); } @@ -54,7 +54,7 @@ stateAfter); } - UnsafeStoreNode(ValueNode object, ValueNode offset, ValueNode value, Kind accessKind, LocationIdentity locationIdentity, FrameState stateAfter) { + protected UnsafeStoreNode(ValueNode object, ValueNode offset, ValueNode value, Kind accessKind, LocationIdentity locationIdentity, FrameState stateAfter) { super(StampFactory.forVoid(), object, offset, accessKind, locationIdentity); this.value = value; this.stateAfter = stateAfter; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -42,7 +42,7 @@ return USE_GENERATED_NODES ? new ValueAnchorNodeGen(value) : new ValueAnchorNode(value); } - ValueAnchorNode(ValueNode value) { + protected ValueAnchorNode(ValueNode value) { super(StampFactory.forVoid()); this.anchored = value; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -40,7 +40,7 @@ return USE_GENERATED_NODES ? new WriteNodeGen(object, value, location, barrierType) : new WriteNode(object, value, location, barrierType); } - WriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType) { + protected WriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType) { super(object, value, location, barrierType); } @@ -48,7 +48,7 @@ return USE_GENERATED_NODES ? new WriteNodeGen(object, value, location, barrierType, initialization) : new WriteNode(object, value, location, barrierType, initialization); } - WriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean initialization) { + protected WriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean initialization) { super(object, value, location, barrierType, initialization); } @@ -56,7 +56,7 @@ return USE_GENERATED_NODES ? new WriteNodeGen(object, value, location, barrierType, guard, initialization) : new WriteNode(object, value, location, barrierType, guard, initialization); } - WriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, GuardingNode guard, boolean initialization) { + protected WriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, GuardingNode guard, boolean initialization) { super(object, value, location, barrierType, guard, initialization); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -74,8 +74,8 @@ @Override public void simplify(SimplifierTool tool) { - Stamp stamp = length.stamp(); - if (stamp instanceof IntegerStamp && ((IntegerStamp) stamp).isPositive()) { + Stamp lengthStamp = length.stamp(); + if (lengthStamp instanceof IntegerStamp && ((IntegerStamp) lengthStamp).isPositive()) { // otherwise, removing the allocation might swallow a NegativeArraySizeException super.simplify(tool); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewObjectNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewObjectNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -38,7 +38,7 @@ @NodeInfo public class AbstractNewObjectNode extends DeoptimizingFixedWithNextNode implements Simplifiable, Lowerable { - private final boolean fillContents; + protected final boolean fillContents; /** * Constructs a new AbstractNewObjectNode. diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -36,7 +36,7 @@ public abstract class AccessIndexedNode extends AccessArrayNode implements Lowerable { @Input protected ValueNode index; - private final Kind elementKind; + protected final Kind elementKind; public ValueNode index() { return index; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -50,7 +50,7 @@ return USE_GENERATED_NODES ? new ArrayLengthNodeGen(array) : new ArrayLengthNode(array); } - ArrayLengthNode(ValueNode array) { + protected ArrayLengthNode(ValueNode array) { super(StampFactory.positiveInt()); this.array = array; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndAddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndAddNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndAddNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -42,13 +42,13 @@ @Input ValueNode offset; @Input ValueNode delta; - private final LocationIdentity locationIdentity; + protected final LocationIdentity locationIdentity; public static AtomicReadAndAddNode create(ValueNode object, ValueNode offset, ValueNode delta, LocationIdentity locationIdentity) { return USE_GENERATED_NODES ? new AtomicReadAndAddNodeGen(object, offset, delta, locationIdentity) : new AtomicReadAndAddNode(object, offset, delta, locationIdentity); } - AtomicReadAndAddNode(ValueNode object, ValueNode offset, ValueNode delta, LocationIdentity locationIdentity) { + protected AtomicReadAndAddNode(ValueNode object, ValueNode offset, ValueNode delta, LocationIdentity locationIdentity) { super(StampFactory.forKind(delta.getKind())); this.object = object; this.offset = offset; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndWriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndWriteNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndWriteNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -43,15 +43,15 @@ @Input ValueNode offset; @Input ValueNode newValue; - private final Kind valueKind; - private final LocationIdentity locationIdentity; + protected final Kind valueKind; + protected final LocationIdentity locationIdentity; public static AtomicReadAndWriteNode create(ValueNode object, ValueNode offset, ValueNode newValue, Kind valueKind, LocationIdentity locationIdentity) { return USE_GENERATED_NODES ? new AtomicReadAndWriteNodeGen(object, offset, newValue, valueKind, locationIdentity) : new AtomicReadAndWriteNode(object, offset, newValue, valueKind, locationIdentity); } - AtomicReadAndWriteNode(ValueNode object, ValueNode offset, ValueNode newValue, Kind valueKind, LocationIdentity locationIdentity) { + protected AtomicReadAndWriteNode(ValueNode object, ValueNode offset, ValueNode newValue, Kind valueKind, LocationIdentity locationIdentity) { super(StampFactory.forKind(newValue.getKind())); this.object = object; this.offset = offset; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -43,7 +43,7 @@ * Determines the exception thrown by this node if the check fails: {@link ClassCastException} * if false; {@link ArrayStoreException} if true. */ - private final boolean forStoreCheck; + protected final boolean forStoreCheck; /** * @param hub the type being cast to @@ -53,7 +53,7 @@ return USE_GENERATED_NODES ? new CheckCastDynamicNodeGen(hub, object, forStoreCheck) : new CheckCastDynamicNode(hub, object, forStoreCheck); } - CheckCastDynamicNode(ValueNode hub, ValueNode object, boolean forStoreCheck) { + protected CheckCastDynamicNode(ValueNode hub, ValueNode object, boolean forStoreCheck) { super(object.stamp()); this.hub = hub; this.object = object; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -44,14 +44,14 @@ public class CheckCastNode extends FixedWithNextNode implements Canonicalizable, Simplifiable, Lowerable, Virtualizable, ValueProxy { @Input protected ValueNode object; - private final ResolvedJavaType type; - private final JavaTypeProfile profile; + protected final ResolvedJavaType type; + protected final JavaTypeProfile profile; /** * Determines the exception thrown by this node if the check fails: {@link ClassCastException} * if false; {@link ArrayStoreException} if true. */ - private final boolean forStoreCheck; + protected final boolean forStoreCheck; /** * Creates a new CheckCast instruction. @@ -104,16 +104,16 @@ */ @Override public void lower(LoweringTool tool) { - Stamp stamp = StampFactory.declared(type, false, true); + Stamp newStamp = StampFactory.declared(type, false, true); if (stamp() instanceof ObjectStamp && object().stamp() instanceof ObjectStamp) { - stamp = ((ObjectStamp) object().stamp()).castTo((ObjectStamp) stamp); + newStamp = ((ObjectStamp) object().stamp()).castTo((ObjectStamp) newStamp); } ValueNode condition; ValueNode theValue = object; - if (stamp instanceof IllegalStamp) { + if (newStamp instanceof IllegalStamp) { // This is a check cast that will always fail condition = LogicConstantNode.contradiction(graph()); - stamp = StampFactory.declared(type, false, true); + newStamp = StampFactory.declared(type, false, true); } else if (StampTool.isObjectNonNull(object)) { condition = graph().addWithoutUnique(InstanceOfNode.create(type, object, profile)); } else { @@ -129,7 +129,7 @@ * optimized away. */ theValue = nullGuarded; - stamp = stamp.join(StampFactory.objectNonNull()); + newStamp = newStamp.join(StampFactory.objectNonNull()); nullCheck.lower(tool); } else { // TODO (ds) replace with probability of null-seen when available @@ -138,7 +138,7 @@ condition = LogicNode.or(graph().unique(IsNullNode.create(object)), typeTest, shortCircuitProbability); } } - GuardingPiNode checkedObject = graph().add(GuardingPiNode.create(theValue, condition, false, forStoreCheck ? ArrayStoreException : ClassCastException, InvalidateReprofile, stamp)); + GuardingPiNode checkedObject = graph().add(GuardingPiNode.create(theValue, condition, false, forStoreCheck ? ArrayStoreException : ClassCastException, InvalidateReprofile, newStamp)); graph().replaceFixedWithFixed(this, checkedObject); checkedObject.lower(tool); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -43,15 +43,15 @@ @Input ValueNode expected; @Input ValueNode newValue; - private final Kind valueKind; - private final LocationIdentity locationIdentity; + protected final Kind valueKind; + protected final LocationIdentity locationIdentity; public static CompareAndSwapNode create(ValueNode object, ValueNode offset, ValueNode expected, ValueNode newValue, Kind valueKind, LocationIdentity locationIdentity) { return USE_GENERATED_NODES ? new CompareAndSwapNodeGen(object, offset, expected, newValue, valueKind, locationIdentity) : new CompareAndSwapNode(object, offset, expected, newValue, valueKind, locationIdentity); } - CompareAndSwapNode(ValueNode object, ValueNode offset, ValueNode expected, ValueNode newValue, Kind valueKind, LocationIdentity locationIdentity) { + protected CompareAndSwapNode(ValueNode object, ValueNode offset, ValueNode expected, ValueNode newValue, Kind valueKind, LocationIdentity locationIdentity) { super(StampFactory.forKind(Kind.Boolean.getStackKind())); assert expected.stamp().isCompatible(newValue.stamp()); this.object = object; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -46,7 +46,7 @@ return USE_GENERATED_NODES ? new DynamicNewArrayNodeGen(elementType, length) : new DynamicNewArrayNode(elementType, length); } - DynamicNewArrayNode(ValueNode elementType, ValueNode length) { + protected DynamicNewArrayNode(ValueNode elementType, ValueNode length) { this(elementType, length, true); } @@ -54,7 +54,7 @@ return USE_GENERATED_NODES ? new DynamicNewArrayNodeGen(elementType, length, fillContents) : new DynamicNewArrayNode(elementType, length, fillContents); } - DynamicNewArrayNode(ValueNode elementType, ValueNode length, boolean fillContents) { + protected DynamicNewArrayNode(ValueNode elementType, ValueNode length, boolean fillContents) { super(StampFactory.objectNonNull(), length, fillContents); this.elementType = elementType; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewInstanceNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewInstanceNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -38,7 +38,7 @@ return USE_GENERATED_NODES ? new DynamicNewInstanceNodeGen(clazz, fillContents) : new DynamicNewInstanceNode(clazz, fillContents); } - DynamicNewInstanceNode(ValueNode clazz, boolean fillContents) { + protected DynamicNewInstanceNode(ValueNode clazz, boolean fillContents) { super(StampFactory.objectNonNull(), fillContents); this.clazz = clazz; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -40,7 +40,7 @@ return USE_GENERATED_NODES ? new ExceptionObjectNodeGen(metaAccess) : new ExceptionObjectNode(metaAccess); } - ExceptionObjectNode(MetaAccessProvider metaAccess) { + protected ExceptionObjectNode(MetaAccessProvider metaAccess) { super(StampFactory.declaredNonNull(metaAccess.lookupJavaType(Throwable.class))); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -48,7 +48,7 @@ return USE_GENERATED_NODES ? new InstanceOfDynamicNodeGen(mirror, object) : new InstanceOfDynamicNode(mirror, object); } - InstanceOfDynamicNode(ValueNode mirror, ValueNode object) { + protected InstanceOfDynamicNode(ValueNode mirror, ValueNode object) { this.mirror = mirror; this.object = object; assert mirror.getKind() == Kind.Object : mirror.getKind(); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -36,8 +36,8 @@ @NodeInfo public class InstanceOfNode extends UnaryOpLogicNode implements Lowerable, Virtualizable { - private final ResolvedJavaType type; - private JavaTypeProfile profile; + protected final ResolvedJavaType type; + protected JavaTypeProfile profile; /** * Constructs a new InstanceOfNode. @@ -63,11 +63,10 @@ @Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { - Stamp stamp = forValue.stamp(); - if (!(stamp instanceof ObjectStamp)) { + if (!(forValue.stamp() instanceof ObjectStamp)) { return this; } - ObjectStamp objectStamp = (ObjectStamp) stamp; + ObjectStamp objectStamp = (ObjectStamp) forValue.stamp(); if (objectStamp.alwaysNull()) { return LogicConstantNode.contradiction(); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -34,7 +34,7 @@ return USE_GENERATED_NODES ? new LoadExceptionObjectNodeGen(stamp) : new LoadExceptionObjectNode(stamp); } - LoadExceptionObjectNode(Stamp stamp) { + protected LoadExceptionObjectNode(Stamp stamp) { super(stamp); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -46,7 +46,7 @@ return USE_GENERATED_NODES ? new LoadIndexedNodeGen(array, index, elementKind) : new LoadIndexedNode(array, index, elementKind); } - LoadIndexedNode(ValueNode array, ValueNode index, Kind elementKind) { + protected LoadIndexedNode(ValueNode array, ValueNode index, Kind elementKind) { super(createStamp(array, elementKind), array, index, elementKind); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -44,7 +44,7 @@ return USE_GENERATED_NODES ? new LoweredAtomicReadAndWriteNodeGen(object, location, newValue, barrierType) : new LoweredAtomicReadAndWriteNode(object, location, newValue, barrierType); } - LoweredAtomicReadAndWriteNode(ValueNode object, LocationNode location, ValueNode newValue, BarrierType barrierType) { + protected LoweredAtomicReadAndWriteNode(ValueNode object, LocationNode location, ValueNode newValue, BarrierType barrierType) { super(object, location, newValue.stamp().unrestricted(), barrierType); this.newValue = newValue; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -66,7 +66,7 @@ newValue, barrierType); } - LoweredCompareAndSwapNode(ValueNode object, LocationNode location, ValueNode expectedValue, ValueNode newValue, BarrierType barrierType) { + protected LoweredCompareAndSwapNode(ValueNode object, LocationNode location, ValueNode expectedValue, ValueNode newValue, BarrierType barrierType) { super(object, location, StampFactory.forKind(Kind.Boolean.getStackKind()), barrierType); assert expectedValue.getKind() == newValue.getKind(); this.expectedValue = expectedValue; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -32,7 +32,7 @@ @NodeInfo public class MethodCallTargetNode extends CallTargetNode implements IterableNodeType, Canonicalizable { - private final JavaType returnType; + protected final JavaType returnType; /** * @param arguments diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -44,7 +44,7 @@ return USE_GENERATED_NODES ? new MonitorEnterNodeGen(object, monitorId) : new MonitorEnterNode(object, monitorId); } - MonitorEnterNode(ValueNode object, MonitorIdNode monitorId) { + protected MonitorEnterNode(ValueNode object, MonitorIdNode monitorId) { super(object, monitorId); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -48,7 +48,7 @@ return USE_GENERATED_NODES ? new MonitorExitNodeGen(object, monitorId, escapedReturnValue) : new MonitorExitNode(object, monitorId, escapedReturnValue); } - MonitorExitNode(ValueNode object, MonitorIdNode monitorId, ValueNode escapedReturnValue) { + protected MonitorExitNode(ValueNode object, MonitorIdNode monitorId, ValueNode escapedReturnValue) { super(object, monitorId); this.escapedReturnValue = escapedReturnValue; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorIdNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorIdNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorIdNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -36,7 +36,7 @@ @NodeInfo(allowedUsageTypes = {InputType.Association}) public class MonitorIdNode extends ValueNode implements IterableNodeType, LIRLowerable { - private int lockDepth; + protected int lockDepth; public static MonitorIdNode create(int lockDepth) { return USE_GENERATED_NODES ? new MonitorIdNodeGen(lockDepth) : new MonitorIdNode(lockDepth); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -38,7 +38,7 @@ @NodeInfo(nameTemplate = "New {p#instanceClass/s}") public class NewInstanceNode extends AbstractNewObjectNode implements VirtualizableAllocation { - private final ResolvedJavaType instanceClass; + protected final ResolvedJavaType instanceClass; /** * Constructs a NewInstanceNode. diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -36,7 +36,7 @@ public class NewMultiArrayNode extends DeoptimizingFixedWithNextNode implements Lowerable, ArrayLengthProvider { @Input protected NodeInputList dimensions; - private final ResolvedJavaType type; + protected final ResolvedJavaType type; public ValueNode dimension(int index) { return dimensions.get(index); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -45,7 +45,7 @@ return USE_GENERATED_NODES ? new RegisterFinalizerNodeGen(value) : new RegisterFinalizerNode(value); } - RegisterFinalizerNode(ValueNode value) { + protected RegisterFinalizerNode(ValueNode value) { super(StampFactory.forVoid()); this.value = value; } @@ -66,16 +66,16 @@ return this; } - ObjectStamp stamp = (ObjectStamp) forValue.stamp(); + ObjectStamp objectStamp = (ObjectStamp) forValue.stamp(); boolean needsCheck = true; - if (stamp.isExactType()) { - needsCheck = stamp.type().hasFinalizer(); - } else if (stamp.type() != null && !stamp.type().hasFinalizableSubclass()) { + if (objectStamp.isExactType()) { + needsCheck = objectStamp.type().hasFinalizer(); + } else if (objectStamp.type() != null && !objectStamp.type().hasFinalizableSubclass()) { // if either the declared type of receiver or the holder // can be assumed to have no finalizers if (tool.assumptions().useOptimisticAssumptions()) { - tool.assumptions().recordNoFinalizableSubclassAssumption(stamp.type()); + tool.assumptions().recordNoFinalizableSubclassAssumption(objectStamp.type()); needsCheck = false; } } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/SelfReplacingMethodCallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/SelfReplacingMethodCallTargetNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/SelfReplacingMethodCallTargetNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -40,8 +40,8 @@ public class SelfReplacingMethodCallTargetNode extends MethodCallTargetNode implements Lowerable { // Replacement method data - private final ResolvedJavaMethod replacementTargetMethod; - private final JavaType replacementReturnType; + protected final ResolvedJavaMethod replacementTargetMethod; + protected final JavaType replacementReturnType; @Input NodeInputList replacementArguments; public static SelfReplacingMethodCallTargetNode create(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType, @@ -50,7 +50,7 @@ : new SelfReplacingMethodCallTargetNode(invokeKind, targetMethod, arguments, returnType, replacementTargetMethod, replacementArguments, replacementReturnType); } - SelfReplacingMethodCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType, ResolvedJavaMethod replacementTargetMethod, + protected SelfReplacingMethodCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType, ResolvedJavaMethod replacementTargetMethod, ValueNode[] replacementArguments, JavaType replacementReturnType) { super(invokeKind, targetMethod, arguments, returnType); this.replacementTargetMethod = replacementTargetMethod; @@ -72,9 +72,9 @@ @Override public void lower(LoweringTool tool) { - InvokeKind invokeKind = replacementTargetMethod.isStatic() ? InvokeKind.Static : InvokeKind.Special; + InvokeKind replacementInvokeKind = replacementTargetMethod.isStatic() ? InvokeKind.Static : InvokeKind.Special; MethodCallTargetNode replacement = graph().add( - MethodCallTargetNode.create(invokeKind, replacementTargetMethod, replacementArguments.toArray(new ValueNode[replacementArguments.size()]), replacementReturnType)); + MethodCallTargetNode.create(replacementInvokeKind, replacementTargetMethod, replacementArguments.toArray(new ValueNode[replacementArguments.size()]), replacementReturnType)); // Replace myself... this.replaceAndDelete(replacement); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -67,7 +67,7 @@ return USE_GENERATED_NODES ? new StoreFieldNodeGen(object, field, value) : new StoreFieldNode(object, field, value); } - StoreFieldNode(ValueNode object, ResolvedJavaField field, ValueNode value) { + protected StoreFieldNode(ValueNode object, ResolvedJavaField field, ValueNode value) { super(StampFactory.forVoid(), object, field); this.value = value; } @@ -76,7 +76,7 @@ return USE_GENERATED_NODES ? new StoreFieldNodeGen(object, field, value, stateAfter) : new StoreFieldNode(object, field, value, stateAfter); } - StoreFieldNode(ValueNode object, ResolvedJavaField field, ValueNode value, FrameState stateAfter) { + protected StoreFieldNode(ValueNode object, ResolvedJavaField field, ValueNode value, FrameState stateAfter) { super(StampFactory.forVoid(), object, field); this.value = value; this.stateAfter = stateAfter; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -68,7 +68,7 @@ return USE_GENERATED_NODES ? new StoreIndexedNodeGen(array, index, elementKind, value) : new StoreIndexedNode(array, index, elementKind, value); } - StoreIndexedNode(ValueNode array, ValueNode index, Kind elementKind, ValueNode value) { + protected StoreIndexedNode(ValueNode array, ValueNode index, Kind elementKind, ValueNode value) { super(StampFactory.forVoid(), array, index, elementKind); this.value = value; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -41,7 +41,7 @@ @NodeInfo public class TypeSwitchNode extends SwitchNode implements LIRLowerable, Simplifiable { - private final ResolvedJavaType[] keys; + protected final ResolvedJavaType[] keys; /** * Constructs a type switch instruction. The keyProbabilities array contain key.length + 1 @@ -57,7 +57,7 @@ return USE_GENERATED_NODES ? new TypeSwitchNodeGen(value, successors, keys, keyProbabilities, keySuccessors) : new TypeSwitchNode(value, successors, keys, keyProbabilities, keySuccessors); } - TypeSwitchNode(ValueNode value, BeginNode[] successors, ResolvedJavaType[] keys, double[] keyProbabilities, int[] keySuccessors) { + protected TypeSwitchNode(ValueNode value, BeginNode[] successors, ResolvedJavaType[] keys, double[] keyProbabilities, int[] keySuccessors) { super(value, successors, keySuccessors, keyProbabilities); assert successors.length <= keys.length + 1; assert keySuccessors.length == keyProbabilities.length; @@ -152,11 +152,11 @@ graph().removeSplit(this, blockSuccessor(survivingEdge)); } if (value() instanceof LoadHubNode && ((LoadHubNode) value()).getValue().stamp() instanceof ObjectStamp) { - ObjectStamp stamp = (ObjectStamp) ((LoadHubNode) value()).getValue().stamp(); - if (stamp.type() != null) { + ObjectStamp objectStamp = (ObjectStamp) ((LoadHubNode) value()).getValue().stamp(); + if (objectStamp.type() != null) { int validKeys = 0; for (int i = 0; i < keyCount(); i++) { - if (stamp.type().isAssignableFrom(keys[i])) { + if (objectStamp.type().isAssignableFrom(keys[i])) { validKeys++; } } @@ -171,7 +171,7 @@ double totalProbability = 0; int current = 0; for (int i = 0; i < keyCount() + 1; i++) { - if (i == keyCount() || stamp.type().isAssignableFrom(keys[i])) { + if (i == keyCount() || objectStamp.type().isAssignableFrom(keys[i])) { int index = newSuccessors.indexOf(keySuccessor(i)); if (index == -1) { index = newSuccessors.size(); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/AllocatedObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/AllocatedObjectNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/AllocatedObjectNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -42,7 +42,7 @@ return USE_GENERATED_NODES ? new AllocatedObjectNodeGen(virtualObject) : new AllocatedObjectNode(virtualObject); } - AllocatedObjectNode(VirtualObjectNode virtualObject) { + protected AllocatedObjectNode(VirtualObjectNode virtualObject) { super(StampFactory.exactNonNull(virtualObject.type())); this.virtualObject = virtualObject; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -38,13 +38,13 @@ @Input NodeInputList virtualObjects = new NodeInputList<>(this); @Input NodeInputList values = new NodeInputList<>(this); @Input(InputType.Association) NodeInputList locks = new NodeInputList<>(this); - private ArrayList lockIndexes = new ArrayList<>(Arrays.asList(0)); + protected ArrayList lockIndexes = new ArrayList<>(Arrays.asList(0)); public static CommitAllocationNode create() { return USE_GENERATED_NODES ? new CommitAllocationNodeGen() : new CommitAllocationNode(); } - CommitAllocationNode() { + protected CommitAllocationNode() { super(StampFactory.forVoid()); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualBoxingNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualBoxingNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualBoxingNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -30,13 +30,13 @@ @NodeInfo public class VirtualBoxingNode extends VirtualInstanceNode { - private final Kind boxingKind; + protected final Kind boxingKind; public static VirtualBoxingNode create(ResolvedJavaType type, Kind boxingKind) { return USE_GENERATED_NODES ? new VirtualBoxingNodeGen(type, boxingKind) : new VirtualBoxingNode(type, boxingKind); } - VirtualBoxingNode(ResolvedJavaType type, Kind boxingKind) { + protected VirtualBoxingNode(ResolvedJavaType type, Kind boxingKind) { super(type, false); this.boxingKind = boxingKind; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -32,7 +32,7 @@ @NodeInfo public abstract class VirtualObjectNode extends ValueNode implements LIRLowerable, IterableNodeType { - private boolean hasIdentity; + protected boolean hasIdentity; public VirtualObjectNode(ResolvedJavaType type, boolean hasIdentity) { super(StampFactory.exactNonNull(type)); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Fri Oct 03 13:48:58 2014 +0200 @@ -213,7 +213,7 @@ } public static boolean tryGlobalValueNumbering(Node node, NodeClass nodeClass) { - if (nodeClass.valueNumberable() && !node.isLeafNode()) { + if (nodeClass.valueNumberable() && !nodeClass.isLeafNode()) { Node newNode = node.graph().findDuplicate(node); if (newNode != null) { assert !(node instanceof FixedNode || newNode instanceof FixedNode); @@ -270,7 +270,7 @@ } if (nodeClass.isSimplifiable()) { - Debug.log("Canonicalizer: simplifying %s", node); + Debug.log(3, "Canonicalizer: simplifying %s", node); METRIC_SIMPLIFICATION_CONSIDERED_NODES.increment(); try (Scope s = Debug.scope("SimplifyNode", node)) { node.simplify(tool); @@ -300,7 +300,7 @@ // @formatter:on private boolean performReplacement(final Node node, Node newCanonical) { if (newCanonical == node) { - Debug.log("Canonicalizer: work on %1s", node); + Debug.log(3, "Canonicalizer: work on %1s", node); return false; } else { Node canonical = newCanonical; @@ -310,6 +310,9 @@ if (canonical != null && !canonical.isAlive()) { assert !canonical.isDeleted(); canonical = graph.addOrUniqueWithInputs(canonical); + if (canonical == node) { + graph.addOrUniqueWithInputs(newCanonical); + } } if (node instanceof FloatingNode) { if (canonical == null) { diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Fri Oct 03 13:48:58 2014 +0200 @@ -211,8 +211,8 @@ if (node instanceof AbstractEndNode) { MergeNode merge = ((AbstractEndNode) node).merge(); for (PhiNode phi : merge.phis()) { - assert currentState.isMarked(phi.valueAt((AbstractEndNode) node)) : phi.valueAt((AbstractEndNode) node) + " not available at phi " + phi + " / end " + node + - " in block " + block; + ValueNode phiValue = phi.valueAt((AbstractEndNode) node); + assert phiValue == null || currentState.isMarked(phiValue) : phiValue + " not available at phi " + phi + " / end " + node + " in block " + block; } } if (stateAfter != null) { diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java Fri Oct 03 13:48:58 2014 +0200 @@ -457,16 +457,12 @@ out.printf("nr %4d ", inst.id()).print(COLUMN_END); final StringBuilder stateString = new StringBuilder(); - inst.forEachState(new StateProcedure() { - - @Override - protected void doState(LIRFrameState state) { - if (state.hasDebugInfo()) { - DebugInfo di = state.debugInfo(); - stateString.append(debugInfoToString(di.getBytecodePosition(), di.getReferenceMap(), di.getCalleeSaveInfo(), target.arch)); - } else { - stateString.append(debugInfoToString(state.topFrame, null, null, target.arch)); - } + inst.forEachState(state -> { + if (state.hasDebugInfo()) { + DebugInfo di = state.debugInfo(); + stateString.append(debugInfoToString(di.getBytecodePosition(), di.getReferenceMap(), di.getCalleeSaveInfo(), target.arch)); + } else { + stateString.append(debugInfoToString(state.topFrame, null, null, target.arch)); } }); if (stateString.length() > 0) { diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -41,7 +41,7 @@ @NodeInfo public class AMD64FloatConvertNode extends UnaryNode implements ArithmeticLIRLowerable { - private final FloatConvert op; + protected final FloatConvert op; public static AMD64FloatConvertNode create(Stamp stamp, FloatConvert op, ValueNode value) { return USE_GENERATED_NODES ? new AMD64FloatConvertNodeGen(stamp, op, value) : new AMD64FloatConvertNode(stamp, op, value); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.replacements.hsail/src/com/oracle/graal/replacements/hsail/HSAILMathIntrinsicsNode.java --- a/graal/com.oracle.graal.replacements.hsail/src/com/oracle/graal/replacements/hsail/HSAILMathIntrinsicsNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.replacements.hsail/src/com/oracle/graal/replacements/hsail/HSAILMathIntrinsicsNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -49,7 +49,7 @@ /** * The math operation that this Node represents. */ - private final HSAILArithmetic operation; + protected final HSAILArithmetic operation; /** * Gets the parameter passed to the math operation that this node represents. diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java Fri Oct 03 13:48:58 2014 +0200 @@ -50,6 +50,10 @@ public static TestNode create() { return USE_GENERATED_NODES ? new EdgesTest_TestNodeGen() : new TestNode(); } + + protected TestNode() { + // TODO Auto-generated constructor stub + } } StructuredGraph graph = new StructuredGraph(); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Fri Oct 03 13:48:58 2014 +0200 @@ -384,7 +384,7 @@ @NodeInfo static class VarargsPlaceholderNode extends FloatingNode implements ArrayLengthProvider { - final Varargs varargs; + protected final Varargs varargs; public static VarargsPlaceholderNode create(Varargs varargs, MetaAccessProvider metaAccess) { return USE_GENERATED_NODES ? new SnippetTemplate_VarargsPlaceholderNodeGen(varargs, metaAccess) : new VarargsPlaceholderNode(varargs, metaAccess); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -39,7 +39,7 @@ public class ArrayEqualsNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable, Virtualizable, MemoryAccess { /** {@link Kind} of the arrays to compare. */ - private final Kind kind; + protected final Kind kind; /** One array to be tested for equality. */ @Input ValueNode array1; @@ -58,8 +58,8 @@ super(StampFactory.forKind(Kind.Boolean)); assert array1.stamp().equals(array2.stamp()); - ObjectStamp stamp = (ObjectStamp) array1.stamp(); - ResolvedJavaType componentType = stamp.type().getComponentType(); + ObjectStamp array1Stamp = (ObjectStamp) array1.stamp(); + ResolvedJavaType componentType = array1Stamp.type().getComponentType(); this.kind = componentType.getKind(); this.array1 = array1; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/AssertionNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/AssertionNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/AssertionNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -40,8 +40,8 @@ @Input ValueNode value; - private final boolean compileTimeAssertion; - private final String message; + protected final boolean compileTimeAssertion; + protected final String message; public static AssertionNode create(boolean compileTimeAssertion, ValueNode value, String message) { return USE_GENERATED_NODES ? new AssertionNodeGen(compileTimeAssertion, value, message) : new AssertionNode(compileTimeAssertion, value, message); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -40,8 +40,8 @@ @Input ValueNode object; @Input ValueNode value; @Input ValueNode offset; - private final int displacement; - private final LocationIdentity locationIdentity; + protected final int displacement; + protected final LocationIdentity locationIdentity; public static DirectObjectStoreNode create(ValueNode object, int displacement, ValueNode offset, ValueNode value, LocationIdentity locationIdentity) { return USE_GENERATED_NODES ? new DirectObjectStoreNodeGen(object, displacement, offset, value, locationIdentity) : new DirectObjectStoreNode(object, displacement, offset, value, diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -39,7 +39,7 @@ public class DirectReadNode extends FixedWithNextNode implements LIRLowerable { @Input protected ValueNode address; - private final Kind readKind; + protected final Kind readKind; public static DirectReadNode create(ValueNode address, Kind readKind) { return USE_GENERATED_NODES ? new DirectReadNodeGen(address, readKind) : new DirectReadNode(address, readKind); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -40,7 +40,7 @@ @Input protected ValueNode address; @Input protected ValueNode value; - private final Kind kind; + protected final Kind kind; public static DirectStoreNode create(ValueNode address, ValueNode value, Kind kind) { return USE_GENERATED_NODES ? new DirectStoreNodeGen(address, value, kind) : new DirectStoreNode(address, value, kind); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -61,10 +61,10 @@ @Input protected NodeInputList arguments; - private final int bci; - private final ResolvedJavaMethod targetMethod; - private final JavaType returnType; - private final InvokeKind invokeKind; + protected final int bci; + protected final ResolvedJavaMethod targetMethod; + protected final JavaType returnType; + protected final InvokeKind invokeKind; public static MacroNode create(Invoke invoke) { return USE_GENERATED_NODES ? new MacroNodeGen(invoke) : new MacroNode(invoke); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -35,7 +35,7 @@ @NodeInfo public class MathIntrinsicNode extends UnaryNode implements ArithmeticLIRLowerable { - private final Operation operation; + protected final Operation operation; public enum Operation { ABS, diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReadRegisterNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -38,20 +38,20 @@ /** * The fixed register to access. */ - private final Register register; + protected final Register register; /** * When true, subsequent uses of this node use the fixed register; when false, the value is * moved into a new virtual register so that the fixed register is not seen by uses. */ - private final boolean directUse; + protected final boolean directUse; /** * When true, this node is also an implicit definition of the value for the register allocator, * i.e., the register is an implicit incoming value; when false, the register must be defined in * the same method or must be an register excluded from register allocation. */ - private final boolean incoming; + protected final boolean incoming; public static ReadRegisterNode create(Register register, Kind kind, boolean directUse, boolean incoming) { return USE_GENERATED_NODES ? new ReadRegisterNodeGen(register, kind, directUse, incoming) : new ReadRegisterNode(register, kind, directUse, incoming); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -38,7 +38,7 @@ /** * The fixed register to access. */ - private final Register register; + protected final Register register; /** * The new value assigned to the register. diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Fri Oct 03 13:48:58 2014 +0200 @@ -76,6 +76,7 @@ private HotSpotTruffleRuntime() { installOptimizedCallTargetCallMethod(); + installOptimizedCallTargetCallDirect(); lookupCallMethods(getGraalProviders().getMetaAccess()); // Create compilation queue. @@ -93,6 +94,12 @@ compileQueue = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), factory); } + private static void installOptimizedCallTargetCallDirect() { + if (TruffleCompilerOptions.TruffleContextSensitiveInlining.getValue()) { + ((HotSpotResolvedJavaMethod) getGraalProviders().getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallDirectMethod())).setNotInlineable(); + } + } + @Override public String getName() { return "Graal Truffle Runtime"; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle.test/sl/TestInlining.sl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/sl/TestInlining.sl Fri Oct 03 13:48:58 2014 +0200 @@ -0,0 +1,20 @@ +/* + * This tests that simple arithmetic gets inlined. + */ +function add(a, b) { + return a + b; +} + + +function test() { + i = 0; + while (i < 100) { + i = add(i, 1); + } + return i; +} + +function main() { + waitForOptimization(callUntilOptimized(test)); + assertTrue(isInlined(test, test, add), "add is not inlined"); +} diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle.test/sl/TestInliningMaxCallerSize.sl --- a/graal/com.oracle.graal.truffle.test/sl/TestInliningMaxCallerSize.sl Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle.test/sl/TestInliningMaxCallerSize.sl Fri Oct 03 13:48:58 2014 +0200 @@ -19,8 +19,8 @@ function main() { waitForOptimization(callUntilOptimized(test1)); - assertTrue(isInlined(test1, inlinableFunction), "inlinableFunction is not inlined"); + assertTrue(isInlined(test1, test1, inlinableFunction), "inlinableFunction is not inlined"); waitForOptimization(callUntilOptimized(test2)); - assertFalse(isInlined(test2, notInlinableFunction), "notInlinableFunction is inlined"); + assertFalse(isInlined(test2, test2, notInlinableFunction), "notInlinableFunction is inlined"); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle.test/sl/TestInliningRecursive1.sl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/sl/TestInliningRecursive1.sl Fri Oct 03 13:48:58 2014 +0200 @@ -0,0 +1,25 @@ +/* + * Test recursive calls do not get inlined and do not crash. + */ +function fib(a) { + if (a == 2 || a == 1) { + return 1; + } + return fib(a-1) + fib(a-2); +} + +function test() { + i = 0; + sum = 0; + while (i < 100) { + sum = sum + fib(7); + i = i + 1; + } + return sum; +} + +function main() { + waitForOptimization(callUntilOptimized(test)); + assertTrue(isInlined(test, test, fib), "fib is not inlined"); + assertFalse(isInlined(test, fib, fib), "fib -> fib is not inlined"); +} diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle.test/sl/TestInliningRecursive2.sl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/sl/TestInliningRecursive2.sl Fri Oct 03 13:48:58 2014 +0200 @@ -0,0 +1,37 @@ +/* + * Tests that indirect recursions are not inlined. + */ +function fib(a) { + if (a == 2 || a == 1) { + return 1; + } + return call(fib, a-1) + call(fib, a-2) + call(void, 0); +} + +function call(f, a) { + return f(a); +} + +function void(a) { + return a; +} + +function test() { + i = 0; + sum = 0; + while (i < 100) { + sum = sum + fib(7); + i = i + 1; + } + return sum; +} + +function main() { + waitForOptimization(callUntilOptimized(test)); + assertTrue(isInlined(test, test, fib), "not inlined: test -> fib"); + if (getOption("TruffleContextSensitiveInlining")) { + assertTrue(isInlined(test, fib, call), "not inlined: fib -> call"); + assertFalse(isInlined(test, call, fib), "inlined: call -> fib"); + assertTrue(isInlined(test, call, void), "inlined: call -> void"); + } +} diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle.test/sl/TestSlowPath01.sl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/sl/TestSlowPath01.sl Fri Oct 03 13:48:58 2014 +0200 @@ -0,0 +1,11 @@ +/* + * This test verifies that CallTargets cannot exceed the TruffleInliningMaxCallerSize limit when inlining. + */ + +function test1() { + testSlowPath01(); +} +function main() { + waitForOptimization(callUntilOptimized(test1)); + assertTrue(isOptimized(test1), "inlinableFunction must be compiled properly"); +} diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Fri Oct 03 13:48:58 2014 +0200 @@ -97,7 +97,7 @@ try (Scope s = Debug.scope("TruffleCompilation", new TruffleDebugJavaMethod(compilable))) { - StructuredGraph resultGraph = truffleCompiler.getPartialEvaluator().createGraph(compilable, assumptions); + StructuredGraph resultGraph = truffleCompiler.getPartialEvaluator().createGraph(compilable, assumptions, null); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(canonicalizeReads); PhaseContext context = new PhaseContext(getProviders(), assumptions); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SLTruffleGraalTestSuite.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SLTruffleGraalTestSuite.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SLTruffleGraalTestSuite.java Fri Oct 03 13:48:58 2014 +0200 @@ -47,6 +47,9 @@ SLTestRunner.installBuiltin(SLCallUntilOptimizedBuiltinFactory.getInstance()); SLTestRunner.installBuiltin(SLIsInlinedBuiltinFactory.getInstance()); SLTestRunner.installBuiltin(SLGenerateDummyNodesBuiltinFactory.getInstance()); + + /* test specific builtins */ + SLTestRunner.installBuiltin(SLTestSlowPath01BuiltinFactory.getInstance()); } /* diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLIsInlinedBuiltin.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLIsInlinedBuiltin.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLIsInlinedBuiltin.java Fri Oct 03 13:48:58 2014 +0200 @@ -40,28 +40,57 @@ @Specialization @SlowPath - public Object isInlined(SLFunction parent, SLFunction inlinedFunction) { - boolean allFalse = true; - boolean allTrue = true; - for (OptimizedCallTarget parentTarget : findDuplicateCallTargets((OptimizedCallTarget) parent.getCallTarget())) { - Set callNodes = findCallsTo(parentTarget.getRootNode(), (OptimizedCallTarget) inlinedFunction.getCallTarget()); - for (DirectCallNode directCall : callNodes) { - if (directCall.isInlined()) { - allFalse = false; - } else { - allTrue = false; - } + public Object isInlined(SLFunction rootFunction, SLFunction parentFunction, SLFunction inlinedFunction) { + InliningTrace trace = new InliningTrace(); + + for (OptimizedCallTarget target : findDuplicateCallTargets((OptimizedCallTarget) rootFunction.getCallTarget())) { + if (target.isValid()) { + searchInlined(trace, target, new ArrayList<>(), parentFunction, inlinedFunction); } } - if (allFalse && allTrue) { - throw new AssertionError(String.format("No calls found from %s to %s .", parent, inlinedFunction)); - } else if (!allFalse && !allTrue) { - throw new AssertionError(String.format("Some calls from %s to %s are inlined and some are not.", parent, inlinedFunction)); + + if (trace.allFalse && trace.allTrue) { + throw new AssertionError(String.format("No optimized calls found from %s to %s .", parentFunction, inlinedFunction)); + } else if (!trace.allFalse && !trace.allTrue) { + throw new AssertionError(String.format("Some optimized calls from %s to %s are inlined and some are not.", parentFunction, inlinedFunction)); } - if (allTrue) { + if (trace.allTrue) { return true; } else { return false; } } + + private void searchInlined(InliningTrace trace, OptimizedCallTarget rootTarget, List stack, SLFunction parent, SLFunction inlinedFunction) { + OptimizedCallTarget root; + if (stack.isEmpty()) { + root = rootTarget; + } else { + root = stack.get(stack.size() - 1).getCurrentCallTarget(); + } + + for (OptimizedDirectCallNode callNode : root.getCallNodes()) { + stack.add(callNode); + + boolean inlined = rootTarget.isInlined(stack); + if (callNode.getRootNode().getCallTarget() == parent.getCallTarget() && callNode.getCallTarget() == inlinedFunction.getCallTarget()) { + if (inlined) { + trace.allFalse = false; + } else { + trace.allTrue = false; + } + } + + if (inlined) { + searchInlined(trace, rootTarget, stack, parent, inlinedFunction); + } + + stack.remove(stack.size() - 1); + } + } + + private static final class InliningTrace { + boolean allFalse = true; + boolean allTrue = true; + } } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLTestSlowPath01Builtin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLTestSlowPath01Builtin.java Fri Oct 03 13:48:58 2014 +0200 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 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.truffle.test.builtins; + +import java.util.concurrent.*; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.CompilerDirectives.SlowPath; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.sl.runtime.*; + +/** + * Just used in TestSlowPath01.sl. Verifies that all intrinsics have no effect inside of a @SlowPath + * annotated method. + */ +@NodeInfo(shortName = "testSlowPath01") +public abstract class SLTestSlowPath01Builtin extends SLGraalRuntimeBuiltin { + + private static Object nonConstantValue = new Object(); + + @Specialization + @SlowPath + public Object testSlowPath() { + CompilerAsserts.neverPartOfCompilation(); + CompilerAsserts.neverPartOfCompilation("Should never throw an exception when compiling."); + CompilerAsserts.compilationConstant(nonConstantValue); + CompilerDirectives.transferToInterpreter(); + CompilerDirectives.transferToInterpreterAndInvalidate(); + CompilerDirectives.bailout("Should not fail"); + if (CompilerDirectives.inCompiledCode()) { + throw new AssertionError(); + } + if (!CompilerDirectives.inInterpreter()) { + throw new AssertionError(); + } + try { + int result = (int) CompilerDirectives.interpreterOnly(new Callable() { + public Object call() throws Exception { + return 1; + } + }); + if (result != 1) { + throw new AssertionError(); + } + } catch (Exception e) { + throw new AssertionError(); + } + + return SLNull.SINGLETON; + } +} diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLWaitForOptimizationBuiltin.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLWaitForOptimizationBuiltin.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLWaitForOptimizationBuiltin.java Fri Oct 03 13:48:58 2014 +0200 @@ -54,7 +54,7 @@ @Specialization public SLFunction waitForCompilation(SLFunction function, @SuppressWarnings("unused") SLNull timeout) { - return waitForOptimization(function, 120000); + return waitForOptimization(function, 640000); } } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/ContextSensitiveInlining.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/ContextSensitiveInlining.java Fri Oct 03 13:48:58 2014 +0200 @@ -0,0 +1,200 @@ +/* + * 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.truffle; + +import java.util.*; +import java.util.stream.*; + +import com.oracle.graal.truffle.ContextSensitiveInlining.InliningDecision; + +public class ContextSensitiveInlining implements Iterable { + + private final List callSites; + + private ContextSensitiveInlining(List callSites) { + this.callSites = callSites; + } + + public ContextSensitiveInlining(OptimizedCallTarget sourceTarget, TruffleInliningPolicy policy) { + this(decideInlining(OptimizedCallUtils.countNonTrivialNodes(sourceTarget, false), exploreCallSites(new ArrayList<>(Arrays.asList(sourceTarget)), policy), policy)); + } + + private static List exploreCallSites(List stack, TruffleInliningPolicy policy) { + List exploredCallSites = new ArrayList<>(); + OptimizedCallTarget parentTarget = stack.get(stack.size() - 1); + for (OptimizedDirectCallNode callNode : parentTarget.getCallNodes()) { + OptimizedCallTarget currentTarget = callNode.getCurrentCallTarget(); + stack.add(currentTarget); // push + exploredCallSites.add(exploreCallSite(stack, policy, callNode)); + stack.remove(stack.size() - 1); // pop + } + return exploredCallSites; + } + + private static InliningDecision exploreCallSite(List callStack, TruffleInliningPolicy policy, OptimizedDirectCallNode callNode) { + OptimizedCallTarget parentTarget = callStack.get(callStack.size() - 2); + OptimizedCallTarget currentTarget = callStack.get(callStack.size() - 1); + + boolean recursive = isRecursiveStack(callStack); + boolean maxDepth = callStack.size() >= 15; + + List childCallSites; + double frequency = TruffleInliningHandler.calculateFrequency(parentTarget, callNode); + int nodeCount = OptimizedCallUtils.countNonTrivialNodes(callNode.getCurrentCallTarget(), false); + int deepNodeCount; + if (recursive || maxDepth) { + deepNodeCount = nodeCount; + childCallSites = Collections.emptyList(); + } else { + childCallSites = decideInlining(nodeCount, exploreCallSites(callStack, policy), policy); + deepNodeCount = nodeCount; + for (InliningDecision childCallSite : childCallSites) { + if (childCallSite.isInline()) { + deepNodeCount += childCallSite.getProfile().getDeepNodeCount(); + } + } + } + + TruffleInliningProfile profile = new TruffleInliningProfile(callNode, nodeCount, deepNodeCount, frequency, recursive, null); + profile.setScore(policy.calculateScore(profile)); + return new InliningDecision(currentTarget, profile, childCallSites); + } + + private static boolean isRecursiveStack(List stack) { + OptimizedCallTarget top = stack.get(stack.size() - 1); + for (int i = 0; i < stack.size() - 1; i++) { + if (stack.get(i) == top) { + return true; + } + } + return false; + } + + private static List decideInlining(int nodeCount, List callSites, TruffleInliningPolicy policy) { + int deepNodeCount = nodeCount; + int index = 0; + for (InliningDecision callSite : callSites.stream().sorted().collect(Collectors.toList())) { + TruffleInliningProfile profile = callSite.getProfile(); + profile.setQueryIndex(index++); + if (policy.isAllowed(profile, deepNodeCount)) { + callSite.setInline(true); + deepNodeCount += profile.getDeepNodeCount(); + } + } + return callSites; + } + + public boolean isInlined(List callNodeTrace) { + if (callNodeTrace.isEmpty()) { + return false; + } + + InliningDecision prev = null; + for (int i = 0; i < callNodeTrace.size(); i++) { + if (prev == null) { + prev = findByCall(callNodeTrace.get(i)); + } else { + prev = prev.findByCall(callNodeTrace.get(i)); + } + if (prev == null || !prev.isInline()) { + return false; + } + } + return true; + } + + public int countCalls() { + return callSites.stream().mapToInt(callSite -> callSite.isInline() ? callSite.countCalls() + 1 : 1).sum(); + } + + public int countInlinedCalls() { + return callSites.stream().filter(InliningDecision::isInline).mapToInt(callSite -> callSite.countInlinedCalls() + 1).sum(); + } + + public List getCallSites() { + return callSites; + } + + public Iterator iterator() { + return callSites.iterator(); + } + + public InliningDecision findByCall(OptimizedDirectCallNode callNode) { + return getCallSites().stream().filter(c -> c.getProfile().getCallNode() == callNode).findFirst().orElse(null); + } + + public static final class InliningDecision extends ContextSensitiveInlining implements Comparable { + + private final OptimizedCallTarget target; + private final TruffleInliningProfile profile; + private boolean inline; + + public InliningDecision(OptimizedCallTarget target, TruffleInliningProfile profile, List children) { + super(children); + this.target = target; + this.profile = profile; + } + + public OptimizedCallTarget getTarget() { + return target; + } + + public void setInline(boolean inline) { + this.inline = inline; + } + + public boolean isInline() { + return inline; + } + + public TruffleInliningProfile getProfile() { + return profile; + } + + public int compareTo(InliningDecision o) { + return Double.compare(o.getProfile().getScore(), getProfile().getScore()); + } + + public boolean isSameAs(InliningDecision other) { + if (getTarget() != other.getTarget()) { + return false; + } else if (isInline() != other.isInline()) { + return false; + } else if (!isInline()) { + assert !other.isInline(); + return true; + } else { + Iterator i1 = iterator(); + Iterator i2 = other.iterator(); + while (i1.hasNext() && i2.hasNext()) { + if (!i1.next().isSameAs(i2.next())) { + return false; + } + } + return !i1.hasNext() && !i2.hasNext(); + } + } + + } + +} diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultInliningPolicy.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultInliningPolicy.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultInliningPolicy.java Fri Oct 03 13:48:58 2014 +0200 @@ -40,15 +40,15 @@ return false; } - if (profile.isForced()) { - return true; - } - if (currentNodeCount + profile.getDeepNodeCount() > TruffleInliningMaxCallerSize.getValue()) { profile.setFailedReason(REASON_MAXIMUM_TOTAL_NODE_COUNT); return false; } + if (profile.isForced()) { + return true; + } + int cappedCallSites = Math.min(Math.max(profile.getCallSites(), 1), 10); if (profile.getDeepNodeCount() * cappedCallSites > TruffleInliningMaxCallerSize.getValue()) { profile.setFailedReason(REASON_MAXIMUM_NODE_COUNT); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Fri Oct 03 13:48:58 2014 +0200 @@ -26,11 +26,14 @@ import static com.oracle.graal.truffle.TruffleCompilerOptions.*; import java.io.*; +import java.lang.reflect.*; import java.util.*; import java.util.concurrent.atomic.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; +import com.oracle.graal.truffle.ContextSensitiveInlining.InliningDecision; import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.frame.*; @@ -58,9 +61,13 @@ private final RootNode rootNode; + /* Experimental fields for new splitting. */ private final Map splitVersions = new HashMap<>(); private TruffleStamp argumentStamp = DefaultTruffleStamp.getInstance(); + /* Experimental field for context sensitive inlining. */ + private ContextSensitiveInlining inliningDecision; + public final RootNode getRootNode() { return rootNode; } @@ -121,7 +128,7 @@ return doInvoke(args); } - public Object callDirect(Object... args) { + public final Object callDirect(Object... args) { profileArguments(args); Object result = doInvoke(args); Class klass = profiledReturnType; @@ -131,6 +138,14 @@ return result; } + public final Object callInlined(Object... arguments) { + if (CompilerDirectives.inInterpreter()) { + compilationProfile.reportInlinedCall(); + } + VirtualFrame frame = createFrame(getRootNode().getFrameDescriptor(), arguments); + return callProxy(frame); + } + @ExplodeLoop private void profileArguments(Object[] args) { if (profiledArgumentTypesAssumption == null) { @@ -204,7 +219,32 @@ // We come here from compiled code (i.e., we have been inlined). } - return callRoot(args); + Object[] args1 = args; + if (this.profiledArgumentTypesAssumption != null && CompilerDirectives.inCompiledCode() && profiledArgumentTypesAssumption.isValid()) { + args1 = CompilerDirectives.unsafeCast(castArrayFixedLength(args1, profiledArgumentTypes.length), Object[].class, true, true); + if (TruffleArgumentTypeSpeculation.getValue()) { + args1 = castArguments(args1); + } + } + VirtualFrame frame = createFrame(getRootNode().getFrameDescriptor(), args1); + Object result = callProxy(frame); + + // Profile call return type + if (profiledReturnTypeAssumption == null) { + if (TruffleReturnTypeSpeculation.getValue()) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + profiledReturnType = (result == null ? null : result.getClass()); + profiledReturnTypeAssumption = runtime.createAssumption("Profiled Return Type"); + } + } else if (profiledReturnType != null) { + if (result == null || profiledReturnType != result.getClass()) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + profiledReturnType = null; + profiledReturnTypeAssumption.invalidate(); + } + } + + return result; } @Override @@ -241,6 +281,26 @@ } } + public ContextSensitiveInlining getInliningDecision() { + return inliningDecision; + } + + public void setInliningDecision(ContextSensitiveInlining inliningDecision) { + this.inliningDecision = inliningDecision; + } + + public boolean isInlined(List callNodeTrace) { + if (TruffleCompilerOptions.TruffleContextSensitiveInlining.getValue()) { + if (inliningDecision == null) { + return false; + } else { + return inliningDecision.isInlined(callNodeTrace); + } + } else { + return callNodeTrace.get(callNodeTrace.size() - 1).isInlined(); + } + } + private void cancelInstalledTask(Node oldNode, Node newNode, CharSequence reason) { if (this.runtime.cancelInstalledTask(this)) { logOptimizingUnqueued(this, oldNode, newNode, reason); @@ -275,6 +335,9 @@ public void compilationFinished(Throwable t) { if (t == null) { // Compilation was successful. + if (inliningDecision != null) { + dequeueInlinedCallSites(inliningDecision); + } } else { compilationPolicy.recordCompilationFailure(t); @@ -291,6 +354,18 @@ } } + private void dequeueInlinedCallSites(ContextSensitiveInlining parentDecision) { + for (InliningDecision decision : parentDecision) { + if (decision.isInline()) { + OptimizedCallTarget target = decision.getProfile().getCallNode().getCurrentCallTarget(); + if (runtime.cancelInstalledTask(target)) { + logOptimizingUnqueued(target, null, null, "Inlining caller compiled."); + } + dequeueInlinedCallSites(decision); + } + } + } + protected final Object callProxy(VirtualFrame frame) { try { return getRootNode().execute(frame); @@ -336,16 +411,8 @@ return compilationProfile; } - public final Object callInlined(Object[] arguments) { - if (CompilerDirectives.inInterpreter()) { - compilationProfile.reportInlinedCall(); - } - VirtualFrame frame = createFrame(getRootNode().getFrameDescriptor(), arguments); - return callProxy(frame); - } - public final void performInlining() { - if (!TruffleFunctionInlining.getValue()) { + if (!TruffleFunctionInlining.getValue() || TruffleContextSensitiveInlining.getValue()) { return; } if (inliningPerformed) { @@ -371,36 +438,6 @@ } } - public final Object callRoot(Object[] originalArguments) { - Object[] args = originalArguments; - if (this.profiledArgumentTypesAssumption != null && CompilerDirectives.inCompiledCode() && profiledArgumentTypesAssumption.isValid()) { - args = CompilerDirectives.unsafeCast(castArrayFixedLength(args, profiledArgumentTypes.length), Object[].class, true, true); - if (TruffleArgumentTypeSpeculation.getValue()) { - args = castArguments(args); - } - } - - VirtualFrame frame = createFrame(getRootNode().getFrameDescriptor(), args); - Object result = callProxy(frame); - - // Profile call return type - if (profiledReturnTypeAssumption == null) { - if (TruffleReturnTypeSpeculation.getValue()) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - profiledReturnType = (result == null ? null : result.getClass()); - profiledReturnTypeAssumption = Truffle.getRuntime().createAssumption("Profiled Return Type"); - } - } else if (profiledReturnType != null) { - if (result == null || profiledReturnType != result.getClass()) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - profiledReturnType = null; - profiledReturnTypeAssumption.invalidate(); - } - } - - return result; - } - @ExplodeLoop private Object[] castArguments(Object[] originalArguments) { Object[] castArguments = new Object[profiledArgumentTypes.length]; @@ -418,6 +455,10 @@ return new FrameWithoutBoxing(descriptor, args); } + public List getCallNodes() { + return NodeUtil.findAllNodeInstances(getRootNode(), OptimizedDirectCallNode.class); + } + @Override public void reportLoopCount(int count) { compilationProfile.reportLoopCount(count); @@ -437,4 +478,20 @@ } + public static Method getCallDirectMethod() { + try { + return OptimizedCallTarget.class.getDeclaredMethod("callDirect", Object[].class); + } catch (NoSuchMethodException | SecurityException e) { + throw new GraalInternalError(e); + } + } + + public static Method getCallInlinedMethod() { + try { + return OptimizedCallTarget.class.getDeclaredMethod("callInlined", Object[].class); + } catch (NoSuchMethodException | SecurityException e) { + throw new GraalInternalError(e); + } + } + } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java Fri Oct 03 13:48:58 2014 +0200 @@ -28,6 +28,7 @@ import java.util.*; import com.oracle.graal.debug.*; +import com.oracle.graal.truffle.ContextSensitiveInlining.InliningDecision; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.api.nodes.NodeUtil.NodeCountFilter; @@ -53,6 +54,29 @@ private OptimizedCallTargetLog() { } + public static void logInliningDecision(OptimizedCallTarget target) { + ContextSensitiveInlining inlining = target.getInliningDecision(); + if (!TraceTruffleInlining.getValue() || inlining == null) { + return; + } + + logInliningStart(target); + logInliningDecisionRecursive(inlining, 1); + logInliningDone(target); + } + + private static void logInliningDecisionRecursive(ContextSensitiveInlining result, int depth) { + for (InliningDecision decision : result) { + TruffleInliningProfile profile = decision.getProfile(); + boolean inlined = decision.isInline(); + String msg = inlined ? "inline success" : "inline failed"; + logInlinedImpl(msg, decision.getProfile().getCallNode(), profile, depth); + if (inlined) { + logInliningDecisionRecursive(decision, depth + 1); + } + } + } + public static void logInliningDecision(TruffleInliningDecision result) { if (!TraceTruffleInlining.getValue()) { return; @@ -119,7 +143,6 @@ private static void logInlinedImpl(String status, OptimizedDirectCallNode callNode, TruffleInliningProfile profile, int depth) { Map properties = new LinkedHashMap<>(); - addASTSizeProperty(callNode.getCurrentCallTarget(), properties); if (profile != null) { properties.putAll(profile.getDebugProperties()); } @@ -224,20 +247,31 @@ } public static void addASTSizeProperty(OptimizedCallTarget target, Map properties) { - int polymorphicCount = NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() { - public boolean isCounted(Node node) { - return node.getCost() == NodeCost.POLYMORPHIC; - } - }, true); + if (TruffleContextSensitiveInlining.getValue() && target.getInliningDecision() != null) { + int deepCount = target.getInliningDecision().getCallSites().stream().filter(callSite -> callSite.isInline()).mapToInt(callSite -> callSite.getProfile().getDeepNodeCount()).sum(); + long nodeCount = OptimizedCallUtils.countNonTrivialNodes(target, false); + properties.put("ASTSize", String.format("%5d/%5d", nodeCount, nodeCount + deepCount)); + } else { + int polymorphicCount = NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() { + public boolean isCounted(Node node) { + return node.getCost() == NodeCost.POLYMORPHIC; + } + }, true); - int megamorphicCount = NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() { - public boolean isCounted(Node node) { - return node.getCost() == NodeCost.MEGAMORPHIC; - } - }, true); + int megamorphicCount = NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() { + public boolean isCounted(Node node) { + return node.getCost() == NodeCost.MEGAMORPHIC; + } + }, true); - String value = String.format("%4d (%d/%d)", OptimizedCallUtils.countNonTrivialNodes(target, true), polymorphicCount, megamorphicCount); - properties.put("ASTSize", value); + String value = String.format("%4d (%d/%d)", OptimizedCallUtils.countNonTrivialNodes(target, true), polymorphicCount, megamorphicCount); + properties.put("ASTSize", value); + } + + } + + public static void logPerformanceWarning(String details, Map properties) { + log(0, "perf warn", details, properties); } static void log(int indent, String msg, String details, Map properties) { diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallUtils.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallUtils.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallUtils.java Fri Oct 03 13:48:58 2014 +0200 @@ -32,19 +32,29 @@ public class OptimizedCallUtils { public static int countCalls(OptimizedCallTarget target) { - return NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() { - public boolean isCounted(Node node) { - return node instanceof DirectCallNode; - } - }, true); + ContextSensitiveInlining inlining = target.getInliningDecision(); + if (inlining != null) { + return inlining.countCalls(); + } else { + return NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() { + public boolean isCounted(Node node) { + return node instanceof DirectCallNode; + } + }, true); + } } public static int countCallsInlined(OptimizedCallTarget target) { - return NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() { - public boolean isCounted(Node node) { - return (node instanceof OptimizedDirectCallNode) && ((OptimizedDirectCallNode) node).isInlined(); - } - }, true); + ContextSensitiveInlining inlining = target.getInliningDecision(); + if (inlining != null) { + return inlining.countInlinedCalls(); + } else { + return NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() { + public boolean isCounted(Node node) { + return (node instanceof OptimizedDirectCallNode) && ((OptimizedDirectCallNode) node).isInlined(); + } + }, true); + } } public static int countNonTrivialNodes(final OptimizedCallTarget target, final boolean inlined) { diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedDirectCallNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedDirectCallNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedDirectCallNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -57,7 +57,14 @@ if (CompilerDirectives.inInterpreter()) { onInterpreterCall(arguments); } - Object result = callProxy(this, getCurrentCallTarget(), frame, arguments, inlined, true); + boolean isInlined; + if (TruffleCompilerOptions.TruffleContextSensitiveInlining.getValue()) { + /* Inlining done during partial evalulation. */ + isInlined = false; + } else { + isInlined = this.inlined; + } + Object result = callProxy(this, getCurrentCallTarget(), frame, arguments, isInlined, true); if (CompilerDirectives.inInterpreter()) { afterInterpreterCall(result); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Fri Oct 03 13:48:58 2014 +0200 @@ -51,6 +51,7 @@ import com.oracle.graal.phases.common.inlining.info.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; +import com.oracle.graal.truffle.ContextSensitiveInlining.InliningDecision; import com.oracle.graal.truffle.nodes.asserts.*; import com.oracle.graal.truffle.nodes.frame.*; import com.oracle.graal.truffle.nodes.frame.NewFrameNode.VirtualOnlyInstanceNode; @@ -58,6 +59,9 @@ import com.oracle.graal.virtual.phases.ea.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.nodes.Node.Child; +import com.oracle.truffle.api.nodes.Node.Children; +import static com.oracle.graal.truffle.OptimizedCallTargetLog.*; /** * Class performing the partial evaluation starting from the root node of an AST. @@ -68,53 +72,45 @@ private final CanonicalizerPhase canonicalizer; private Set constantReceivers; private final TruffleCache truffleCache; + private final SnippetReflectionProvider snippetReflection; + private final ResolvedJavaMethod callDirectMethod; + private final ResolvedJavaMethod callSiteProxyMethod; public PartialEvaluator(Providers providers, TruffleCache truffleCache) { this.providers = providers; CustomCanonicalizer customCanonicalizer = new PartialEvaluatorCanonicalizer(providers.getMetaAccess(), providers.getConstantReflection()); this.canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue(), customCanonicalizer); + this.snippetReflection = Graal.getRequiredCapability(SnippetReflectionProvider.class); this.truffleCache = truffleCache; + this.callDirectMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallDirectMethod()); + this.callSiteProxyMethod = providers.getMetaAccess().lookupJavaMethod(GraalFrameInstance.CallNodeFrame.METHOD); } - public StructuredGraph createGraph(final OptimizedCallTarget callTarget, final Assumptions assumptions) { - try (Scope s = Debug.scope("TruffleTree")) { + public StructuredGraph createGraph(final OptimizedCallTarget callTarget, final Assumptions assumptions, ContextSensitiveInlining inlining) { + if (TraceTruffleCompilationHistogram.getValue() || TraceTruffleCompilationDetails.getValue()) { + constantReceivers = new HashSet<>(); + } + + try (Scope c = Debug.scope("TruffleTree")) { Debug.dump(callTarget, "truffle tree"); } catch (Throwable e) { throw Debug.handle(e); } - - if (TraceTruffleCompilationHistogram.getValue() || TraceTruffleCompilationDetails.getValue()) { - constantReceivers = new HashSet<>(); - } - final StructuredGraph graph = truffleCache.createRootGraph(callTarget.toString()); assert graph != null : "no graph for root method"; try (Scope s = Debug.scope("CreateGraph", graph); Indent indent = Debug.logAndIndent("createGraph %s", graph.method())) { - - // Replace thisNode with constant. - ParameterNode thisNode = graph.getParameter(0); - - /* - * Converting the call target to a Constant using the SnippetReflectionProvider is a - * workaround, we should think about a better solution. Since object constants are - * VM-specific, only the hosting VM knows how to do the conversion. - */ - SnippetReflectionProvider snippetReflection = Graal.getRequiredCapability(SnippetReflectionProvider.class); - thisNode.replaceAndDelete(ConstantNode.forConstant(snippetReflection.forObject(callTarget), providers.getMetaAccess(), graph)); - // Canonicalize / constant propagate. PhaseContext baseContext = new PhaseContext(providers, assumptions); - canonicalizer.apply(graph, baseContext); - // Intrinsify methods. - new IncrementalCanonicalizerPhase<>(canonicalizer, new ReplaceIntrinsicsPhase(providers.getReplacements())).apply(graph, baseContext); + injectConstantCallTarget(graph, callTarget, baseContext); - Debug.dump(graph, "Before inlining"); + Debug.dump(graph, "Before expansion"); - // Make sure frame does not escape. expandTree(graph, assumptions); + expandDirectCalls(graph, assumptions, inlining != null ? new TruffleInliningCache() : null, inlining); + if (Thread.currentThread().isInterrupted()) { return null; } @@ -170,6 +166,7 @@ } } } + } catch (Throwable e) { throw Debug.handle(e); } @@ -177,6 +174,49 @@ return graph; } + private void expandDirectCalls(StructuredGraph graph, Assumptions assumptions, TruffleInliningCache inliningCache, ContextSensitiveInlining inlining) { + if (inlining == null) { + return; + } + PhaseContext phaseContext = new PhaseContext(providers, assumptions); + TruffleExpansionLogger expansionLogger = new TruffleExpansionLogger(providers, graph); + + for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.class).snapshot()) { + StructuredGraph inlineGraph = parseDirectCallGraph(phaseContext, assumptions, inliningCache, inlining, methodCallTargetNode); + + if (inlineGraph != null) { + expandTreeInline(graph, phaseContext, expansionLogger, methodCallTargetNode, inlineGraph); + } + } + // non inlined direct calls need to be expanded until TruffleCallBoundary. + expandTree(graph, assumptions); + assert noDirectCallsLeft(graph); + } + + private boolean noDirectCallsLeft(StructuredGraph graph) { + for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.class).snapshot()) { + if (methodCallTargetNode.targetMethod().equals(callDirectMethod)) { + return false; + } + } + return true; + } + + private void injectConstantCallTarget(final StructuredGraph graph, final OptimizedCallTarget constantCallTarget, PhaseContext baseContext) { + ParameterNode thisNode = graph.getParameter(0); + + /* + * Converting the call target to a Constant using the SnippetReflectionProvider is a + * workaround, we should think about a better solution. Since object constants are + * VM-specific, only the hosting VM knows how to do the conversion. + */ + thisNode.replaceAndDelete(ConstantNode.forConstant(snippetReflection.forObject(constantCallTarget), providers.getMetaAccess(), graph)); + + canonicalizer.apply(graph, baseContext); + + new IncrementalCanonicalizerPhase<>(canonicalizer, new ReplaceIntrinsicsPhase(providers.getReplacements())).apply(graph, baseContext); + } + private void createHistogram() { DebugHistogram histogram = Debug.createHistogram("Expanded Truffle Nodes"); for (Constant c : constantReceivers) { @@ -219,9 +259,10 @@ changed = changedInIteration = true; continue; } + StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod()); - StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod()); - if (inlineGraph == null && !methodCallTargetNode.targetMethod().isNative() && methodCallTargetNode.targetMethod().canBeInlined()) { + ResolvedJavaMethod targetMethod = methodCallTargetNode.targetMethod(); + if (inlineGraph == null && !targetMethod.isNative() && targetMethod.canBeInlined()) { inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions, phaseContext); } @@ -236,6 +277,7 @@ throw new BailoutException("Truffle compilation is exceeding maximum node count: " + graph.getNodeCount()); } } + } while (changedInIteration); if (TraceTruffleExpansion.getValue()) { @@ -244,20 +286,113 @@ return changed; } + private StructuredGraph parseDirectCallGraph(PhaseContext phaseContext, Assumptions assumptions, TruffleInliningCache inliningCache, ContextSensitiveInlining inlining, + MethodCallTargetNode methodCallTargetNode) { + OptimizedDirectCallNode callNode = resolveConstantCallNode(methodCallTargetNode); + if (callNode == null) { + return null; + } + + InliningDecision decision = inlining.findByCall(callNode); + if (decision == null) { + if (TruffleCompilerOptions.PrintTrufflePerformanceWarnings.getValue()) { + logPerformanceWarning(String.format("%s '%s' is reached using partial evaluation but it is not reachable in the Truffle AST. Did you miss @%s or @%s annotation on a node field?. ", + DirectCallNode.class.getSimpleName(), callNode, Child.class.getSimpleName(), Children.class.getSimpleName()), callNode.getRootNode().getDebugProperties()); + } + return null; + } + + assert decision.getProfile().getCallNode() == callNode; + + OptimizedCallTarget currentTarget = decision.getProfile().getCallNode().getCurrentCallTarget(); + if (decision.getTarget() != currentTarget) { + if (TruffleCompilerOptions.PrintTrufflePerformanceWarnings.getValue()) { + logPerformanceWarning( + String.format("CallTarget '%s' changed to '%s' during compilation for call node '%s'. Call node was not inlined.", decision.getTarget(), currentTarget, callNode), null); + + } + return null; + } + + StructuredGraph graph; + if (decision.isInline()) { + if (inliningCache == null) { + graph = createInlineGraph(phaseContext, assumptions, null, decision); + } else { + graph = inliningCache.getCachedGraph(phaseContext, assumptions, decision); + } + decision.getProfile().setGraalDeepNodeCount(graph.getNodeCount()); + } else { + graph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions, phaseContext); + } + + return graph; + } + + private StructuredGraph createInlineGraph(PhaseContext phaseContext, Assumptions assumptions, TruffleInliningCache cache, InliningDecision decision) { + OptimizedCallTarget target = decision.getTarget(); + StructuredGraph inlineGraph = truffleCache.createInlineGraph(target.toString()); + injectConstantCallTarget(inlineGraph, decision.getTarget(), phaseContext); + expandTree(inlineGraph, assumptions); + expandDirectCalls(inlineGraph, assumptions, cache, decision); + return inlineGraph; + } + + private OptimizedDirectCallNode resolveConstantCallNode(MethodCallTargetNode methodCallTargetNode) { + if (!methodCallTargetNode.targetMethod().equals(callDirectMethod)) { + return null; + } + + Invoke invoke = methodCallTargetNode.invoke(); + if (invoke == null) { + return null; + } + + FrameState directCallState = invoke.stateAfter(); + while (directCallState != null && directCallState.method() != callSiteProxyMethod) { + directCallState = directCallState.outerFrameState(); + } + + if (directCallState == null) { + // not a direct call. May be indirect call. + return null; + } + + if (directCallState.values().isEmpty()) { + throw new AssertionError(String.format("Frame state of method '%s' is invalid.", callDirectMethod.toString())); + } + + ValueNode node = directCallState.values().get(0); + if (!node.isConstant()) { + throw new AssertionError(String.format("Method argument for method '%s' is not constant.", callDirectMethod.toString())); + } + + Constant constantCallNode = node.asConstant(); + Object value = snippetReflection.asObject(constantCallNode); + + if (!(value instanceof OptimizedDirectCallNode)) { + // might be an indirect call. + return null; + } + + return (OptimizedDirectCallNode) value; + } + private void expandTreeInline(StructuredGraph graph, PhaseContext phaseContext, TruffleExpansionLogger expansionLogger, MethodCallTargetNode methodCallTargetNode, StructuredGraph inlineGraph) { - try (Indent indent = Debug.logAndIndent("inline graph %s", methodCallTargetNode.targetMethod())) { + try (Indent indent = Debug.logAndIndent("expand graph %s", methodCallTargetNode.targetMethod())) { int nodeCountBefore = graph.getNodeCount(); if (TraceTruffleExpansion.getValue()) { expansionLogger.preExpand(methodCallTargetNode, inlineGraph); } List canonicalizedNodes = methodCallTargetNode.invoke().asNode().usages().snapshot(); + Map inlined = InliningUtil.inline(methodCallTargetNode.invoke(), inlineGraph, false, canonicalizedNodes); if (TraceTruffleExpansion.getValue()) { expansionLogger.postExpand(inlined); } if (Debug.isDumpEnabled()) { int nodeCountAfter = graph.getNodeCount(); - Debug.dump(graph, "After inlining %s %+d (%d)", methodCallTargetNode.targetMethod().toString(), nodeCountAfter - nodeCountBefore, nodeCountAfter); + Debug.dump(graph, "After expand %s %+d (%d)", methodCallTargetNode.targetMethod().toString(), nodeCountAfter - nodeCountBefore, nodeCountAfter); } AbstractInlineInfo.getInlinedParameterUsages(canonicalizedNodes, inlineGraph, inlined); canonicalizer.applyIncremental(graph, phaseContext, canonicalizedNodes); @@ -325,4 +460,51 @@ return sortedLoops; } + private final class TruffleInliningCache { + + private final Map cache; + + public TruffleInliningCache() { + this.cache = new HashMap<>(); + } + + public StructuredGraph getCachedGraph(PhaseContext phaseContext, Assumptions assumptions, InliningDecision decision) { + CacheKey cacheKey = new CacheKey(decision); + StructuredGraph inlineGraph = cache.get(cacheKey); + if (inlineGraph == null) { + inlineGraph = createInlineGraph(phaseContext, assumptions, this, decision); + cache.put(cacheKey, inlineGraph); + } + return inlineGraph; + } + + private final class CacheKey { + + public final InliningDecision decision; + + public CacheKey(InliningDecision decision) { + this.decision = decision; + /* + * If decision.isInline() is not true CacheKey#hashCode does not match + * CacheKey#equals + */ + assert decision.isInline(); + } + + @Override + public int hashCode() { + return decision.getTarget().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof CacheKey)) { + return false; + } + CacheKey other = (CacheKey) obj; + return decision.isSameAs(other.decision); + } + } + } + } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Fri Oct 03 13:48:58 2014 +0200 @@ -35,6 +35,8 @@ */ StructuredGraph createRootGraph(String name); + StructuredGraph createInlineGraph(String name); + /** * Returns a cached graph for a method with given arguments. */ diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Fri Oct 03 13:48:58 2014 +0200 @@ -56,7 +56,7 @@ private final Providers providers; private final GraphBuilderConfiguration config; - private final GraphBuilderConfiguration configForRootGraph; + private final GraphBuilderConfiguration configForRoot; private final OptimisticOptimizations optimisticOptimizations; private final HashMap, StructuredGraph> cache = new HashMap<>(); @@ -69,12 +69,14 @@ private final ResolvedJavaType controlFlowExceptionClass; private final ResolvedJavaMethod callBoundaryMethod; + private final ResolvedJavaMethod callInlinedMethod; + private long counter; - public TruffleCacheImpl(Providers providers, GraphBuilderConfiguration config, GraphBuilderConfiguration configForRootGraph, OptimisticOptimizations optimisticOptimizations) { + public TruffleCacheImpl(Providers providers, GraphBuilderConfiguration config, GraphBuilderConfiguration configForRoot, OptimisticOptimizations optimisticOptimizations) { this.providers = providers; this.config = config; - this.configForRootGraph = configForRootGraph; + this.configForRoot = configForRoot; this.optimisticOptimizations = optimisticOptimizations; this.stringBuilderClass = providers.getMetaAccess().lookupJavaType(StringBuilder.class); @@ -83,15 +85,22 @@ this.controlFlowExceptionClass = providers.getMetaAccess().lookupJavaType(ControlFlowException.class); try { - callBoundaryMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("callRoot", Object[].class)); + callBoundaryMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("callBoundary", Object[].class)); } catch (NoSuchMethodException ex) { throw new RuntimeException(ex); } + this.callInlinedMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallInlinedMethod()); + } + + public StructuredGraph createInlineGraph(String name) { + StructuredGraph graph = new StructuredGraph(name, callInlinedMethod); + new GraphBuilderPhase.Instance(providers.getMetaAccess(), config, TruffleCompilerImpl.Optimizations).apply(graph); + return graph; } public StructuredGraph createRootGraph(String name) { StructuredGraph graph = new StructuredGraph(name, callBoundaryMethod); - new GraphBuilderPhase.Instance(providers.getMetaAccess(), configForRootGraph, TruffleCompilerImpl.Optimizations).apply(graph); + new GraphBuilderPhase.Instance(providers.getMetaAccess(), configForRoot, TruffleCompilerImpl.Optimizations).apply(graph); return graph; } @@ -183,6 +192,16 @@ } } + if (TruffleCompilerOptions.PrintTrufflePerformanceWarnings.getValue()) { + int warnNodeCount = TruffleCompilerOptions.TrufflePerformanceWarningGraalNodeCount.getValue(); + if (graph.getNodeCount() > warnNodeCount) { + Map map = new LinkedHashMap<>(); + map.put("nodeCount", graph.getNodeCount()); + map.put("method", method.toString()); + OptimizedCallTargetLog.logPerformanceWarning(String.format("Method on fast path contains more than %d graal nodes.", warnNodeCount), map); + } + } + cache.put(key, graph); if (TruffleCompilerOptions.TraceTruffleCacheDetails.getValue()) { TTY.println(String.format("[truffle] added to graph cache method %s with %d nodes.", method, graph.getNodeCount())); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Fri Oct 03 13:48:58 2014 +0200 @@ -80,7 +80,6 @@ ResolvedJavaType[] skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess()); GraphBuilderConfiguration eagerConfig = GraphBuilderConfiguration.getEagerDefault().withSkippedExceptionTypes(skippedExceptionTypes); this.config = GraphBuilderConfiguration.getDefault().withSkippedExceptionTypes(skippedExceptionTypes); - this.truffleCache = new TruffleCacheImpl(providers, eagerConfig, config, TruffleCompilerImpl.Optimizations); this.partialEvaluator = new PartialEvaluator(providers, truffleCache); @@ -122,8 +121,9 @@ long timeCompilationStarted = System.nanoTime(); Assumptions assumptions = new Assumptions(true); + ContextSensitiveInlining inlining = TruffleCompilerOptions.TruffleContextSensitiveInlining.getValue() ? new ContextSensitiveInlining(compilable, new DefaultInliningPolicy()) : null; try (TimerCloseable a = PartialEvaluationTime.start(); Closeable c = PartialEvaluationMemUse.start()) { - graph = partialEvaluator.createGraph(compilable, assumptions); + graph = partialEvaluator.createGraph(compilable, assumptions, inlining); } if (Thread.currentThread().isInterrupted()) { @@ -136,13 +136,15 @@ long timeCompilationFinished = System.nanoTime(); int nodeCountLowered = graph.getNodeCount(); - if (Thread.currentThread().isInterrupted()) { - return; + compilable.setInliningDecision(inlining); + + if (TraceTruffleInlining.getValue() && inlining != null) { + OptimizedCallTargetLog.logInliningDecision(compilable); } - if (TraceTruffleCompilation.getValue()) { printTruffleCompilation(compilable, timeCompilationStarted, timePartialEvaluationFinished, nodeCountPartialEval, compilationResult, timeCompilationFinished, nodeCountLowered); } + } private static void printTruffleCompilation(final OptimizedCallTarget compilable, long timeCompilationStarted, long timePartialEvaluationFinished, int nodeCountPartialEval, diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Fri Oct 03 13:48:58 2014 +0200 @@ -53,6 +53,10 @@ public static final OptionValue TruffleReplaceReprofileCount = new OptionValue<>(10); @Option(help = "Enable automatic inlining of call targets") public static final OptionValue TruffleFunctionInlining = new OptionValue<>(true); + @Option(help = "Experimental: Enable context senstive inlining decisions.") + public static final StableOptionValue TruffleContextSensitiveInlining = new StableOptionValue<>(false); + @Option(help = "Experimental: Enable an expansion cache per CallTarget. Only functionable with TruffleContextSensitiveInlining enabled.") + public static final OptionValue TruffleCallTargetExpansionCache = new OptionValue<>(true); @Option(help = "Maximum number of Graal IR nodes during partial evaluation") public static final OptionValue TruffleGraphMaxNodes = new OptionValue<>(200000); @Option(help = "Stop inlining if caller's cumulative tree size would exceed this limit") @@ -64,6 +68,9 @@ @Option(help = "Allow inlining of less hot candidates if tree size is small") public static final OptionValue TruffleInliningTrivialSize = new OptionValue<>(10); + @Option(help = "Defines the number of graal nodes that triggers a performance warning.") + public static final OptionValue TrufflePerformanceWarningGraalNodeCount = new OptionValue<>(1000); + @Option(help = "Enable call target splitting") public static final OptionValue TruffleSplitting = new OptionValue<>(true); @Option(help = "Experimental: Enable the new version of truffle splitting.") @@ -95,6 +102,8 @@ public static final OptionValue TruffleArgumentTypeSpeculation = new StableOptionValue<>(true); // tracing + @Option(help = "Prints potential performance problems of the guest language implementation.") + public static final OptionValue PrintTrufflePerformanceWarnings = new OptionValue<>(false); @Option(help = "") public static final OptionValue TraceTruffleCompilation = new OptionValue<>(false); @Option(help = "") diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java Fri Oct 03 13:48:58 2014 +0200 @@ -137,15 +137,16 @@ className = className.substring(lastIndex + 1, className.length()); } - lastIndex = className.lastIndexOf('$'); - if (lastIndex != -1) { - className = className.substring(lastIndex + 1, className.length()); - } + className = extractInnerClassName(className); String constantType = ""; if (targetReceiverType != null) { - if (!targetReceiverType.getName().equals(className)) { - constantType = "<" + targetReceiverType.getName() + ">"; + String javaName = targetReceiverType.toJavaName(false); + + javaName = extractInnerClassName(javaName); + + if (!javaName.equals(className)) { + constantType = "<" + javaName + ">"; } } @@ -164,6 +165,14 @@ } } + private static String extractInnerClassName(String className) { + int lastIndex = className.lastIndexOf('$'); + if (lastIndex != -1) { + return className.substring(lastIndex + 1, className.length()); + } + return className; + } + private static String formatSource(StackTraceElement e) { if (e == null) { return ""; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningHandler.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningHandler.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningHandler.java Fri Oct 03 13:48:58 2014 +0200 @@ -110,7 +110,7 @@ return policy; } - private static double calculateFrequency(OptimizedCallTarget target, OptimizedDirectCallNode ocn) { + public static double calculateFrequency(OptimizedCallTarget target, OptimizedDirectCallNode ocn) { return (double) Math.max(1, ocn.getCallCount()) / (double) Math.max(1, target.getCompilationProfile().getCallCount()); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningProfile.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningProfile.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningProfile.java Fri Oct 03 13:48:58 2014 +0200 @@ -33,6 +33,7 @@ private final boolean recursiveCall; private final TruffleInliningDecision recursiveResult; + private int graalDeepNodeCount = -1; private String failedReason; private int queryIndex = -1; private double score; @@ -104,11 +105,23 @@ public Map getDebugProperties() { Map properties = new LinkedHashMap<>(); - properties.put("nodeCount", String.format("%5d/%5d", deepNodeCount, nodeCount)); - properties.put("frequency", frequency); + properties.put("ASTSize", String.format("%5d/%5d", nodeCount, deepNodeCount)); + properties.put("frequency", String.format("%8.4f", getFrequency())); properties.put("score", String.format("%8.4f", getScore())); properties.put(String.format("index=%3d, force=%s, callSites=%2d", queryIndex, (isForced() ? "Y" : "N"), getCallSites()), ""); + if (graalDeepNodeCount != -1) { + properties.put("graalCount", String.format("%5d", graalDeepNodeCount)); + } properties.put("reason", failedReason); return properties; } + + public void setGraalDeepNodeCount(int graalDeepNodeCount) { + this.graalDeepNodeCount = graalDeepNodeCount; + } + + public int getGraalDeepNodeCount() { + return graalDeepNodeCount; + } + } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -30,7 +30,7 @@ @NodeInfo public class NeverPartOfCompilationNode extends MacroStateSplitNode implements IterableNodeType { - private final String message; + protected final String message; public static NeverPartOfCompilationNode create(Invoke invoke) { return USE_GENERATED_NODES ? new NeverPartOfCompilationNodeGen(invoke) : new NeverPartOfCompilationNode(invoke); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -106,13 +106,13 @@ @NodeInfo public static class VirtualOnlyInstanceNode extends VirtualInstanceNode { - private boolean allowMaterialization; + protected boolean allowMaterialization; public static VirtualOnlyInstanceNode create(ResolvedJavaType type, ResolvedJavaField[] fields) { return USE_GENERATED_NODES ? new NewFrameNode_VirtualOnlyInstanceNodeGen(type, fields) : new VirtualOnlyInstanceNode(type, fields); } - VirtualOnlyInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields) { + protected VirtualOnlyInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields) { super(type, fields, false); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -46,7 +46,7 @@ @Input ValueNode offset; @Input ValueNode condition; @Input ValueNode location; - private final Kind accessKind; + protected final Kind accessKind; public static CustomizedUnsafeLoadFinalNode create(ValueNode object, ValueNode offset, ValueNode condition, ValueNode location, Kind accessKind) { return USE_GENERATED_NODES ? new CustomizedUnsafeLoadFinalNodeGen(object, offset, condition, location, accessKind) : new CustomizedUnsafeLoadFinalNode(object, offset, condition, location, diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -67,10 +67,10 @@ replaceAtUsages(objectArgument); GraphUtil.removeFixedWithUnusedInputs(this); } else { - Stamp stamp = StampFactory.declared(lookupJavaType, nonNullArgument.asConstant().asInt() != 0, true); + Stamp piStamp = StampFactory.declared(lookupJavaType, nonNullArgument.asConstant().asInt() != 0, true); ConditionAnchorNode valueAnchorNode = graph().add( ConditionAnchorNode.create(CompareNode.createCompareNode(graph(), Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph())))); - PiNode piCast = graph().unique(PiNode.create(objectArgument, stamp, valueAnchorNode)); + PiNode piCast = graph().unique(PiNode.create(objectArgument, piStamp, valueAnchorNode)); replaceAtUsages(piCast); graph().replaceFixedWithFixed(this, valueAnchorNode); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Fri Oct 03 13:48:58 2014 +0200 @@ -49,7 +49,7 @@ private final Map, GraphEffectList> loopMergeEffects = newIdentityMap(); private final Map loopEntryStates = newNodeIdentityMap(); - private boolean changed; + protected boolean changed; public EffectsClosure(SchedulePhase schedule, ControlFlowGraph cfg) { this.schedule = schedule; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -46,7 +46,7 @@ @NodeInfo public class SnippetLocationNode extends LocationNode implements Canonicalizable { - private final SnippetReflectionProvider snippetReflection; + protected final SnippetReflectionProvider snippetReflection; @Input ValueNode valueKind; @Input(InputType.Association) ValueNode locationIdentity; @@ -64,7 +64,7 @@ displacement); } - SnippetLocationNode(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode kind, ValueNode displacement) { + protected SnippetLocationNode(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode kind, ValueNode displacement) { this(snippetReflection, locationIdentity, kind, displacement, null, null); } @@ -74,7 +74,7 @@ locationIdentity, kind, displacement, index, indexScaling); } - SnippetLocationNode(SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode kind, ValueNode displacement, ValueNode index, ValueNode indexScaling) { + protected SnippetLocationNode(SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode kind, ValueNode displacement, ValueNode index, ValueNode indexScaling) { super(StampFactory.object()); this.snippetReflection = snippetReflection; this.valueKind = kind; diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Fri Oct 03 13:48:58 2014 +0200 @@ -54,7 +54,7 @@ return USE_GENERATED_NODES ? new WordCastNodeGen(stamp, input) : new WordCastNode(stamp, input); } - WordCastNode(Stamp stamp, ValueNode input) { + protected WordCastNode(Stamp stamp, ValueNode input) { super(stamp); this.input = input; } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/GeneratedBy.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/GeneratedBy.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/GeneratedBy.java Fri Oct 03 13:48:58 2014 +0200 @@ -27,7 +27,7 @@ import java.lang.annotation.*; /** - * Marks a type to be generated by another class or a method. + * Marks a type as being generated based on another class or method. */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/DSLShare.java --- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/DSLShare.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/DSLShare.java Fri Oct 03 13:48:58 2014 +0200 @@ -25,6 +25,7 @@ package com.oracle.truffle.api.dsl.internal; import java.util.*; +import java.util.concurrent.*; import com.oracle.truffle.api.nodes.*; @@ -50,19 +51,23 @@ return containsClass(newNode.getMetadata0().getIncludes(), oldNode); } - public static T rewrite(Node thisNode, T newNode, String message) { - assert newNode != null; - if (getNext(thisNode) != null || getPrevious(thisNode) != null) { - // already polymorphic -> append - return appendPolymorphic(findUninitialized(thisNode), newNode); - } else if (includes(thisNode, newNode)) { - // included -> remains monomorphic - newNode.adoptChildren0(thisNode, null); - return thisNode.replace(newNode, message); - } else { - // goto polymorphic - return null; - } + public static T rewrite(final Node thisNode, final T newNode, final String message) { + return thisNode.atomic(new Callable() { + public T call() { + assert newNode != null; + if (getNext(thisNode) != null || getPrevious(thisNode) != null) { + // already polymorphic -> append + return appendPolymorphic(findUninitialized(thisNode), newNode); + } else if (includes(thisNode, newNode)) { + // included -> remains monomorphic + newNode.adoptChildren0(thisNode, null); + return thisNode.replace(newNode, message); + } else { + // goto polymorphic + return null; + } + } + }); } @SuppressWarnings("unchecked") @@ -86,37 +91,47 @@ return cur; } - public static T rewriteUninitialized(Node uninitialized, T newNode) { - Node prev = getPrevious(uninitialized); - if (prev == null) { - newNode.adoptChildren0(uninitialized, null); - return uninitialized.replace(newNode, "Uninitialized monomorphic"); - } else { - return appendPolymorphic(uninitialized, newNode); - } + public static T rewriteUninitialized(final Node uninitialized, final T newNode) { + return uninitialized.atomic(new Callable() { + public T call() { + Node prev = getPrevious(uninitialized); + if (prev == null) { + newNode.adoptChildren0(uninitialized, null); + return uninitialized.replace(newNode, "Uninitialized monomorphic"); + } else { + return appendPolymorphic(uninitialized, newNode); + } + } + }); + } - public static T rewriteToPolymorphic(Node oldNode, DSLNode uninitializedDSL, T polymorphic, DSLNode currentCopy, DSLNode newNodeDSL, String message) { - assert getNext(oldNode) == null; - assert getPrevious(oldNode) == null; - assert newNodeDSL != null; + public static T rewriteToPolymorphic(final Node oldNode, final DSLNode uninitializedDSL, final T polymorphic, final DSLNode currentCopy, final DSLNode newNodeDSL, + final String message) { + return oldNode.atomic(new Callable() { + public T call() { + assert getNext(oldNode) == null; + assert getPrevious(oldNode) == null; + assert newNodeDSL != null; - Node uninitialized = (Node) uninitializedDSL; - Node newNode = (Node) newNodeDSL; - polymorphic.adoptChildren0(oldNode, (Node) currentCopy); + Node uninitialized = (Node) uninitializedDSL; + Node newNode = (Node) newNodeDSL; + polymorphic.adoptChildren0(oldNode, (Node) currentCopy); - updateSourceSection(oldNode, uninitialized); - // new specialization - updateSourceSection(oldNode, newNode); - newNodeDSL.adoptChildren0(null, uninitialized); - currentCopy.adoptChildren0(null, newNode); + updateSourceSection(oldNode, uninitialized); + // new specialization + updateSourceSection(oldNode, newNode); + newNodeDSL.adoptChildren0(null, uninitialized); + currentCopy.adoptChildren0(null, newNode); - oldNode.replace(polymorphic, message); + oldNode.replace(polymorphic, message); - assert polymorphic.getNext0() == currentCopy; - assert newNode != null ? currentCopy.getNext0() == newNode : currentCopy.getNext0() == uninitialized; - assert uninitializedDSL.getNext0() == null; - return polymorphic; + assert polymorphic.getNext0() == currentCopy; + assert newNode != null ? currentCopy.getNext0() == newNode : currentCopy.getNext0() == uninitialized; + assert uninitializedDSL.getNext0() == null; + return polymorphic; + } + }); } private static void updateSourceSection(Node oldNode, Node newNode) { diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/InterfaceChildFieldTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/InterfaceChildFieldTest.java Fri Oct 03 13:48:58 2014 +0200 @@ -0,0 +1,153 @@ +/* + * 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.truffle.api.test; + +import java.util.*; + +import org.junit.*; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; + +/** + * Test child fields declared with interface types instead of {@link Node} subclasses. + */ +public class InterfaceChildFieldTest { + + @Test + public void testChild() { + TruffleRuntime runtime = Truffle.getRuntime(); + TestChildInterface leftChild = new TestLeafNode(); + TestChildInterface rightChild = new TestLeafNode(); + TestChildNode parent = new TestChildNode(leftChild, rightChild); + TestRootNode rootNode = new TestRootNode(parent); + CallTarget target = runtime.createCallTarget(rootNode); + Iterator iterator = parent.getChildren().iterator(); + Assert.assertEquals(leftChild, iterator.next()); + Assert.assertEquals(rightChild, iterator.next()); + Assert.assertFalse(iterator.hasNext()); + Object result = target.call(); + Assert.assertEquals(42, result); + + Assert.assertEquals(4, NodeUtil.countNodes(rootNode)); + Assert.assertEquals(4, NodeUtil.countNodes(NodeUtil.cloneNode(rootNode))); + } + + @Test + public void testChildren() { + TruffleRuntime runtime = Truffle.getRuntime(); + TestChildInterface[] children = new TestChildInterface[5]; + for (int i = 0; i < children.length; i++) { + children[i] = new TestLeafNode(); + } + TestChildrenNode parent = new TestChildrenNode(children); + TestRootNode rootNode = new TestRootNode(parent); + CallTarget target = runtime.createCallTarget(rootNode); + Iterator iterator = parent.getChildren().iterator(); + for (int i = 0; i < children.length; i++) { + Assert.assertEquals(children[i], iterator.next()); + } + Assert.assertFalse(iterator.hasNext()); + Object result = target.call(); + Assert.assertEquals(105, result); + + Assert.assertEquals(2 + children.length, NodeUtil.countNodes(rootNode)); + Assert.assertEquals(2 + children.length, NodeUtil.countNodes(NodeUtil.cloneNode(rootNode))); + } + + class TestRootNode extends RootNode { + + @Child private TestChildInterface child; + + public TestRootNode(TestChildInterface child) { + super(null); + this.child = child; + } + + @Override + public Object execute(VirtualFrame frame) { + return child.executeIntf(); + } + } + + interface TestChildInterface { + public int executeIntf(); + } + + class TestLeafNode extends Node implements TestChildInterface { + public TestLeafNode() { + super(null); + } + + public int executeIntf() { + return this.replace(new TestLeaf2Node()).executeIntf(); + } + } + + class TestLeaf2Node extends Node implements TestChildInterface { + public TestLeaf2Node() { + super(null); + } + + public int executeIntf() { + return 21; + } + } + + class TestChildNode extends Node implements TestChildInterface { + + @Child private TestChildInterface left; + @Child private TestChildInterface right; + + public TestChildNode(TestChildInterface left, TestChildInterface right) { + super(null); + this.left = left; + this.right = right; + } + + @Override + public int executeIntf() { + return left.executeIntf() + right.executeIntf(); + } + } + + class TestChildrenNode extends Node implements TestChildInterface { + + @Children private final TestChildInterface[] children; + + public TestChildrenNode(TestChildInterface[] children) { + super(null); + this.children = children; + } + + @Override + public int executeIntf() { + int sum = 0; + for (int i = 0; i < children.length; ++i) { + sum += children[i].executeIntf(); + } + return sum; + } + } +} diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Fri Oct 03 13:48:58 2014 +0200 @@ -185,7 +185,7 @@ public NodeClass(Class clazz, FieldOffsetProvider fieldOffsetProvider) { List fieldsList = new ArrayList<>(); - List parentOffsetsList = new ArrayList<>(); + long parentFieldOffset = -1; List childOffsetsList = new ArrayList<>(); List childrenOffsetsList = new ArrayList<>(); @@ -195,30 +195,53 @@ } NodeFieldKind kind; - if (Node.class.isAssignableFrom(field.getType()) && field.getName().equals("parent") && field.getDeclaringClass() == Node.class) { + if (field.getDeclaringClass() == Node.class && field.getName().equals("parent")) { + assert Node.class.isAssignableFrom(field.getType()); kind = NodeFieldKind.PARENT; - parentOffsetsList.add(fieldOffsetProvider.objectFieldOffset(field)); - } else if (Node.class.isAssignableFrom(field.getType()) && field.getAnnotation(Child.class) != null) { + parentFieldOffset = fieldOffsetProvider.objectFieldOffset(field); + } else if (field.getAnnotation(Child.class) != null) { + checkChildField(field); kind = NodeFieldKind.CHILD; childOffsetsList.add(fieldOffsetProvider.objectFieldOffset(field)); - assert !Modifier.isFinal(field.getModifiers()) : "child field must not be final (\"" + field.getName() + "\", " + clazz + ")"; - } else if (field.getType().isArray() && Node.class.isAssignableFrom(field.getType().getComponentType()) && field.getAnnotation(Children.class) != null) { + } else if (field.getAnnotation(Children.class) != null) { + checkChildrenField(field); kind = NodeFieldKind.CHILDREN; childrenOffsetsList.add(fieldOffsetProvider.objectFieldOffset(field)); - assert Modifier.isFinal(field.getModifiers()) : "children array field must be final (\"" + field.getName() + "\", " + clazz + ")"; } else { kind = NodeFieldKind.DATA; } fieldsList.add(new NodeField(kind, field.getType(), field.getName(), fieldOffsetProvider.objectFieldOffset(field))); } + + if (parentFieldOffset < 0) { + throw new AssertionError("parent field not found"); + } + this.fields = fieldsList.toArray(new NodeField[fieldsList.size()]); - assert parentOffsetsList.size() == 1 : "must have exactly one parent field"; - this.parentOffset = parentOffsetsList.get(0); + this.parentOffset = parentFieldOffset; this.childOffsets = toLongArray(childOffsetsList); this.childrenOffsets = toLongArray(childrenOffsetsList); this.clazz = clazz; } + private static void checkChildField(Field field) { + if (!(Node.class.isAssignableFrom(field.getType()) || field.getType().isInterface())) { + throw new AssertionError("@Child field type must be a subclass of Node or an interface (" + field + ")"); + } + if (Modifier.isFinal(field.getModifiers())) { + throw new AssertionError("@Child field must not be final (" + field + ")"); + } + } + + private static void checkChildrenField(Field field) { + if (!(field.getType().isArray() && (Node.class.isAssignableFrom(field.getType().getComponentType()) || field.getType().getComponentType().isInterface()))) { + throw new AssertionError("@Children field type must be an array of a subclass of Node or an interface (" + field + ")"); + } + if (!Modifier.isFinal(field.getModifiers())) { + throw new AssertionError("@Children field must be final (" + field + ")"); + } + } + public NodeField[] getFields() { return fields; } @@ -269,7 +292,7 @@ private int childrenCount() { int nodeCount = childOffsets.length; for (long fieldOffset : childrenOffsets) { - Node[] children = ((Node[]) unsafe.getObject(node, fieldOffset)); + Object[] children = ((Object[]) unsafe.getObject(node, fieldOffset)); if (children != null) { nodeCount += children.length; } @@ -283,9 +306,9 @@ return (Node) unsafe.getObject(node, childOffsets[idx]); } else { for (long fieldOffset : childrenOffsets) { - Node[] nodeArray = (Node[]) unsafe.getObject(node, fieldOffset); + Object[] nodeArray = (Object[]) unsafe.getObject(node, fieldOffset); if (idx < nodeCount + nodeArray.length) { - return nodeArray[idx - nodeCount]; + return (Node) nodeArray[idx - nodeCount]; } nodeCount += nodeArray.length; } @@ -361,12 +384,12 @@ } } for (long fieldOffset : nodeClass.childrenOffsets) { - Node[] children = (Node[]) unsafe.getObject(orig, fieldOffset); + Object[] children = (Object[]) unsafe.getObject(orig, fieldOffset); if (children != null) { - Node[] clonedChildren = (Node[]) Array.newInstance(children.getClass().getComponentType(), children.length); + Object[] clonedChildren = (Object[]) Array.newInstance(children.getClass().getComponentType(), children.length); for (int i = 0; i < children.length; i++) { if (children[i] != null) { - Node clonedChild = cloneNode(children[i]); + Node clonedChild = cloneNode((Node) children[i]); clonedChildren[i] = clonedChild; unsafe.putObject(clonedChild, nodeClass.parentOffset, clone); } @@ -388,11 +411,11 @@ } } for (long fieldOffset : nodeClass.childrenOffsets) { - Node[] children = (Node[]) unsafe.getObject(node, fieldOffset); + Object[] children = (Object[]) unsafe.getObject(node, fieldOffset); if (children != null) { - for (Node child : children) { + for (Object child : children) { if (child != null) { - nodes.add(child); + nodes.add((Node) child); } } } @@ -415,8 +438,7 @@ for (long fieldOffset : nodeClass.getChildrenOffsets()) { Object arrayObject = unsafe.getObject(parent, fieldOffset); if (arrayObject != null) { - assert arrayObject instanceof Node[] : "Children array must be instanceof Node[] "; - Node[] array = (Node[]) arrayObject; + Object[] array = (Object[]) arrayObject; for (int i = 0; i < array.length; i++) { if (array[i] == oldChild) { assert assertAssignable(nodeClass, fieldOffset, newChild); @@ -655,25 +677,7 @@ if (parent == null) { p.println(nodeName(node)); } else { - String fieldName = "unknownField"; - NodeField[] fields = NodeClass.get(parent.getClass()).fields; - for (NodeField field : fields) { - Object value = field.loadValue(parent); - if (value == node) { - fieldName = field.getName(); - break; - } else if (value instanceof Node[]) { - int index = 0; - for (Node arrayNode : (Node[]) value) { - if (arrayNode == node) { - fieldName = field.getName() + "[" + index + "]"; - break; - } - index++; - } - } - } - p.print(fieldName); + p.print(getNodeFieldName(parent, node, "unknownField")); p.print(" = "); p.println(nodeName(node)); } @@ -713,25 +717,7 @@ } if (parent != null) { - String childName = ""; - NodeField[] fields = NodeClass.get(parent.getClass()).fields; - for (NodeField field : fields) { - Object value = field.loadValue(parent); - if (value == node) { - childName = field.getName(); - break; - } else if (value instanceof Node[]) { - int index = 0; - for (Node arrayNode : (Node[]) value) { - if (arrayNode == node) { - childName = field.getName() + "[" + index + "]"; - break; - } - index++; - } - } - } - sb.append(childName); + sb.append(getNodeFieldName(parent, node, "")); } sb.append(" (" + node.getClass().getSimpleName() + ") "); @@ -744,6 +730,25 @@ p.flush(); } + private static String getNodeFieldName(Node parent, Node node, String defaultName) { + NodeField[] fields = NodeClass.get(parent.getClass()).fields; + for (NodeField field : fields) { + Object value = field.loadValue(parent); + if (field.getKind() == NodeFieldKind.CHILD && value == node) { + return field.getName(); + } else if (field.getKind() == NodeFieldKind.CHILDREN) { + int index = 0; + for (Object arrayNode : (Object[]) value) { + if (arrayNode == node) { + return field.getName() + "[" + index + "]"; + } + index++; + } + } + } + return defaultName; + } + /** * Prints a human readable form of a {@link Node} AST to the given {@link PrintStream}. This * print method does not check for cycles in the node structure. @@ -815,13 +820,13 @@ private static void printChildren(PrintWriter p, int level, Object value) { String sep; - Node[] children = (Node[]) value; + Object[] children = (Object[]) value; p.print(" = ["); sep = ""; - for (Node child : children) { + for (Object child : children) { p.print(sep); sep = ", "; - printTree(p, child, level + 1); + printTree(p, (Node) child, level + 1); } p.print("]"); } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeCodeGenerator.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeCodeGenerator.java Fri Oct 03 13:48:58 2014 +0200 @@ -129,13 +129,13 @@ return valueName(parameter) + "Cast"; } - private void addInternalValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame, boolean evaluated) { - if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) { + private void addInternalValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame, boolean disableFrame, boolean evaluated) { + if (forceFrame && !disableFrame && specialization.getSpecification().findParameterSpec("frame") != null) { method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue")); } for (Parameter parameter : specialization.getParameters()) { ParameterSpec spec = parameter.getSpecification(); - if (forceFrame && spec.getName().equals("frame")) { + if ((disableFrame || forceFrame) && spec.getName().equals("frame")) { continue; } if (spec.isLocal()) { @@ -152,13 +152,13 @@ } private static void addInternalValueParameterNames(CodeTreeBuilder builder, TemplateMethod source, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame, - Map customNames) { - if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) { + boolean disableFrame, Map customNames) { + if (forceFrame && !disableFrame && specialization.getSpecification().findParameterSpec("frame") != null) { builder.string("frameValue"); } for (Parameter parameter : specialization.getParameters()) { ParameterSpec spec = parameter.getSpecification(); - if (forceFrame && spec.getName().equals("frame")) { + if ((disableFrame || forceFrame) && spec.getName().equals("frame")) { continue; } @@ -322,12 +322,12 @@ /** *
      * variant1 $condition != null
-     * 
+     *
      * $type $name = defaultValue($type);
      * if ($condition) {
      *     $name = $value;
      * }
-     * 
+     *
      * variant2 $condition != null
      * $type $name = $value;
      * 
@@ -1034,7 +1034,7 @@ private Element createInfoMessage(NodeData node) { CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, STATIC), getContext().getType(String.class), CREATE_INFO); method.addParameter(new CodeVariableElement(getContext().getType(String.class), "message")); - addInternalValueParameters(method, node.getGenericSpecialization(), false, false); + addInternalValueParameters(method, node.getGenericSpecialization(), false, false, false); CodeTreeBuilder builder = method.createBuilder(); @@ -1089,7 +1089,7 @@ private CodeExecutableElement createCachedExecute(NodeData node, SpecializationData polymorph) { CodeExecutableElement cachedExecute = new CodeExecutableElement(modifiers(PROTECTED, ABSTRACT), polymorph.getReturnType().getType(), EXECUTE_CHAINED); - addInternalValueParameters(cachedExecute, polymorph, true, false); + addInternalValueParameters(cachedExecute, polymorph, true, false, false); ExecutableTypeData sourceExecutableType = node.findExecutableType(polymorph.getReturnType().getTypeSystemType(), 0); boolean sourceThrowsUnexpected = sourceExecutableType != null && sourceExecutableType.hasUnexpectedValue(getContext()); @@ -1244,12 +1244,13 @@ NodeData node = getModel().getNode(); SpecializationData generic = node.getGenericSpecialization(); CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), generic.getReturnType().getType(), EXECUTE_UNINITIALIZED); - addInternalValueParameters(method, generic, true, false); + addInternalValueParameters(method, generic, true, false, false); CodeTreeBuilder builder = method.createBuilder(); + boolean needsFrame = node.isFrameUsedByAnyGuard(getContext()); CodeTreeBuilder createSpecializationCall = builder.create(); createSpecializationCall.startCall(SPECIALIZE); - addInternalValueParameterNames(createSpecializationCall, generic, generic, null, node.needsFrame(getContext()), null); + addInternalValueParameterNames(createSpecializationCall, generic, generic, null, needsFrame, !needsFrame, null); createSpecializationCall.end(); builder.declaration(baseClassName(node), "newNode", createSpecializationCall); @@ -1269,7 +1270,7 @@ builder.startReturn(); builder.startStaticCall(context.getTruffleTypes().getDslShare(), "rewriteUninitialized").string("this").string("newNode").end(); builder.string(".").startCall(EXECUTE_CHAINED); - addInternalValueParameterNames(builder, generic, generic, null, true, null); + addInternalValueParameterNames(builder, generic, generic, null, true, false, null); builder.end(); builder.end(); @@ -1283,7 +1284,7 @@ private CodeTree createInfoCall(CodeTreeBuilder parent, SpecializationData specialization, String reason) { CodeTreeBuilder builder = parent.create(); builder.startCall(CREATE_INFO).string(reason); - addInternalValueParameterNames(builder, specialization, specialization, null, false, null); + addInternalValueParameterNames(builder, specialization, specialization, null, false, false, null); builder.end(); return builder.getRoot(); } @@ -1293,16 +1294,17 @@ SpecializationData generic = node.getGenericSpecialization(); CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), generic.getReturnType().getType(), REWRITE); - addInternalValueParameters(method, generic, true, false); + addInternalValueParameters(method, generic, true, false, false); method.addParameter(new CodeVariableElement(getContext().getType(String.class), "reason")); + boolean needsFrame = node.isFrameUsedByAnyGuard(getContext()); CodeTreeBuilder builder = method.createBuilder(); builder.startStatement().startStaticCall(context.getTruffleTypes().getCompilerAsserts(), "neverPartOfCompilation").end().end(); String baseClassName = baseClassName(getModel().getNode()); CodeTreeBuilder createSpecializationCall = builder.create(); createSpecializationCall.startCall(SPECIALIZE); - addInternalValueParameterNames(createSpecializationCall, generic, generic, null, node.needsFrame(getContext()), null); + addInternalValueParameterNames(createSpecializationCall, generic, generic, null, needsFrame, !needsFrame, null); createSpecializationCall.end(); builder.declaration(baseClassName, "newNode", createSpecializationCall); @@ -1328,7 +1330,7 @@ builder.startReturn(); builder.startCall("returnNode", EXECUTE_CHAINED); - addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, null); + addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, false, null); builder.end(); builder.end(); @@ -1356,16 +1358,19 @@ private CodeExecutableElement createCreateSpecializationMethod(NodeData node, SpecializationGroup group) { CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), new GeneratedTypeMirror(ElementUtils.getPackageName(node.getTemplateType()), baseClassName(node)), SPECIALIZE); - if (!node.needsFrame(getContext())) { + + final boolean needsFrame = node.isFrameUsedByAnyGuard(getContext()); + + if (!needsFrame) { method.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getSlowPath())); } - addInternalValueParameters(method, node.getGenericSpecialization(), node.needsFrame(getContext()), false); + addInternalValueParameters(method, node.getGenericSpecialization(), needsFrame, !needsFrame, false); final CodeTreeBuilder builder = method.createBuilder(); builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), group, new CodeBlock() { public CodeTree create(CodeTreeBuilder b, SpecializationData current) { - return createCreateSpecializationMethodBody0(builder, current); + return createCreateSpecializationMethodBody0(builder, current, needsFrame); } }, null, false, true, false, true)); @@ -1374,7 +1379,7 @@ return method; } - protected CodeTree createCreateSpecializationMethodBody0(CodeTreeBuilder parent, SpecializationData current) { + protected CodeTree createCreateSpecializationMethodBody0(CodeTreeBuilder parent, SpecializationData current, boolean useDeoptimize) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); if (current.isGeneric()) { builder.startReturn().nullLiteral().end(); @@ -1386,7 +1391,7 @@ builder.startBlock(); } - if (current.getNode().getGenericSpecialization().isReachable()) { + if (current.getNode().getGenericSpecialization().isReachable() && useDeoptimize) { builder.tree(createDeoptimize(builder)); } builder.startReturn(); @@ -2226,7 +2231,7 @@ CodeTreeBuilder execute = new CodeTreeBuilder(builder); execute.startCall("next0", EXECUTE_CHAINED); - addInternalValueParameterNames(execute, specialization, polymorphic, param.getLocalName(), true, null); + addInternalValueParameterNames(execute, specialization, polymorphic, param.getLocalName(), true, false, null); execute.end(); TypeData sourceType = polymorphic.getReturnType().getTypeSystemType(); @@ -2342,7 +2347,7 @@ SpecializationData generic = node.getGenericSpecialization(); CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent); specializeCall.startCall(REWRITE); - addInternalValueParameterNames(specializeCall, generic, node.getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, null); + addInternalValueParameterNames(specializeCall, generic, node.getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, false, null); specializeCall.doubleQuote(reason); specializeCall.end().end(); @@ -2664,17 +2669,17 @@ if (specialization.isPolymorphic()) { builder.startReturn().startCall("this.next0", EXECUTE_CHAINED); - addInternalValueParameterNames(builder, polymorphic, polymorphic, null, true, null); + addInternalValueParameterNames(builder, polymorphic, polymorphic, null, true, false, null); builder.end().end(); } else if (specialization.isUninitialized()) { builder.tree(createDeoptimizeUninitialized(node, builder)); builder.startReturn().startCall("this", EXECUTE_UNINITIALIZED); - addInternalValueParameterNames(builder, polymorphic, polymorphic, null, true, null); + addInternalValueParameterNames(builder, polymorphic, polymorphic, null, true, false, null); builder.end().end(); } else { CodeTreeBuilder elseBuilder = new CodeTreeBuilder(builder); elseBuilder.startReturn().startCall("this.next0", EXECUTE_CHAINED); - addInternalValueParameterNames(elseBuilder, polymorphic, polymorphic, null, true, null); + addInternalValueParameterNames(elseBuilder, polymorphic, polymorphic, null, true, false, null); elseBuilder.end().end(); builder.tree(createExecuteTree(builder, polymorphic, SpecializationGroup.create(specialization), new CodeBlock() { @@ -2861,11 +2866,11 @@ CodeTreeBuilder returnBuilder = new CodeTreeBuilder(parent); if (specialization.isPolymorphic()) { returnBuilder.startCall("next0", EXECUTE_CHAINED); - addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, null); + addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, false, null); returnBuilder.end(); } else if (specialization.isUninitialized()) { returnBuilder.startCall(EXECUTE_UNINITIALIZED); - addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, null); + addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, false, null); returnBuilder.end(); } else if (specialization.getMethod() == null && !node.needsRewrites(context)) { emitEncounteredSynthetic(builder, specialization); diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeData.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeData.java Fri Oct 03 13:48:58 2014 +0200 @@ -99,12 +99,12 @@ return 0; } - public boolean needsFrame(ProcessorContext context) { + public boolean isFrameUsedByAnyGuard(ProcessorContext context) { for (SpecializationData specialization : specializations) { if (!specialization.isReachable()) { continue; } - if (specialization.hasFrame(context)) { + if (specialization.isFrameUsedByGuard(context)) { return true; } } diff -r 8a2a809110ba -r 5d4749f9c5f6 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/SpecializationData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/SpecializationData.java Fri Oct 03 11:07:44 2014 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/SpecializationData.java Fri Oct 03 13:48:58 2014 +0200 @@ -287,12 +287,19 @@ return String.format("%s [id = %s, method = %s, guards = %s, signature = %s]", getClass().getSimpleName(), getId(), getMethod(), getGuards(), getTypeSignature()); } - public boolean hasFrame(ProcessorContext context) { - for (Parameter param : getParameters()) { - if (ElementUtils.typeEquals(param.getType(), context.getTruffleTypes().getFrame())) { - return true; + public boolean isFrameUsedByGuard(ProcessorContext context) { + for (GuardExpression guard : getGuards()) { + if (guard.getResolvedGuard() == null) { + continue; + } + + for (Parameter param : guard.getResolvedGuard().getParameters()) { + if (ElementUtils.typeEquals(param.getType(), context.getTruffleTypes().getFrame())) { + return true; + } } } + return false; } diff -r 8a2a809110ba -r 5d4749f9c5f6 mx/mx_graal.py --- a/mx/mx_graal.py Fri Oct 03 11:07:44 2014 +0200 +++ b/mx/mx_graal.py Fri Oct 03 13:48:58 2014 +0200 @@ -529,7 +529,7 @@ graalRuntime_inline_hpp = join(genSrcDir, 'graalRuntime.inline.hpp') cp = os.pathsep.join([mx.distribution(d).path for d in dist.distDependencies] + [dist.path, p.output_dir()]) tmp = StringIO.StringIO() - mx.run_java(['-cp', mx._tspU2W(cp), mainClass], out=tmp.write) + mx.run_java(['-cp', mx._separatedCygpathU2W(cp), mainClass], out=tmp.write) # Compute SHA1 for currently generated graalRuntime.inline.hpp content # and all other generated sources in genSrcDir @@ -552,7 +552,7 @@ javaClass = join(_graal_home, 'GeneratedSourcesSha1.class') with open(javaSource, 'w') as fp: print >> fp, 'class GeneratedSourcesSha1 { private static final String value = "' + sha1 + '"; }' - subprocess.check_call([mx.java().javac, '-d', mx._tpU2W(_graal_home), mx._tpU2W(javaSource)], stderr=subprocess.PIPE, stdout=subprocess.PIPE) + subprocess.check_call([mx.java().javac, '-d', mx._cygpathU2W(_graal_home), mx._cygpathU2W(javaSource)], stderr=subprocess.PIPE, stdout=subprocess.PIPE) zf = zipfile.ZipFile(dist.path, 'a') with open(javaClass, 'rb') as fp: zf.writestr(os.path.basename(javaClass), fp.read()) @@ -611,14 +611,14 @@ winSDK = mx.get_env('WIN_SDK', 'C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\') - if not exists(mx._tpW2U(winSDK)): + if not exists(mx._cygpathW2U(winSDK)): mx.abort("Could not find Windows SDK : '" + winSDK + "' does not exist") - winSDKSetEnv = mx._tpW2U(join(winSDK, 'Bin', 'SetEnv.cmd')) + winSDKSetEnv = mx._cygpathW2U(join(winSDK, 'Bin', 'SetEnv.cmd')) if not exists(winSDKSetEnv): mx.abort("Invalid Windows SDK path (" + winSDK + ") : could not find Bin/SetEnv.cmd (you can use the WIN_SDK environment variable to specify an other path)") - wincmd = 'cmd.exe /E:ON /V:ON /K "' + mx._tpU2W(winSDKSetEnv) + '"' + wincmd = 'cmd.exe /E:ON /V:ON /K "' + mx._cygpathU2W(winSDKSetEnv) + '"' p = subprocess.Popen(wincmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout = p.stdout stdin = p.stdin @@ -796,13 +796,15 @@ if not mx.ask_yes_no("Warning: building while --installed-jdks is set (" + _installed_jdks + ") is not recommanded - are you sure you want to continue", 'n'): mx.abort(1) + isWindows = platform.system() == 'Windows' or "CYGWIN" in platform.system() for build in builds: if build == 'ide-build-target': build = os.environ.get('IDE_BUILD_TARGET', None) if build is None or len(build) == 0: continue - jdk = _jdk(build, create=True, installJars=vm != 'original' and not opts2.java) + installJars = vm != 'original' and (isWindows or not opts2.java) + jdk = _jdk(build, create=True, installJars=installJars) if vm == 'original': if build != 'product': @@ -846,15 +848,15 @@ mx.logv('[all files in src and make directories are older than ' + timestampFile[len(_graal_home) + 1:] + ' - skipping native build]') continue - if platform.system() == 'Windows' or "CYGWIN" in platform.system(): - t_compilelogfile = mx._tpU2W(os.path.join(_graal_home, "graalCompile.log")) + if isWindows: + t_compilelogfile = mx._cygpathU2W(os.path.join(_graal_home, "graalCompile.log")) mksHome = mx.get_env('MKS_HOME', 'C:\\cygwin\\bin') variant = {'client': 'compiler1', 'server': 'compiler2'}.get(vm, vm) project_config = variant + '_' + build - t_graal_home = mx._tpU2W(_graal_home) + t_graal_home = mx._cygpathU2W(_graal_home) _runInDebugShell('msbuild ' + t_graal_home + r'\build\vs-amd64\jvm.vcproj /p:Configuration=' + project_config + ' /target:clean', t_graal_home) - winCompileCmd = r'set HotSpotMksHome=' + mksHome + r'& set OUT_DIR=' + mx._tpU2W(jdk) + r'& set JAVA_HOME=' + mx._tpU2W(jdk) + r'& set path=%JAVA_HOME%\bin;%path%;%HotSpotMksHome%& cd /D "' + t_graal_home + r'\make\windows"& call create.bat ' + t_graal_home + winCompileCmd = r'set HotSpotMksHome=' + mksHome + r'& set OUT_DIR=' + mx._cygpathU2W(jdk) + r'& set JAVA_HOME=' + mx._cygpathU2W(jdk) + r'& set path=%JAVA_HOME%\bin;%path%;%HotSpotMksHome%& cd /D "' + t_graal_home + r'\make\windows"& call create.bat ' + t_graal_home print winCompileCmd winCompileSuccess = re.compile(r"^Writing \.vcxproj file:") if not _runInDebugShell(winCompileCmd, t_graal_home, t_compilelogfile, winCompileSuccess): @@ -901,6 +903,9 @@ setMakeVar('GRAAL_VERSION', version) setMakeVar('INCLUDE_GRAAL', 'true') setMakeVar('INSTALL', 'y', env=env) + if mx.get_os() == 'darwin' and platform.mac_ver()[0] != '': + # Force use of clang on MacOS + setMakeVar('USE_CLANG', 'true') if mx.get_os() == 'solaris': # If using sparcWorks, setup flags to avoid make complaining about CC version cCompilerVersion = subprocess.Popen('CC -V', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).stderr.readlines()[0] @@ -1175,7 +1180,7 @@ # replaying the VM execution in a native debugger (e.g., gdb). vm(prefixArgs + vmArgs + ['-cp', cp, 'com.oracle.graal.test.GraalJUnitCore'] + coreArgs + testclasses) else: - vm(prefixArgs + vmArgs + ['-cp', cp, 'com.oracle.graal.test.GraalJUnitCore'] + coreArgs + ['@' + testfile]) + vm(prefixArgs + vmArgs + ['-cp', cp, 'com.oracle.graal.test.GraalJUnitCore'] + coreArgs + ['@' + mx._cygpathU2W(testfile)]) try: _run_tests(args, harness, annotations, testfile, blacklist, whitelist, regex) @@ -1308,9 +1313,11 @@ log = open(join(_graal_home, logFile), 'wb') start = time.time() mx.log('BEGIN: ' + v + '-' + vmbuild + '\t(see: ' + logFile + ')') + verbose = ['-v'] if mx._opts.verbose else [] # Run as subprocess so that output can be directed to a file - subprocess.check_call([sys.executable, '-u', join('mxtool', 'mx.py'), '--vm', v, '--vmbuild', - vmbuild, 'build'], cwd=_graal_home, stdout=log, stderr=subprocess.STDOUT) + cmd = [sys.executable, '-u', join('mxtool', 'mx.py')] + verbose + ['--vm', v, '--vmbuild', vmbuild, 'build'] + mx.logv("executing command: " + str(cmd)) + subprocess.check_call(cmd, cwd=_graal_home, stdout=log, stderr=subprocess.STDOUT) duration = datetime.timedelta(seconds=time.time() - start) mx.log('END: ' + v + '-' + vmbuild + '\t[' + str(duration) + ']') else: @@ -1451,7 +1458,7 @@ _jacoco = 'off' t = Task('CleanAndBuildIdealGraphVisualizer') - buildxml = mx._tpU2W(join(_graal_home, 'src', 'share', 'tools', 'IdealGraphVisualizer', 'build.xml')) + buildxml = mx._cygpathU2W(join(_graal_home, 'src', 'share', 'tools', 'IdealGraphVisualizer', 'build.xml')) mx.run(['ant', '-f', buildxml, '-q', 'clean', 'build']) tasks.append(t.stop()) @@ -1850,7 +1857,7 @@ buildOutput.append(x) env = os.environ.copy() env['JAVA_HOME'] = _jdk(vmToCheck='server') - env['MAVEN_OPTS'] = '-server' + env['MAVEN_OPTS'] = '-server -XX:-UseGraalClassLoader' mx.log("Building benchmarks...") cmd = ['mvn'] if args.settings: @@ -1876,6 +1883,8 @@ mx.abort(1) vmArgs, benchmarksAndJsons = _extract_VM_args(args) + if '-XX:-UseGraalClassLoader' not in vmArgs: + vmArgs = ['-XX:-UseGraalClassLoader'] + vmArgs benchmarks = [b for b in benchmarksAndJsons if not b.startswith('{')] jmhArgJsons = [b for b in benchmarksAndJsons if b.startswith('{')] @@ -2245,13 +2254,13 @@ findbugsJar = join(findbugsLib, 'findbugs.jar') assert exists(findbugsJar) nonTestProjects = [p for p in mx.projects() if not p.name.endswith('.test') and not p.name.endswith('.jtt')] - outputDirs = map(mx._tpU2W, [p.output_dir() for p in nonTestProjects]) + outputDirs = map(mx._cygpathU2W, [p.output_dir() for p in nonTestProjects]) findbugsResults = join(_graal_home, 'findbugs.results') - cmd = ['-jar', mx._tpU2W(findbugsJar), '-textui', '-low', '-maxRank', '15'] + cmd = ['-jar', mx._cygpathU2W(findbugsJar), '-textui', '-low', '-maxRank', '15'] if sys.stdout.isatty(): cmd.append('-progress') - cmd = cmd + ['-auxclasspath', mx.classpath([d.name for d in _jdkDeployedDists] + [p.name for p in nonTestProjects]), '-output', mx._tpU2W(findbugsResults), '-exitcode'] + args + outputDirs + cmd = cmd + ['-auxclasspath', mx.classpath([d.name for d in _jdkDeployedDists] + [p.name for p in nonTestProjects]), '-output', mx._cygpathU2W(findbugsResults), '-exitcode'] + args + outputDirs exitcode = mx.run_java(cmd, nonZeroIsFatal=False) if exitcode != 0: with open(findbugsResults) as fp: diff -r 8a2a809110ba -r 5d4749f9c5f6 mxtool/mx.py --- a/mxtool/mx.py Fri Oct 03 11:07:44 2014 +0200 +++ b/mxtool/mx.py Fri Oct 03 13:48:58 2014 +0200 @@ -284,6 +284,13 @@ Add the transitive set of dependencies for this project, including libraries if 'includeLibs' is true, to the 'deps' list. """ + return self._all_deps_helper(deps, [], includeLibs, includeSelf, includeJreLibs, includeAnnotationProcessors) + + def _all_deps_helper(self, deps, dependants, includeLibs, includeSelf=True, includeJreLibs=False, includeAnnotationProcessors=False): + if self in dependants: + abort(str(self) + 'Project dependency cycle found:\n ' + + '\n |\n V\n '.join(map(str, dependants[dependants.index(self):])) + + '\n |\n V\n ' + self.name) childDeps = list(self.deps) if includeAnnotationProcessors and len(self.annotation_processors()) > 0: childDeps = self.annotation_processors() + childDeps @@ -292,8 +299,11 @@ for name in childDeps: assert name != self.name dep = dependency(name) - if not dep in deps and (dep.isProject or (dep.isLibrary() and includeLibs) or (dep.isJreLibrary() and includeJreLibs)): - dep.all_deps(deps, includeLibs=includeLibs, includeJreLibs=includeJreLibs, includeAnnotationProcessors=includeAnnotationProcessors) + if not dep in deps: + if dep.isProject(): + dep._all_deps_helper(deps, dependants + [self], includeLibs=includeLibs, includeJreLibs=includeJreLibs, includeAnnotationProcessors=includeAnnotationProcessors) + elif dep.isProject or (dep.isLibrary() and includeLibs) or (dep.isJreLibrary() and includeJreLibs): + dep.all_deps(deps, includeLibs=includeLibs, includeJreLibs=includeJreLibs, includeAnnotationProcessors=includeAnnotationProcessors) if not self in deps and includeSelf: deps.append(self) return deps @@ -1335,39 +1345,43 @@ else: abort('Unknown operating system ' + sys.platform) -def _tpU2W(p): +def _cygpathU2W(p): """ - Translate a path from unix-style to windows-style + Translate a path from unix-style to windows-style. + This method has no effects on other platforms than cygwin. """ if p is None or get_os() != "cygwin": return p return subprocess.check_output(['cygpath', '-w', p]).strip() -def _tpW2U(p): +def _cygpathW2U(p): """ - Translate a path from windows-style to unix-style + Translate a path from windows-style to unix-style. + This method has no effects on other platforms than cygwin. """ if p is None or get_os() != "cygwin": return p return subprocess.check_output(['cygpath', '-u', p]).strip() -def _tspU2W(p): +def _separatedCygpathU2W(p): """ - Translate a group of paths, seperated by a path seperator. + Translate a group of paths, separated by a path separator. unix-style to windows-style. + This method has no effects on other platforms than cygwin. """ if p is None or p == "" or get_os() != "cygwin": return p - return ';'.join(map(_tpU2W, p.split(os.pathsep))) - -def _tspW2U(p): + return ';'.join(map(_cygpathU2W, p.split(os.pathsep))) + +def _separatedCygpathW2U(p): """ - Translate a group of paths, seperated by a path seperator. + Translate a group of paths, separated by a path separator. windows-style to unix-style. + This method has no effects on other platforms than cygwin. """ if p is None or p == "" or get_os() != "cygwin": return p - return os.pathsep.join(map(_tpW2U, p.split(';'))) + return os.pathsep.join(map(_cygpathW2U, p.split(';'))) def get_arch(): machine = platform.uname()[4] @@ -1558,7 +1572,7 @@ if includeBootClasspath: result = os.pathsep.join([java().bootclasspath(), result]) - return _tspU2W(result) + return _separatedCygpathU2W(result) def classpath_walk(names=None, resolve=True, includeSelf=True, includeBootClasspath=False): """ @@ -2026,7 +2040,7 @@ return cmp(self.parts, other.parts) def _filter_non_existant_paths(paths): - return os.pathsep.join([path for path in _tspW2U(paths).split(os.pathsep) if exists(path)]) + return os.pathsep.join([path for path in _separatedCygpathW2U(paths).split(os.pathsep) if exists(path)]) """ A JavaConfig object encapsulates info on how Java commands are run. @@ -2091,8 +2105,8 @@ os.makedirs(outDir) javaSource = join(myDir, 'ClasspathDump.java') if not exists(join(outDir, 'ClasspathDump.class')): - subprocess.check_call([self.javac, '-d', _tpU2W(outDir), _tpU2W(javaSource)], stderr=subprocess.PIPE, stdout=subprocess.PIPE) - self._bootclasspath, self._extdirs, self._endorseddirs = [x if x != 'null' else None for x in subprocess.check_output([self.java, '-cp', _tspU2W(outDir), 'ClasspathDump'], stderr=subprocess.PIPE).split('|')] + subprocess.check_call([self.javac, '-d', _cygpathU2W(outDir), _cygpathU2W(javaSource)], stderr=subprocess.PIPE, stdout=subprocess.PIPE) + self._bootclasspath, self._extdirs, self._endorseddirs = [x if x != 'null' else None for x in subprocess.check_output([self.java, '-cp', _separatedCygpathU2W(outDir), 'ClasspathDump'], stderr=subprocess.PIPE).split('|')] if not self._bootclasspath or not self._extdirs or not self._endorseddirs: warn("Could not find all classpaths: boot='" + str(self._bootclasspath) + "' extdirs='" + str(self._extdirs) + "' endorseddirs='" + str(self._endorseddirs) + "'") self._bootclasspath = _filter_non_existant_paths(self._bootclasspath) @@ -2119,17 +2133,17 @@ def bootclasspath(self): if self._bootclasspath is None: self._init_classpaths() - return _tspU2W(self._bootclasspath) + return _separatedCygpathU2W(self._bootclasspath) def extdirs(self): if self._extdirs is None: self._init_classpaths() - return _tspU2W(self._extdirs) + return _separatedCygpathU2W(self._extdirs) def endorseddirs(self): if self._endorseddirs is None: self._init_classpaths() - return _tspU2W(self._endorseddirs) + return _separatedCygpathU2W(self._endorseddirs) def containsJar(self, jar): if self._bootclasspath is None: @@ -2275,11 +2289,11 @@ javaSource = join(myDir, 'URLConnectionDownload.java') javaClass = join(myDir, 'URLConnectionDownload.class') if not exists(javaClass) or getmtime(javaClass) < getmtime(javaSource): - subprocess.check_call([java().javac, '-d', _tpU2W(myDir), _tpU2W(javaSource)]) + subprocess.check_call([java().javac, '-d', _cygpathU2W(myDir), _cygpathU2W(javaSource)]) verbose = [] if sys.stderr.isatty(): verbose.append("-v") - if run([java().java, '-cp', _tpU2W(myDir), 'URLConnectionDownload', _tpU2W(path)] + verbose + urls, nonZeroIsFatal=False) == 0: + if run([java().java, '-cp', _cygpathU2W(myDir), 'URLConnectionDownload', _cygpathU2W(path)] + verbose + urls, nonZeroIsFatal=False) == 0: return abort('Could not download to ' + path + ' from any of the following URLs:\n\n ' + @@ -2334,7 +2348,7 @@ def execute(self): argfileName = join(self.proj.dir, 'javafilelist.txt') argfile = open(argfileName, 'wb') - argfile.write('\n'.join(map(_tpU2W, self.javafilelist))) + argfile.write('\n'.join(map(_cygpathU2W, self.javafilelist))) argfile.close() processorArgs = [] @@ -2344,13 +2358,13 @@ if exists(genDir): shutil.rmtree(genDir) os.mkdir(genDir) - processorArgs += ['-processorpath', _tspU2W(join(processorPath)), '-s', _tpU2W(genDir)] + processorArgs += ['-processorpath', _separatedCygpathU2W(join(processorPath)), '-s', _cygpathU2W(genDir)] else: processorArgs += ['-proc:none'] args = self.args jdk = self.jdk - outputDir = _tpU2W(self.outputDir) + outputDir = _cygpathU2W(self.outputDir) compliance = str(jdk.javaCompliance) cp = classpath(self.proj.name, includeSelf=True) toBeDeleted = [argfileName] @@ -2365,7 +2379,7 @@ if jdk.debug_port is not None: javacCmd += ['-J-Xdebug', '-J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(jdk.debug_port)] javacCmd += processorArgs - javacCmd += ['@' + _tpU2W(argfile.name)] + javacCmd += ['@' + _cygpathU2W(argfile.name)] if not args.warnAPI: javacCmd.append('-XDignore.symbol.file') @@ -2382,7 +2396,7 @@ else: self.logCompilation('JDT') - jdtVmArgs = ['-Xmx1g', '-jar', _tpU2W(self.jdtJar)] + jdtVmArgs = ['-Xmx1g', '-jar', _cygpathU2W(self.jdtJar)] jdtArgs = ['-' + compliance, '-cp', cp, '-g', '-enableJavadoc', @@ -2412,10 +2426,10 @@ with open(jdtPropertiesTmp, 'w') as fp: fp.write(content) toBeDeleted.append(jdtPropertiesTmp) - jdtArgs += ['-properties', jdtPropertiesTmp] + jdtArgs += ['-properties', _cygpathU2W(jdtPropertiesTmp)] else: - jdtArgs += ['-properties', jdtProperties] - jdtArgs.append('@' + _tpU2W(argfile.name)) + jdtArgs += ['-properties', _cygpathU2W(jdtProperties)] + jdtArgs.append('@' + _cygpathU2W(argfile.name)) run_java(jdtVmArgs + jdtArgs) diff -r 8a2a809110ba -r 5d4749f9c5f6 src/share/tools/ProjectCreator/WinGammaPlatformVC10.java --- a/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java Fri Oct 03 11:07:44 2014 +0200 +++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java Fri Oct 03 13:48:58 2014 +0200 @@ -352,8 +352,7 @@ // Set /On option addAttr(rv, "Optimization", opt); // Set /FR option. - addAttr(rv, "BrowseInformation", "true"); - addAttr(rv, "BrowseInformationFile", "$(IntDir)"); + addAttr(rv, "BrowseInformation", "false"); // Set /MD option. addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL"); // Set /Oy- option diff -r 8a2a809110ba -r 5d4749f9c5f6 src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Fri Oct 03 11:07:44 2014 +0200 +++ b/src/share/vm/graal/graalRuntime.cpp Fri Oct 03 13:48:58 2014 +0200 @@ -1015,7 +1015,7 @@ oop GraalRuntime::compute_graal_class_loader(TRAPS) { assert(UseGraalClassLoader, "must be"); TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/loader/Factory", CHECK_NULL); - KlassHandle klass = SystemDictionary::resolve_or_null(name, CHECK_NULL); + KlassHandle klass = SystemDictionary::resolve_or_fail(name, true, CHECK_NULL); TempNewSymbol getClassLoader = SymbolTable::new_symbol("newClassLoader", CHECK_NULL); JavaValue result(T_OBJECT);