Mercurial > hg > graal-compiler
changeset 20982:23d6b95bd687
Merge
author | Tom Rodriguez <tom.rodriguez@oracle.com> |
---|---|
date | Wed, 15 Apr 2015 11:03:04 -0700 |
parents | 92fc95e8667d (diff) 018c536858cc (current diff) |
children | b99da6d86cfe |
files | graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/TypeSystemNodeFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/TypeData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/ExecutableTypeMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/GenericParser.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLAbstractDispatchNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLDirectDispatchNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLGenericDispatchNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLUninitializedDispatchNode.java |
diffstat | 38 files changed, 1171 insertions(+), 1894 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java Wed Apr 15 11:03:04 2015 -0700 @@ -25,28 +25,29 @@ import com.oracle.graal.api.code.CodeUtil.RefMapFormatter; import com.oracle.graal.api.meta.*; -public interface ReferenceMap extends Cloneable { +public abstract class ReferenceMap implements Cloneable { - void setRegister(int idx, LIRKind kind); + public abstract void setRegister(int idx, LIRKind kind); - void clearRegister(int idx, LIRKind kind); + public abstract void clearRegister(int idx, LIRKind kind); - void setStackSlot(int offset, LIRKind kind); + public abstract void setStackSlot(int offset, LIRKind kind); - void clearStackSlot(int offset, LIRKind kind); + public abstract void clearStackSlot(int offset, LIRKind kind); - boolean hasRegisterRefMap(); + public abstract boolean hasRegisterRefMap(); - boolean hasFrameRefMap(); + public abstract boolean hasFrameRefMap(); - void appendRegisterMap(StringBuilder sb, RefMapFormatter formatterArg); + public abstract void appendRegisterMap(StringBuilder sb, RefMapFormatter formatterArg); - void appendFrameMap(StringBuilder sb, RefMapFormatter formatterArg); + public abstract void appendFrameMap(StringBuilder sb, RefMapFormatter formatterArg); - ReferenceMap clone(); + @Override + public abstract ReferenceMap clone(); /** * Updates this map with all references marked in {@code other}. */ - void updateUnion(ReferenceMap other); + public abstract void updateUnion(ReferenceMap other); }
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Wed Apr 15 11:03:04 2015 -0700 @@ -398,6 +398,22 @@ } } + public static void log(String format, int arg) { + log(DEFAULT_LOG_LEVEL, format, arg); + } + + /** + * Prints a message to the current debug scope's logging stream if logging is enabled. + * + * @param format a format string + * @param arg the argument referenced by the format specifiers in {@code format} + */ + public static void log(int logLevel, String format, int arg) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg); + } + } + public static void log(String format, Object arg1, Object arg2) { log(DEFAULT_LOG_LEVEL, format, arg1, arg2); } @@ -411,6 +427,45 @@ } } + public static void log(String format, int arg1, Object arg2) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + + /** + * @see #log(int, String, Object) + */ + public static void log(int logLevel, String format, int arg1, Object arg2) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg1, arg2); + } + } + + public static void log(String format, Object arg1, int arg2) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + + /** + * @see #log(int, String, Object) + */ + public static void log(int logLevel, String format, Object arg1, int arg2) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg1, arg2); + } + } + + public static void log(String format, int arg1, int arg2) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + + /** + * @see #log(int, String, Object) + */ + public static void log(int logLevel, String format, int arg1, int arg2) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg1, arg2); + } + } + public static void log(String format, Object arg1, Object arg2, Object arg3) { log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); } @@ -424,6 +479,19 @@ } } + public static void log(String format, int arg1, int arg2, int arg3) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); + } + + /** + * @see #log(int, String, Object) + */ + public static void log(int logLevel, String format, int arg1, int arg2, int arg3) { + if (ENABLED) { + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3); + } + } + public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4) { log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4); } @@ -695,6 +763,67 @@ return null; } + public static Indent logAndIndent(String format, int arg) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg); + } + + /** + * A convenience function which combines {@link #log(String, Object)} and {@link #indent()}. + * + * @param format a format string + * @param arg the argument referenced by the format specifiers in {@code format} + * @return an object that reverts to the current indentation level when + * {@linkplain Indent#close() closed} or null if debugging is disabled + */ + public static Indent logAndIndent(int logLevel, String format, int arg) { + if (ENABLED) { + return logvAndIndent(logLevel, format, arg); + } + return null; + } + + public static Indent logAndIndent(String format, int arg1, Object arg2) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, int arg1, Object arg2) { + if (ENABLED) { + return logvAndIndent(logLevel, format, arg1, arg2); + } + return null; + } + + public static Indent logAndIndent(String format, Object arg1, int arg2) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, Object arg1, int arg2) { + if (ENABLED) { + return logvAndIndent(logLevel, format, arg1, arg2); + } + return null; + } + + public static Indent logAndIndent(String format, int arg1, int arg2) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, int arg1, int arg2) { + if (ENABLED) { + return logvAndIndent(logLevel, format, arg1, arg2); + } + return null; + } + public static Indent logAndIndent(String format, Object arg1, Object arg2) { return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2); } @@ -723,6 +852,34 @@ return null; } + public static Indent logAndIndent(String format, int arg1, int arg2, int arg3) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, int arg1, int arg2, int arg3) { + if (ENABLED) { + return logvAndIndent(logLevel, format, arg1, arg2, arg3); + } + return null; + } + + public static Indent logAndIndent(String format, Object arg1, int arg2, int arg3) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, Object arg1, int arg2, int arg3) { + if (ENABLED) { + return logvAndIndent(logLevel, format, arg1, arg2, arg3); + } + return null; + } + public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3, Object arg4) { return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java Wed Apr 15 11:03:04 2015 -0700 @@ -30,12 +30,277 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; -public final class HotSpotReferenceMap implements ReferenceMap, Serializable { +public final class HotSpotReferenceMap extends ReferenceMap implements Serializable { + + static final int OOP64 = 0b1010; + static final int OOP32 = 0b01; + static final int NARROW_LOW = OOP32; + static final int NARROW_HIGH = OOP32 << 2; + static final int NARROW_BOTH = NARROW_LOW | NARROW_HIGH; + + private enum MapEntry { + NoReference(0), + WideOop(OOP64), + NarrowOopLowerHalf(NARROW_LOW), + NarrowOopUpperHalf(NARROW_HIGH), + TwoNarrowOops(NARROW_BOTH), + Illegal(-1); + + MapEntry(int pattern) { + this.pattern = pattern; + } + + final int pattern; + + /** + * Create enum values from OopMap. + * <p> + * These bits can have the following values (MSB first): + * + * <pre> + * 0000 - contains no references + * 1010 - contains a wide oop + * 0001 - contains a narrow oop in the lower half + * 0101 - contains a narrow oop in the upper half + * 0101 - contains two narrow oops + * </pre> + * + * @see HotSpotReferenceMap#registerRefMap + * @see HotSpotReferenceMap#frameRefMap + */ + static MapEntry getFromBits(int idx, HotSpotOopMap set) { + int n = set.get(idx); + switch (n) { + case 0: + return NoReference; + case OOP64: + return WideOop; + case NARROW_LOW: + return NarrowOopLowerHalf; + case NARROW_HIGH: + return NarrowOopUpperHalf; + case NARROW_BOTH: + return TwoNarrowOops; + default: + return Illegal; + } + } + + String toBitString() { + int bits = toBit(this); + if (bits == -1) { + return "---"; + } + return String.format("%3s", Integer.toBinaryString(bits)).replace(' ', '0'); + } + + static int toBit(MapEntry type) { + return type.pattern; + } + } + + /** + * A specialized bit set that represents both wide and narrow oops in an efficient manner. The + * map consists of 4 bit entries that represent 8 bytes of memory. + * + */ + class HotSpotOopMap implements Cloneable, Serializable { + + private static final long serialVersionUID = -4997600265320131213L; + + /** + * Each entry is 4 bits long and covers 8 bytes of memory. + */ + private static final int BITS_PER_ENTRY = 4; + private static final int BITS_PER_ELEMENT = 64; + + public HotSpotOopMap(int i) { + words = new long[(i * BITS_PER_ENTRY + BITS_PER_ELEMENT) / BITS_PER_ELEMENT]; + } + + public HotSpotOopMap(HotSpotOopMap other) { + words = other.words.clone(); + } + + private long[] words; + + private int get(int i) { + return getEntry(i); + } + + private boolean isEmpty() { + for (int i = 0; i < words.length; i++) { + if (words[i] != 0) { + return false; + } + } + return true; + } + + public void or(HotSpotOopMap src) { + if (words.length < src.words.length) { + long[] newWords = new long[src.words.length]; + System.arraycopy(src.words, 0, newWords, 0, src.words.length); + for (int i = 0; i < words.length; i++) { + newWords[i] |= words[i]; + } + words = newWords; + } else { + for (int i = 0; i < src.words.length; i++) { + words[i] |= src.words[i]; + } + } + } + + private void setOop(int regIdx) { + setEntry(regIdx, OOP64); + } + + public int size() { + return words.length * BITS_PER_ELEMENT / BITS_PER_ENTRY; + } + + @Override + public HotSpotOopMap clone() { + return new HotSpotOopMap(this); + } + + private void setNarrowOop(int offset, int index) { + setNarrowEntry(offset + index, OOP32); + } + + private void setEntry(int regIdx, int value) { + assert regIdx % 2 == 0 : "must be alinged"; + int bitIndex = (regIdx >> 1) * BITS_PER_ENTRY; + int wordIndex = bitIndex / BITS_PER_ELEMENT; + int shift = bitIndex - wordIndex * BITS_PER_ELEMENT; + if (wordIndex >= words.length) { + if (value == 0) { + // Nothing to do since bits are clear + return; + } + words = Arrays.copyOf(words, wordIndex + 1); + } + assert verifyUpdate(this, this); + long orig = words[wordIndex]; + words[wordIndex] = (orig & (~(0b1111L << shift))) | ((long) value << shift); + assert get(regIdx / 2) == value; + assert verifyUpdate(this, this); + } + + private void setNarrowEntry(int offset, int value) { + int regIdx = offset >> 1; + boolean low = offset % 2 == 0; + int bitIndex = regIdx * BITS_PER_ENTRY; + int wordIndex = bitIndex / BITS_PER_ELEMENT; + int shift = bitIndex - wordIndex * BITS_PER_ELEMENT; + if (wordIndex >= words.length) { + if (value == 0) { + // Nothing to do since bits are clear + return; + } + words = Arrays.copyOf(words, wordIndex + 1); + } + long originalValue = words[wordIndex]; + int current = ((int) (originalValue >> shift)) & 0b1111; + if (current == OOP64) { + current = 0; + } + long newValue; + if (value != 0) { + newValue = current | (low ? value : (value << 2)); + } else { + newValue = current & (low ? 0b1100 : 0b0011); + } + long masked = originalValue & (~(0b1111L << shift)); + words[wordIndex] = masked | (newValue << shift); + assert verifyUpdate(this, this); + } + + private int getEntry(int regIdx) { + int bitIndex = regIdx * BITS_PER_ENTRY; + int wordIndex = bitIndex / BITS_PER_ELEMENT; + int shift = bitIndex - wordIndex * BITS_PER_ELEMENT; + return ((int) (words[wordIndex] >>> shift)) & 0b1111; + } + + private void clearOop(int offset) { + setEntry(offset, 0); + } + + private void clearNarrowOop(int offset) { + setNarrowEntry(offset, 0); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + + if (other instanceof HotSpotOopMap) { + HotSpotOopMap otherMap = (HotSpotOopMap) other; + int limit = Math.min(words.length, otherMap.words.length); + for (int i = 0; i < limit; i++) { + if (words[i] != otherMap.words[i]) { + return false; + } + } + for (int i = limit; i < words.length; i++) { + if (words[i] != 0) { + return false; + } + } + for (int i = limit; i < otherMap.words.length; i++) { + if (otherMap.words[i] != 0) { + return false; + } + } + return true; + } + return false; + } + + @Override + public int hashCode() { + long h = 1234; + for (int i = words.length; --i >= 0;) { + h ^= words[i] * (i + 1); + } + return (int) ((h >> 32) ^ h); + } + + @Override + public String toString() { + int count = 0; + StringBuilder sb = new StringBuilder(); + sb.append("["); + for (int idx = 0; idx < size(); idx++) { + MapEntry dstType = MapEntry.getFromBits(idx, this); + if (dstType == MapEntry.NoReference) { + continue; + } + if (count > 0) { + sb.append(", "); + } + if (dstType == MapEntry.Illegal) { + int value = get(idx); + sb.append("0x"); + sb.append(Integer.toHexString(value)); + } else { + sb.append(idx); + sb.append(':'); + sb.append(dstType); + } + count++; + } + sb.append("]"); + return sb.toString(); + } + } private static final long serialVersionUID = -1052183095979496819L; - public static final int BITS_PER_WORD = 3; - /** * Contains 3 bits per scalar register, and n*3 bits per n-word vector register (e.g., on a * 64-bit system, a 256-bit vector register requires 12 reference map bits). @@ -50,7 +315,7 @@ * 111 - contains two narrow oops * </pre> */ - private final BitSet registerRefMap; + private final HotSpotOopMap registerRefMap; /** * Contains 3 bits per stack word. @@ -65,23 +330,23 @@ * 111 - contains two narrow oops * </pre> */ - private final BitSet frameRefMap; + private final HotSpotOopMap frameRefMap; private final TargetDescription target; public HotSpotReferenceMap(int registerCount, int frameSlotCount, TargetDescription target) { if (registerCount > 0) { - this.registerRefMap = new BitSet(registerCount * BITS_PER_WORD); + this.registerRefMap = new HotSpotOopMap(registerCount); } else { this.registerRefMap = null; } - this.frameRefMap = new BitSet(frameSlotCount * BITS_PER_WORD); + this.frameRefMap = new HotSpotOopMap(frameSlotCount); this.target = target; } private HotSpotReferenceMap(HotSpotReferenceMap other) { - this.registerRefMap = (BitSet) other.registerRefMap.clone(); - this.frameRefMap = (BitSet) other.frameRefMap.clone(); + this.registerRefMap = other.registerRefMap.clone(); + this.frameRefMap = other.frameRefMap.clone(); this.target = other.target; } @@ -92,32 +357,26 @@ // setters - private static void setOop(BitSet map, int startIdx, LIRKind kind) { + private static void setOop(HotSpotOopMap map, int startIdx, LIRKind kind) { int length = kind.getPlatformKind().getVectorLength(); - map.clear(BITS_PER_WORD * startIdx, BITS_PER_WORD * (startIdx + length)); - for (int i = 0, idx = BITS_PER_WORD * startIdx; i < length; i++, idx += BITS_PER_WORD) { + for (int i = 0, idx = startIdx; i < length; i++, idx += 1) { if (kind.isReference(i)) { - map.set(idx); + map.setOop(idx); + } + + } + } + + private static void setNarrowOop(HotSpotOopMap map, int offset, LIRKind kind) { + int length = kind.getPlatformKind().getVectorLength(); + for (int i = 0; i < length; i++) { + if (kind.isReference(i)) { + map.setNarrowOop(offset, i); } } } - private static void setNarrowOop(BitSet map, int idx, LIRKind kind) { - int length = kind.getPlatformKind().getVectorLength(); - int nextIdx = idx + (length + 1) / 2; - map.clear(BITS_PER_WORD * idx, BITS_PER_WORD * nextIdx); - for (int i = 0, regIdx = BITS_PER_WORD * idx; i < length; i += 2, regIdx += BITS_PER_WORD) { - if (kind.isReference(i)) { - map.set(regIdx); - map.set(regIdx + 1); - } - if ((i + 1) < length && kind.isReference(i + 1)) { - map.set(regIdx); - map.set(regIdx + 2); - } - } - } - + @Override public void setRegister(int idx, LIRKind kind) { if (kind.isDerivedReference()) { throw GraalInternalError.shouldNotReachHere("derived reference cannot be inserted in ReferenceMap"); @@ -126,15 +385,16 @@ PlatformKind platformKind = kind.getPlatformKind(); int bytesPerElement = target.getSizeInBytes(platformKind) / platformKind.getVectorLength(); - if (bytesPerElement == target.wordSize) { - setOop(registerRefMap, idx, kind); - } else if (bytesPerElement == target.wordSize / 2) { - setNarrowOop(registerRefMap, idx, kind); + if (bytesPerElement == 8) { + setOop(registerRefMap, idx * 2, kind); + } else if (bytesPerElement == 4) { + setNarrowOop(registerRefMap, idx * 2, kind); } else { assert kind.isValue() : "unsupported reference kind " + kind; } } + @Override public void setStackSlot(int offset, LIRKind kind) { if (kind.isDerivedReference()) { throw GraalInternalError.shouldNotReachHere("derived reference cannot be inserted in ReferenceMap"); @@ -144,109 +404,81 @@ int bytesPerElement = target.getSizeInBytes(platformKind) / platformKind.getVectorLength(); assert offset % bytesPerElement == 0 : "unaligned value in ReferenceMap"; - if (bytesPerElement == target.wordSize) { - setOop(frameRefMap, offset / target.wordSize, kind); - } else if (bytesPerElement == target.wordSize / 2) { - if (platformKind.getVectorLength() > 1) { - setNarrowOop(frameRefMap, offset / target.wordSize, kind); - } else { - // in this case, offset / target.wordSize may not divide evenly - // so setNarrowOop won't work correctly - int idx = offset / target.wordSize; - if (kind.isReference(0)) { - frameRefMap.set(BITS_PER_WORD * idx); - if (offset % target.wordSize == 0) { - frameRefMap.set(BITS_PER_WORD * idx + 1); - } else { - frameRefMap.set(BITS_PER_WORD * idx + 2); - } - } - } + int index = offset / 4; // Addressing is done in increments of 4 bytes + if (bytesPerElement == 8) { + setOop(frameRefMap, index, kind); + } else if (bytesPerElement == 4) { + setNarrowOop(frameRefMap, index, kind); } else { assert kind.isValue() : "unknown reference kind " + kind; } } - public BitSet getFrameMap() { - return frameRefMap == null ? null : (BitSet) frameRefMap.clone(); + public HotSpotOopMap getFrameMap() { + return frameRefMap == null ? null : (HotSpotOopMap) frameRefMap.clone(); } - public BitSet getRegisterMap() { - return registerRefMap == null ? null : (BitSet) registerRefMap.clone(); + public HotSpotOopMap getRegisterMap() { + return registerRefMap == null ? null : (HotSpotOopMap) registerRefMap.clone(); } // clear - private static void clearOop(BitSet map, int startIdx, LIRKind kind) { - int length = kind.getPlatformKind().getVectorLength(); - map.clear(BITS_PER_WORD * startIdx, BITS_PER_WORD * (startIdx + length)); + private static void clearOop(HotSpotOopMap map, int offset, PlatformKind platformKind) { + int length = platformKind.getVectorLength(); + for (int i = 0; i < length; i++) { + map.clearOop(offset + i * 2); + } } - private static void clearNarrowOop(BitSet map, int idx, LIRKind kind) { - int length = kind.getPlatformKind().getVectorLength(); - int nextIdx = idx + (length + 1) / 2; - map.clear(BITS_PER_WORD * idx, BITS_PER_WORD * nextIdx); + private static void clearNarrowOop(HotSpotOopMap map, int offset, PlatformKind platformKind) { + int length = platformKind.getVectorLength(); + for (int i = 0; i < length; i++) { + map.clearNarrowOop(offset + i); + } } + @Override public void clearRegister(int idx, LIRKind kind) { - PlatformKind platformKind = kind.getPlatformKind(); int bytesPerElement = target.getSizeInBytes(platformKind) / platformKind.getVectorLength(); - if (bytesPerElement == target.wordSize) { - clearOop(registerRefMap, idx, kind); - } else if (bytesPerElement == target.wordSize / 2) { - clearNarrowOop(registerRefMap, idx, kind); + if (bytesPerElement == 8) { + clearOop(registerRefMap, idx * 2, platformKind); + } else if (bytesPerElement == 4) { + clearNarrowOop(registerRefMap, idx * 2, platformKind); } else { assert kind.isValue() : "unsupported reference kind " + kind; } } + @Override public void clearStackSlot(int offset, LIRKind kind) { PlatformKind platformKind = kind.getPlatformKind(); int bytesPerElement = target.getSizeInBytes(platformKind) / platformKind.getVectorLength(); assert offset % bytesPerElement == 0 : "unaligned value in ReferenceMap"; - if (bytesPerElement == target.wordSize) { - clearOop(frameRefMap, offset / target.wordSize, kind); - } else if (bytesPerElement == target.wordSize / 2) { - if (platformKind.getVectorLength() > 1) { - clearNarrowOop(frameRefMap, offset / target.wordSize, kind); - } else { - // in this case, offset / target.wordSize may not divide evenly - // so setNarrowOop won't work correctly - int idx = offset / target.wordSize; - if (kind.isReference(0)) { - if (offset % target.wordSize == 0) { - frameRefMap.clear(BITS_PER_WORD * idx + 1); - if (!frameRefMap.get(BITS_PER_WORD * idx + 2)) { - // only reset the first bit if there is no other narrow oop - frameRefMap.clear(BITS_PER_WORD * idx); - } - } else { - frameRefMap.clear(BITS_PER_WORD * idx + 2); - if (!frameRefMap.get(BITS_PER_WORD * idx + 1)) { - // only reset the first bit if there is no other narrow oop - frameRefMap.clear(BITS_PER_WORD * idx); - } - } - } - } + int index = offset / 4; // Addressing is done in increments of 4 bytes + if (bytesPerElement == 8) { + clearOop(frameRefMap, index, platformKind); + } else if (bytesPerElement == 4) { + clearNarrowOop(frameRefMap, index, platformKind); } else { assert kind.isValue() : "unknown reference kind " + kind; } } + @Override public void updateUnion(ReferenceMap otherArg) { HotSpotReferenceMap other = (HotSpotReferenceMap) otherArg; if (registerRefMap != null) { assert other.registerRefMap != null; - updateUnionBitSetRaw(registerRefMap, other.registerRefMap); + updateUnionOopMapRaw(registerRefMap, other.registerRefMap); } else { - assert other.registerRefMap == null || other.registerRefMap.cardinality() == 0 : "Target register reference map is empty but the source is not: " + other.registerRefMap; + assert other.registerRefMap == null || other.registerRefMap.isEmpty() : "Target register reference map is empty but the source is not: " + other.registerRefMap; } - updateUnionBitSetRaw(frameRefMap, other.frameRefMap); + updateUnionOopMapRaw(frameRefMap, other.frameRefMap); } /** @@ -255,111 +487,69 @@ * @see HotSpotReferenceMap#registerRefMap * @see HotSpotReferenceMap#frameRefMap */ - private static void updateUnionBitSetRaw(BitSet dst, BitSet src) { - assert dst.size() == src.size(); - assert UpdateUnionVerifier.verifyUpate(dst, src); + private static void updateUnionOopMapRaw(HotSpotOopMap dst, HotSpotOopMap src) { + assert verifyUpdate(dst, src); dst.or(src); + assert verifyUpdate(dst, dst); } - private enum UpdateUnionVerifier { - NoReference, - WideOop, - NarrowOopLowerHalf, - NarrowOopUpperHalf, - TwoNarrowOops, - Illegal; + static MapEntry[] entries(HotSpotOopMap fixedMap) { + MapEntry[] result = new MapEntry[fixedMap.size()]; + for (int idx = 0; idx < fixedMap.size(); idx++) { + MapEntry dstType = MapEntry.getFromBits(idx, fixedMap); + result[idx] = dstType; + } + return result; + } - /** - * Create enum values from BitSet. - * <p> - * These bits can have the following values (LSB first): - * - * <pre> - * 000 - contains no references - * 100 - contains a wide oop - * 110 - contains a narrow oop in the lower half - * 101 - contains a narrow oop in the upper half - * 111 - contains two narrow oops - * </pre> - * - * @see HotSpotReferenceMap#registerRefMap - * @see HotSpotReferenceMap#frameRefMap - */ - static UpdateUnionVerifier getFromBits(int idx, BitSet set) { - int n = (set.get(idx) ? 1 : 0) << 0 | (set.get(idx + 1) ? 1 : 0) << 1 | (set.get(idx + 2) ? 1 : 0) << 2; - switch (n) { - case 0: - return NoReference; - case 1: - return WideOop; - case 3: - return NarrowOopLowerHalf; - case 5: - return NarrowOopUpperHalf; - case 7: - return TwoNarrowOops; - default: - return Illegal; + private static boolean verifyUpdate(HotSpotOopMap dst, HotSpotOopMap src) { + return verifyUpdate(dst, src, true); + } + + private static boolean verifyUpdate(HotSpotOopMap dst, HotSpotOopMap src, boolean doAssert) { + for (int idx = 0; idx < Math.min(src.size(), dst.size()); idx++) { + if (!verifyUpdateEntry(idx, dst, src, doAssert)) { + return false; } } - - String toBitString() { - int bits = toBit(this); - if (bits == -1) { - return "---"; - } - return String.format("%3s", Integer.toBinaryString(bits)).replace(' ', '0'); - } + return true; + } - static int toBit(UpdateUnionVerifier type) { - switch (type) { - case NoReference: - return 0; - case WideOop: - return 1; - case NarrowOopLowerHalf: - return 3; - case NarrowOopUpperHalf: - return 5; - case TwoNarrowOops: - return 7; - default: - return -1; - } - } + private static boolean verifyUpdateEntry(int idx, HotSpotOopMap dst, HotSpotOopMap src, boolean doAssert) { + MapEntry dstType = MapEntry.getFromBits(idx, dst); + MapEntry srcType = MapEntry.getFromBits(idx, src); - private static boolean verifyUpate(BitSet dst, BitSet src) { - for (int idx = 0; idx < dst.size(); idx += BITS_PER_WORD) { - if (!verifyUpdateEntry(idx, dst, src)) { - return false; - } - } - return true; + if (dstType == MapEntry.Illegal || srcType == MapEntry.Illegal) { + assert !doAssert : String.format("Illegal RefMap bit pattern: %s (0b%s), %s (0b%s)", dstType, dstType.toBitString(), srcType, srcType.toBitString()); + return false; } - - private static boolean verifyUpdateEntry(int idx, BitSet dst, BitSet src) { - UpdateUnionVerifier dstType = UpdateUnionVerifier.getFromBits(idx, dst); - UpdateUnionVerifier srcType = UpdateUnionVerifier.getFromBits(idx, src); - - if (dstType == UpdateUnionVerifier.Illegal || srcType == UpdateUnionVerifier.Illegal) { - assert false : String.format("Illegal RefMap bit pattern: %s (0b%s), %s (0b%s)", dstType, dstType.toBitString(), srcType, srcType.toBitString()); + switch (dstType) { + case NoReference: + return true; + case WideOop: + switch (srcType) { + case NoReference: + case WideOop: + return true; + default: + assert false : String.format("Illegal RefMap combination: %s (0b%s), %s (0b%s)", dstType, dstType.toBitString(), srcType, srcType.toBitString()); + return false; + } + case TwoNarrowOops: + case NarrowOopLowerHalf: + case NarrowOopUpperHalf: + switch (srcType) { + case TwoNarrowOops: + case NarrowOopLowerHalf: + case NarrowOopUpperHalf: + case NoReference: + return true; + default: + assert false : String.format("Illegal RefMap combination: %s (0b%s), %s (0b%s)", dstType, dstType.toBitString(), srcType, srcType.toBitString()); + return false; + } + default: return false; - } - switch (dstType) { - case NoReference: - return true; - case WideOop: - switch (srcType) { - case NoReference: - case WideOop: - return true; - default: - assert false : String.format("Illegal RefMap combination: %s (0b%s), %s (0b%s)", dstType, dstType.toBitString(), srcType, srcType.toBitString()); - return false; - } - default: - return true; - } } } @@ -382,23 +572,50 @@ return false; } + @Override public boolean hasRegisterRefMap() { return registerRefMap != null && registerRefMap.size() > 0; } + @Override public boolean hasFrameRefMap() { return frameRefMap != null && frameRefMap.size() > 0; } + @Override public void appendRegisterMap(StringBuilder sb, RefMapFormatter formatter) { - for (int reg = registerRefMap.nextSetBit(0); reg >= 0; reg = registerRefMap.nextSetBit(reg + BITS_PER_WORD)) { - sb.append(' ').append(formatter.formatRegister(reg / BITS_PER_WORD)); + for (int idx = 0; idx < registerRefMap.size(); idx++) { + MapEntry dstType = MapEntry.getFromBits(idx, registerRefMap); + if (dstType != MapEntry.NoReference) { + sb.append(' ').append(formatter.formatRegister(idx)).append(':').append(dstType); + } } } + @Override public void appendFrameMap(StringBuilder sb, RefMapFormatter formatter) { - for (int slot = frameRefMap.nextSetBit(0); slot >= 0; slot = frameRefMap.nextSetBit(slot + BITS_PER_WORD)) { - sb.append(' ').append(formatter.formatStackSlot(slot / BITS_PER_WORD)); + for (int idx = 0; idx < frameRefMap.size(); idx++) { + MapEntry dstType = MapEntry.getFromBits(idx, frameRefMap); + if (dstType != MapEntry.NoReference) { + sb.append(' ').append(formatter.formatStackSlot(idx)).append(':').append(dstType); + } } } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + if (registerRefMap != null) { + sb.append("Registers = "); + sb.append(registerRefMap); + } + sb.append("Stack = "); + sb.append(frameRefMap); + return sb.toString(); + } + + public void verify() { + assert verifyUpdate(frameRefMap, frameRefMap); + assert registerRefMap == null || verifyUpdate(registerRefMap, registerRefMap); + } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTargetDescription.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTargetDescription.java Wed Apr 15 11:03:04 2015 -0700 @@ -23,7 +23,6 @@ package com.oracle.graal.hotspot; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; public class HotSpotTargetDescription extends TargetDescription { @@ -32,11 +31,6 @@ } @Override - public int getSizeInBytes(PlatformKind kind) { - return super.getSizeInBytes(kind); - } - - @Override public ReferenceMap createReferenceMap(boolean hasRegisters, int stackSlotCount) { return new HotSpotReferenceMap(hasRegisters ? arch.getRegisterReferenceMapSize() : 0, stackSlotCount, this); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java Wed Apr 15 11:03:04 2015 -0700 @@ -26,7 +26,6 @@ import java.util.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.lir.*; /** * Represents a constant non-{@code null} object reference, within the compiler and across the @@ -84,14 +83,6 @@ JavaConstant getCallSiteTarget(Assumptions assumptions); /** - * Gets the result of {@link CompositeValueClass#create(Class)} for the {@link Class} object - * represented by this constant. - * - * @return {@code null} if this constant does not represent a {@link Class} object - */ - JavaConstant getCompositeValueClass(); - - /** * Determines if this constant represents an {@linkplain String#intern() interned} string. */ boolean isInternedString();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java Wed Apr 15 11:03:04 2015 -0700 @@ -28,9 +28,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.lir.*; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import edu.umd.cs.findbugs.annotations.*; /** * Represents a constant non-{@code null} object reference, within the compiler and across the @@ -184,16 +183,6 @@ return null; } - @SuppressWarnings("unchecked") - public JavaConstant getCompositeValueClass() { - if (object instanceof Class) { - Class<? extends CompositeValue> c = (Class<? extends CompositeValue>) object; - assert CompositeValue.class.isAssignableFrom(c) : c; - return HotSpotObjectConstantImpl.forObject(CompositeValueClass.create(c)); - } - return null; - } - @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "reference equality is what we want") public boolean isInternedString() { if (object instanceof String) {
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java Wed Apr 15 11:03:04 2015 -0700 @@ -25,16 +25,16 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import java.util.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.asm.amd64.AMD64Address.Scale; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.OperandFlag; +import com.oracle.graal.lir.LIRInstruction.*; public final class AMD64AddressValue extends CompositeValue { - public static final CompositeValueClass<AMD64AddressValue> TYPE = CompositeValueClass.create(AMD64AddressValue.class); - private static final long serialVersionUID = -4444600052487578694L; @Component({REG, OperandFlag.ILLEGAL}) protected AllocatableValue base; @@ -42,12 +42,14 @@ protected final Scale scale; protected final int displacement; + private static final EnumSet<OperandFlag> flags = EnumSet.of(OperandFlag.REG, OperandFlag.ILLEGAL); + public AMD64AddressValue(LIRKind kind, AllocatableValue base, int displacement) { this(kind, base, Value.ILLEGAL, Scale.Times1, displacement); } public AMD64AddressValue(LIRKind kind, AllocatableValue base, AllocatableValue index, Scale scale, int displacement) { - super(TYPE, kind); + super(kind); this.base = base; this.index = index; this.scale = scale; @@ -56,6 +58,22 @@ assert scale != null; } + @Override + public CompositeValue forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc) { + AllocatableValue newBase = (AllocatableValue) proc.doValue(inst, base, mode, flags); + AllocatableValue newIndex = (AllocatableValue) proc.doValue(inst, index, mode, flags); + if (!base.identityEquals(newBase) || !index.identityEquals(newIndex)) { + return new AMD64AddressValue(getLIRKind(), newBase, newIndex, scale, displacement); + } + return this; + } + + @Override + protected void forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueConsumer proc) { + proc.visitValue(inst, base, mode, flags); + proc.visitValue(inst, index, mode, flags); + } + private static Register toRegister(AllocatableValue value) { if (value.equals(Value.ILLEGAL)) { return Register.None;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java Wed Apr 15 11:03:04 2015 -0700 @@ -25,33 +25,52 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import java.util.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.LIRInstruction.OperandFlag; +import com.oracle.graal.lir.LIRInstruction.OperandMode; public final class SPARCAddressValue extends CompositeValue { - public static final CompositeValueClass<SPARCAddressValue> TYPE = CompositeValueClass.create(SPARCAddressValue.class); - private static final long serialVersionUID = -3583286416638228207L; @Component({REG, OperandFlag.ILLEGAL}) protected AllocatableValue base; @Component({REG, OperandFlag.ILLEGAL}) protected AllocatableValue index; protected final int displacement; + private static final EnumSet<OperandFlag> flags = EnumSet.of(OperandFlag.REG, OperandFlag.ILLEGAL); + public SPARCAddressValue(LIRKind kind, AllocatableValue base, int displacement) { this(kind, base, Value.ILLEGAL, displacement); } public SPARCAddressValue(LIRKind kind, AllocatableValue base, AllocatableValue index, int displacement) { - super(TYPE, kind); + super(kind); assert isIllegal(index) || displacement == 0; this.base = base; this.index = index; this.displacement = displacement; } + @Override + public CompositeValue forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc) { + AllocatableValue newBase = (AllocatableValue) proc.doValue(inst, base, mode, flags); + AllocatableValue newIndex = (AllocatableValue) proc.doValue(inst, index, mode, flags); + if (!base.identityEquals(newBase) || !index.identityEquals(newIndex)) { + return new SPARCAddressValue(getLIRKind(), newBase, newIndex, displacement); + } + return this; + } + + @Override + protected void forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueConsumer proc) { + proc.visitValue(inst, base, mode, flags); + proc.visitValue(inst, index, mode, flags); + } + private static Register toRegister(AllocatableValue value) { if (isIllegal(value)) { return Register.None;
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest1.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest1.java Wed Apr 15 11:03:04 2015 -0700 @@ -25,11 +25,14 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static org.junit.Assert.*; +import java.util.*; + import org.junit.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.LIRInstruction.OperandFlag; +import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.asm.*; /** @@ -38,17 +41,31 @@ */ public class CompositeValueReplacementTest1 { - private static class NestedCompositeValue extends CompositeValue { - public static final CompositeValueClass<NestedCompositeValue> TYPE = CompositeValueClass.create(NestedCompositeValue.class); + private static class TestCompositeValue extends CompositeValue { private static final long serialVersionUID = -8804214200173503527L; @Component({REG, OperandFlag.ILLEGAL}) protected Value value; - public NestedCompositeValue(Value value) { - super(TYPE, LIRKind.Illegal); + public TestCompositeValue(Value value) { + super(LIRKind.Illegal); this.value = value; } + private static final EnumSet<OperandFlag> flags = EnumSet.of(OperandFlag.REG, OperandFlag.ILLEGAL); + + @Override + public CompositeValue forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc) { + Value newValue = proc.doValue(inst, value, mode, flags); + if (!value.identityEquals(newValue)) { + return new TestCompositeValue(newValue); + } + return this; + } + + @Override + protected void forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueConsumer proc) { + proc.visitValue(inst, value, mode, flags); + } } private static class DummyValue extends AbstractValue { @@ -98,9 +115,9 @@ private static final class TestOp extends LIRInstruction { public static final LIRInstructionClass<TestOp> TYPE = LIRInstructionClass.create(TestOp.class); - @Use({COMPOSITE}) protected NestedCompositeValue compValue; + @Use({COMPOSITE}) protected TestCompositeValue compValue; - public TestOp(NestedCompositeValue compValue) { + public TestOp(TestCompositeValue compValue) { super(TYPE); this.compValue = compValue; } @@ -112,43 +129,12 @@ } - private static NestedCompositeValue createNestedCompValue(Value value, int nestingLevel) { - NestedCompositeValue compValue = new NestedCompositeValue(value); - for (int i = 0; i < nestingLevel; i++) { - compValue = new NestedCompositeValue(compValue); - } - return compValue; - } - @Test public void replaceCompValueTest0() { DummyValue dummyValue1 = new DummyValue(); DummyValue dummyValue2 = new DummyValue(); DummyValue dummyValue3 = new DummyValue(); - NestedCompositeValue compValue1 = createNestedCompValue(dummyValue1, 0); - LIRInstruction op1 = new TestOp(compValue1); - LIRInstruction op2 = new TestOp(compValue1); - - op1.forEachInput((instruction, value, mode, flags) -> { - assertEquals(dummyValue1, value); - return dummyValue2; - }); - - op2.forEachInput((instruction, value, mode, flags) -> { - assertEquals(dummyValue1, value); - return dummyValue3; - }); - - op1.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue2, value)); - op2.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue3, value)); - } - - @Test - public void replaceCompValueTest1() { - DummyValue dummyValue1 = new DummyValue(); - DummyValue dummyValue2 = new DummyValue(); - DummyValue dummyValue3 = new DummyValue(); - NestedCompositeValue compValue1 = createNestedCompValue(dummyValue1, 1); + TestCompositeValue compValue1 = new TestCompositeValue(dummyValue1); LIRInstruction op1 = new TestOp(compValue1); LIRInstruction op2 = new TestOp(compValue1);
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest2.java Wed Apr 15 10:21:02 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.lir.test; - -import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.OperandFlag; -import com.oracle.graal.lir.asm.*; - -/** - * Same as {@link CompositeValueReplacementTest1} but with value arrays. - * - * @see CompositeValueReplacementTest1 - */ -public class CompositeValueReplacementTest2 { - - private static class NestedCompositeValue extends CompositeValue { - public static final CompositeValueClass<NestedCompositeValue> TYPE = CompositeValueClass.create(NestedCompositeValue.class); - - private static final long serialVersionUID = -8804214200173503527L; - @Component({REG, OperandFlag.ILLEGAL}) protected Value[] values; - - public NestedCompositeValue(Value value) { - super(TYPE, LIRKind.Illegal); - this.values = new Value[]{value}; - } - - } - - private static class DummyValue extends AbstractValue { - - private static final long serialVersionUID = -645435039553382737L; - private final int id; - private static int counter = 1; - - protected DummyValue() { - super(LIRKind.Illegal); - this.id = counter++; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + id; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - DummyValue other = (DummyValue) obj; - if (id != other.id) { - return false; - } - return true; - } - - @Override - public String toString() { - return "DummyValue [id=" + id + "]"; - } - - } - - private static final class TestOp extends LIRInstruction { - public static final LIRInstructionClass<TestOp> TYPE = LIRInstructionClass.create(TestOp.class); - - @Use({COMPOSITE}) protected NestedCompositeValue compValue; - - public TestOp(NestedCompositeValue compValue) { - super(TYPE); - this.compValue = compValue; - } - - @Override - public void emitCode(CompilationResultBuilder crb) { - fail("should not reach!"); - } - - } - - private static NestedCompositeValue createNestedCompValue(Value value, int nestingLevel) { - NestedCompositeValue compValue = new NestedCompositeValue(value); - for (int i = 0; i < nestingLevel; i++) { - compValue = new NestedCompositeValue(compValue); - } - return compValue; - } - - @Test - public void replaceCompValueTest0() { - DummyValue dummyValue1 = new DummyValue(); - DummyValue dummyValue2 = new DummyValue(); - DummyValue dummyValue3 = new DummyValue(); - NestedCompositeValue compValue1 = createNestedCompValue(dummyValue1, 0); - LIRInstruction op1 = new TestOp(compValue1); - LIRInstruction op2 = new TestOp(compValue1); - - op1.forEachInput((instruction, value, mode, flags) -> { - assertEquals(dummyValue1, value); - return dummyValue2; - }); - - op2.forEachInput((instruction, value, mode, flags) -> { - assertEquals(dummyValue1, value); - return dummyValue3; - }); - - op1.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue2, value)); - op2.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue3, value)); - } - - @Test - public void replaceCompValueTest1() { - DummyValue dummyValue1 = new DummyValue(); - DummyValue dummyValue2 = new DummyValue(); - DummyValue dummyValue3 = new DummyValue(); - NestedCompositeValue compValue1 = createNestedCompValue(dummyValue1, 1); - LIRInstruction op1 = new TestOp(compValue1); - LIRInstruction op2 = new TestOp(compValue1); - - op1.forEachInput((instruction, value, mode, flags) -> { - assertEquals(dummyValue1, value); - return dummyValue2; - }); - - op2.forEachInput((instruction, value, mode, flags) -> { - assertEquals(dummyValue1, value); - return dummyValue3; - }); - - op1.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue2, value)); - op2.visitEachInput((instruction, value, mode, flags) -> assertEquals(dummyValue3, value)); - } -}
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest3.java Wed Apr 15 10:21:02 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.lir.test; - -import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.OperandFlag; -import com.oracle.graal.lir.asm.*; - -/** - * Same as {@link CompositeValueReplacementTest1} but with for {@link ValuePosition}s. - * - * @see CompositeValueReplacementTest1 - */ -public class CompositeValueReplacementTest3 { - - private static class NestedCompositeValue extends CompositeValue { - public static final CompositeValueClass<NestedCompositeValue> TYPE = CompositeValueClass.create(NestedCompositeValue.class); - - private static final long serialVersionUID = -8804214200173503527L; - @Component({REG, OperandFlag.ILLEGAL}) protected Value value; - - public NestedCompositeValue(Value value) { - super(TYPE, LIRKind.Illegal); - this.value = value; - } - - } - - private static class DummyValue extends AbstractValue { - - private static final long serialVersionUID = -645435039553382737L; - private final int id; - private static int counter = 1; - - protected DummyValue() { - super(LIRKind.Illegal); - this.id = counter++; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + id; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - DummyValue other = (DummyValue) obj; - if (id != other.id) { - return false; - } - return true; - } - - @Override - public String toString() { - return "DummyValue [id=" + id + "]"; - } - - } - - private static final class TestOp extends LIRInstruction { - public static final LIRInstructionClass<TestOp> TYPE = LIRInstructionClass.create(TestOp.class); - - @Use({COMPOSITE}) protected NestedCompositeValue compValue; - - public TestOp(NestedCompositeValue compValue) { - super(TYPE); - this.compValue = compValue; - } - - @Override - public void emitCode(CompilationResultBuilder crb) { - fail("should not reach!"); - } - - } - - private static NestedCompositeValue createNestedCompValue(Value value, int nestingLevel) { - NestedCompositeValue compValue = new NestedCompositeValue(value); - for (int i = 0; i < nestingLevel; i++) { - compValue = new NestedCompositeValue(compValue); - } - return compValue; - } - - @Test - public void replaceCompValueTest0() { - DummyValue dummyValue1 = new DummyValue(); - DummyValue dummyValue2 = new DummyValue(); - DummyValue dummyValue3 = new DummyValue(); - NestedCompositeValue compValue1 = createNestedCompValue(dummyValue1, 0); - LIRInstruction op1 = new TestOp(compValue1); - LIRInstruction op2 = new TestOp(compValue1); - - op1.forEachInputPos((instruction, position) -> { - Value value = position.get(instruction); - assertEquals(dummyValue1, value); - position.set(instruction, dummyValue2); - }); - - op2.forEachInputPos((instruction, position) -> { - Value value = position.get(instruction); - assertEquals(dummyValue1, value); - position.set(instruction, dummyValue3); - }); - - op1.forEachInputPos((instruction, position) -> { - Value value = position.get(instruction); - assertEquals(dummyValue2, value); - }); - - op2.forEachInputPos((instruction, position) -> { - Value value = position.get(instruction); - assertEquals(dummyValue3, value); - }); - } - - @Test - public void replaceCompValueTest1() { - DummyValue dummyValue1 = new DummyValue(); - DummyValue dummyValue2 = new DummyValue(); - DummyValue dummyValue3 = new DummyValue(); - NestedCompositeValue compValue1 = createNestedCompValue(dummyValue1, 1); - LIRInstruction op1 = new TestOp(compValue1); - LIRInstruction op2 = new TestOp(compValue1); - - op1.forEachInputPos((instruction, position) -> { - Value value = position.get(instruction); - assertEquals(dummyValue1, value); - position.set(instruction, dummyValue2); - }); - - op2.forEachInputPos((instruction, position) -> { - Value value = position.get(instruction); - assertEquals(dummyValue1, value); - position.set(instruction, dummyValue3); - }); - - op1.forEachInputPos((instruction, position) -> { - Value value = position.get(instruction); - assertEquals(dummyValue2, value); - }); - - op2.forEachInputPos((instruction, position) -> { - Value value = position.get(instruction); - assertEquals(dummyValue3, value); - }); - } -}
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/CompositeValueReplacementTest4.java Wed Apr 15 10:21:02 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.lir.test; - -import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; -import static org.junit.Assert.*; - -import org.junit.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.OperandFlag; -import com.oracle.graal.lir.asm.*; - -/** - * Same as {@link CompositeValueReplacementTest2} but with value arrays {@link ValuePosition}s. - * - * @see CompositeValueReplacementTest2 - */ -public class CompositeValueReplacementTest4 { - - private static class NestedCompositeValue extends CompositeValue { - public static final CompositeValueClass<NestedCompositeValue> TYPE = CompositeValueClass.create(NestedCompositeValue.class); - - private static final long serialVersionUID = -8804214200173503527L; - @Component({REG, OperandFlag.ILLEGAL}) protected Value[] values; - - public NestedCompositeValue(Value value) { - super(TYPE, LIRKind.Illegal); - this.values = new Value[]{value}; - } - - } - - private static class DummyValue extends AbstractValue { - - private static final long serialVersionUID = -645435039553382737L; - private final int id; - private static int counter = 1; - - protected DummyValue() { - super(LIRKind.Illegal); - this.id = counter++; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + id; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - DummyValue other = (DummyValue) obj; - if (id != other.id) { - return false; - } - return true; - } - - @Override - public String toString() { - return "DummyValue [id=" + id + "]"; - } - - } - - private static class TestOp extends LIRInstruction { - public static final LIRInstructionClass<TestOp> TYPE = LIRInstructionClass.create(TestOp.class); - - @Use({COMPOSITE}) protected NestedCompositeValue compValue; - - public TestOp(NestedCompositeValue compValue) { - super(TYPE); - this.compValue = compValue; - } - - @Override - public void emitCode(CompilationResultBuilder crb) { - fail("should not reach!"); - } - - } - - private static NestedCompositeValue createNestedCompValue(Value value, int nestingLevel) { - NestedCompositeValue compValue = new NestedCompositeValue(value); - for (int i = 0; i < nestingLevel; i++) { - compValue = new NestedCompositeValue(compValue); - } - return compValue; - } - - @Test - public void replaceCompValueTest0() { - DummyValue dummyValue1 = new DummyValue(); - DummyValue dummyValue2 = new DummyValue(); - DummyValue dummyValue3 = new DummyValue(); - NestedCompositeValue compValue1 = createNestedCompValue(dummyValue1, 0); - LIRInstruction op1 = new TestOp(compValue1); - LIRInstruction op2 = new TestOp(compValue1); - - op1.forEachInputPos((instruction, position) -> { - Value value = position.get(instruction); - assertEquals(dummyValue1, value); - position.set(instruction, dummyValue2); - }); - - op2.forEachInputPos((instruction, position) -> { - Value value = position.get(instruction); - assertEquals(dummyValue1, value); - position.set(instruction, dummyValue3); - }); - - op1.forEachInputPos((instruction, position) -> { - Value value = position.get(instruction); - assertEquals(dummyValue2, value); - }); - - op2.forEachInputPos((instruction, position) -> { - Value value = position.get(instruction); - assertEquals(dummyValue3, value); - }); - } - - @Test - public void replaceCompValueTest1() { - DummyValue dummyValue1 = new DummyValue(); - DummyValue dummyValue2 = new DummyValue(); - DummyValue dummyValue3 = new DummyValue(); - NestedCompositeValue compValue1 = createNestedCompValue(dummyValue1, 1); - LIRInstruction op1 = new TestOp(compValue1); - LIRInstruction op2 = new TestOp(compValue1); - - op1.forEachInputPos((instruction, position) -> { - Value value = position.get(instruction); - assertEquals(dummyValue1, value); - position.set(instruction, dummyValue2); - }); - - op2.forEachInputPos((instruction, position) -> { - Value value = position.get(instruction); - assertEquals(dummyValue1, value); - position.set(instruction, dummyValue3); - }); - - op1.forEachInputPos((instruction, position) -> { - Value value = position.get(instruction); - assertEquals(dummyValue2, value); - }); - - op2.forEachInputPos((instruction, position) -> { - Value value = position.get(instruction); - assertEquals(dummyValue3, value); - }); - } -}
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest1.java Wed Apr 15 10:21:02 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.lir.test; - -import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; -import static org.junit.Assert.*; - -import java.util.*; - -import org.junit.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.OperandFlag; -import com.oracle.graal.lir.asm.*; - -public class ValuePositionTest1 { - - private static class NestedCompositeValue extends CompositeValue { - public static final CompositeValueClass<NestedCompositeValue> TYPE = CompositeValueClass.create(NestedCompositeValue.class); - - private static final long serialVersionUID = -8804214200173503527L; - @Component({REG, OperandFlag.ILLEGAL}) protected Value value; - - public NestedCompositeValue(Value value) { - super(TYPE, LIRKind.Illegal); - this.value = value; - } - - } - - private static class DummyValue extends AbstractValue { - - private static final long serialVersionUID = -645435039553382737L; - private final int id; - private static int counter = 1; - - protected DummyValue() { - super(LIRKind.Illegal); - this.id = counter++; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + id; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - DummyValue other = (DummyValue) obj; - if (id != other.id) { - return false; - } - return true; - } - } - - private static final class TestOp extends LIRInstruction { - public static final LIRInstructionClass<TestOp> TYPE = LIRInstructionClass.create(TestOp.class); - - @Use({COMPOSITE}) protected NestedCompositeValue compValue; - - public TestOp(NestedCompositeValue compValue) { - super(TYPE); - this.compValue = compValue; - } - - @Override - public void emitCode(CompilationResultBuilder crb) { - fail("should not reach!"); - } - - } - - private static LIRInstruction createNestedOp(Value value, int nestingLevel) { - NestedCompositeValue compValue = new NestedCompositeValue(value); - for (int i = 0; i < nestingLevel; i++) { - compValue = new NestedCompositeValue(compValue); - } - TestOp op = new TestOp(compValue); - return op; - } - - @Test - public void nestedTest0() { - DummyValue dummyValue = new DummyValue(); - LIRInstruction op = createNestedOp(dummyValue, 0); - - List<ValuePosition> positions = new ArrayList<>(); - - op.forEachInputPos((instruction, position) -> positions.add(position)); - - assertEquals(1, positions.size()); - assertEquals(dummyValue, positions.get(0).get(op)); - } - - @Test - public void nestedTest1() { - DummyValue dummyValue = new DummyValue(); - LIRInstruction op = createNestedOp(dummyValue, 1); - - List<ValuePosition> positions = new ArrayList<>(); - - op.forEachInputPos((instruction, position) -> positions.add(position)); - - assertEquals(1, positions.size()); - assertEquals(dummyValue, positions.get(0).get(op)); - } - - @Test - public void nestedTest2() { - DummyValue dummyValue = new DummyValue(); - LIRInstruction op = createNestedOp(dummyValue, 2); - - List<ValuePosition> positions = new ArrayList<>(); - - op.forEachInputPos((instruction, position) -> positions.add(position)); - - assertEquals(1, positions.size()); - assertEquals(dummyValue, positions.get(0).get(op)); - } - -}
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest2.java Wed Apr 15 10:21:02 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.lir.test; - -import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; -import static org.junit.Assert.*; - -import java.util.*; - -import org.junit.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.OperandFlag; -import com.oracle.graal.lir.asm.*; - -public class ValuePositionTest2 { - - private static class NestedCompositeValue extends CompositeValue { - public static final CompositeValueClass<NestedCompositeValue> TYPE = CompositeValueClass.create(NestedCompositeValue.class); - - private static final long serialVersionUID = -2243948303328857965L; - @Component({REG, OperandFlag.ILLEGAL}) protected Value value1; - @Component({REG, OperandFlag.ILLEGAL}) protected Value value2; - - public NestedCompositeValue(Value value1, Value value2) { - super(TYPE, LIRKind.Illegal); - this.value1 = value1; - this.value2 = value2; - } - - } - - private static class DummyValue extends AbstractValue { - - private static final long serialVersionUID = 3620305384660607012L; - private final int id; - private static int counter = 0; - - protected DummyValue() { - super(LIRKind.Illegal); - this.id = counter++; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + id; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - DummyValue other = (DummyValue) obj; - if (id != other.id) { - return false; - } - return true; - } - } - - private static class TestOp extends LIRInstruction { - public static final LIRInstructionClass<TestOp> TYPE = LIRInstructionClass.create(TestOp.class); - - @Use({COMPOSITE}) protected NestedCompositeValue compValue; - - public TestOp(NestedCompositeValue compValue) { - super(TYPE); - this.compValue = compValue; - } - - @Override - public void emitCode(CompilationResultBuilder crb) { - fail("should not reach!"); - } - - } - - @Test - public void testSetGet() { - DummyValue dummyValue0 = new DummyValue(); - DummyValue dummyValue1 = new DummyValue(); - DummyValue dummyValue2 = new DummyValue(); - DummyValue dummyValue3 = new DummyValue(); - - NestedCompositeValue compValue0 = new NestedCompositeValue(dummyValue0, dummyValue1); - NestedCompositeValue compValue1 = new NestedCompositeValue(compValue0, dummyValue2); - NestedCompositeValue compValue2 = new NestedCompositeValue(dummyValue3, compValue1); - - LIRInstruction op = new TestOp(compValue2); - List<ValuePosition> positions = new ArrayList<>(); - - op.forEachInputPos((instruction, position) -> positions.add(position)); - - assertEquals(4, positions.size()); - - // replace values - List<Value> replValues = new ArrayList<>(); - for (ValuePosition pos : positions) { - Value v = new DummyValue(); - replValues.add(v); - pos.set(op, v); - - } - - // check replaced values - Iterator<Value> it = replValues.iterator(); - for (ValuePosition pos : positions) { - Value v = pos.get(op); - assertEquals(it.next(), v); - } - assertFalse(it.hasNext()); - } - -}
--- a/graal/com.oracle.graal.lir.test/src/com/oracle/graal/lir/test/ValuePositionTest3.java Wed Apr 15 10:21:02 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.lir.test; - -import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; -import static org.junit.Assert.*; - -import java.util.*; - -import org.junit.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.OperandFlag; -import com.oracle.graal.lir.LIRInstruction.OperandMode; -import com.oracle.graal.lir.asm.*; - -public class ValuePositionTest3 { - - public static final class TestAddressValue extends CompositeValue { - public static final CompositeValueClass<TestAddressValue> TYPE = CompositeValueClass.create(TestAddressValue.class); - - private static final long serialVersionUID = -2679790860680123026L; - - @Component({REG, OperandFlag.ILLEGAL}) protected AllocatableValue base; - @Component({REG, OperandFlag.ILLEGAL}) protected AllocatableValue index; - - public TestAddressValue(LIRKind kind, AllocatableValue base) { - this(kind, base, Value.ILLEGAL); - } - - public TestAddressValue(LIRKind kind, AllocatableValue base, AllocatableValue index) { - super(TYPE, kind); - this.base = base; - this.index = index; - } - } - - private static class DummyValue extends AllocatableValue { - - private static final long serialVersionUID = 3620305384660607012L; - private final int id; - private static int counter = 0; - - protected DummyValue() { - super(LIRKind.Illegal); - this.id = counter++; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + id; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - DummyValue other = (DummyValue) obj; - if (id != other.id) { - return false; - } - return true; - } - - @Override - public String toString() { - return "DummyValue" + id; - } - - } - - private static class TestOp extends LIRInstruction { - public static final LIRInstructionClass<TestOp> TYPE = LIRInstructionClass.create(TestOp.class); - - @Use({COMPOSITE}) protected Value value; - - public TestOp(Value value) { - super(TYPE); - this.value = value; - } - - @Override - public void emitCode(CompilationResultBuilder crb) { - fail("should not reach!"); - } - - @Override - public String toString() { - return "TestOp [" + value + "]"; - } - - } - - @Test - public void test0() { - DummyValue dummyValue0 = new DummyValue(); - DummyValue dummyValue1 = new DummyValue(); - - TestAddressValue compValue0 = new TestAddressValue(LIRKind.Illegal, dummyValue0, dummyValue1); - - LIRInstruction op = new TestOp(compValue0); - - HashMap<Value, EnumSet<OperandFlag>> positionMap = new HashMap<>(); - HashMap<Value, EnumSet<OperandFlag>> normalMap = new HashMap<>(); - - op.forEachInputPos(new ValuePositionProcedure() { - - @Override - public void doValue(LIRInstruction instruction, ValuePosition position) { - positionMap.put(position.get(instruction), position.getFlags()); - } - }); - op.visitEachInput(new InstructionValueConsumer() { - - @Override - public void visitValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet<OperandFlag> flags) { - normalMap.put(value, flags); - } - }); - - assertEquals(normalMap.size(), positionMap.size()); - assertTrue(normalMap.keySet().containsAll(positionMap.keySet())); - normalMap.keySet().forEach(key -> { - EnumSet<OperandFlag> normal = normalMap.get(key); - EnumSet<OperandFlag> position = positionMap.get(key); - assertTrue(normal.containsAll(position)); - assertTrue(position.containsAll(normal)); - }); - } -}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java Wed Apr 15 11:03:04 2015 -0700 @@ -23,17 +23,19 @@ package com.oracle.graal.lir; import java.lang.annotation.*; +import java.util.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; /** - * Base class to represent values that need to be stored in more than one register. + * Base class to represent values that need to be stored in more than one register. This is mainly + * intended to support addresses and not general arbitrary nesting of composite values. Because of + * the possibility of sharing of CompositeValues they should be immutable. */ -public abstract class CompositeValue extends AbstractValue implements Cloneable { +public abstract class CompositeValue extends AbstractValue { private static final long serialVersionUID = -169180052684126180L; @@ -44,61 +46,69 @@ OperandFlag[] value() default OperandFlag.REG; } - private final CompositeValueClass<?> valueClass; - private static final DebugMetric COMPOSITE_VALUE_COUNT = Debug.metric("CompositeValues"); - public CompositeValue(CompositeValueClass<? extends CompositeValue> c, LIRKind kind) { + public CompositeValue(LIRKind kind) { super(kind); COMPOSITE_VALUE_COUNT.increment(); - valueClass = c; - assert c.getClazz() == this.getClass(); + assert CompositeValueClass.get(getClass()) != null; } - final CompositeValue forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc) { - return valueClass.forEachComponent(inst, this, mode, proc); + /** + * Invoke {@code proc} on each {@link Value} element of this {@link CompositeValue}. If + * {@code proc} replaces any value then a new CompositeValue should be returned. + * + * @param inst + * @param mode + * @param proc + * @return the original CompositeValue or a copy with any modified values + */ + public abstract CompositeValue forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc); + + /** + * A helper method to visit {@link Value}[] ensuring that a copy of the array is made if it's + * needed. + * + * @param inst + * @param values + * @param mode + * @param proc + * @param flags + * @return the original {@code values} array or a copy if values changed + */ + protected Value[] visitValueArray(LIRInstruction inst, Value[] values, OperandMode mode, InstructionValueProcedure proc, EnumSet<OperandFlag> flags) { + Value[] newValues = null; + for (int i = 0; i < values.length; i++) { + Value value = values[i]; + Value newValue = proc.doValue(inst, value, mode, flags); + if (!value.identityEquals(newValue)) { + if (newValues == null) { + newValues = values.clone(); + } + newValues[i] = value; + } + } + return newValues != null ? newValues : values; } - final void forEachComponent(LIRInstruction inst, OperandMode mode, ValuePositionProcedure proc, ValuePosition outerPosition) { - valueClass.forEachComponent(inst, this, mode, proc, outerPosition); - } + protected abstract void forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueConsumer proc); @Override public String toString() { - return valueClass.toString(this); + return CompositeValueClass.format(this); } @Override public int hashCode() { - return 53 * super.hashCode() + valueClass.hashCode(); + return 53 * super.hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof CompositeValue) { CompositeValue other = (CompositeValue) obj; - return super.equals(other) && valueClass.equals(other.valueClass); + return super.equals(other); } return false; } - - CompositeValueClass<?> getValueClass() { - return valueClass; - } - - @Override - public final CompositeValue clone() { - CompositeValue compositeValue = null; - try { - compositeValue = (CompositeValue) super.clone(); - } catch (CloneNotSupportedException e) { - throw new GraalInternalError(e); - } - - // copy value arrays - getValueClass().copyValueArrays(compositeValue); - - return compositeValue; - } - }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java Wed Apr 15 11:03:04 2015 -0700 @@ -25,11 +25,12 @@ import java.lang.reflect.*; import java.util.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.CompositeValue.Component; import com.oracle.graal.lir.LIRInstruction.OperandFlag; -import com.oracle.graal.lir.LIRInstruction.OperandMode; +import com.oracle.graal.lir.LIRIntrospection.LIRFieldsScanner; +import com.oracle.graal.lir.LIRIntrospection.OperandModeAnnotation; +import com.oracle.graal.lir.LIRIntrospection.Values; /** * Lazily associated metadata for every {@link CompositeValue} type. The metadata includes: @@ -38,20 +39,35 @@ * such fields.</li> * </ul> */ -public class CompositeValueClass<T> extends LIRIntrospection<T> { +public final class CompositeValueClass<T> { + + /** + * The CompositeValueClass is only used for formatting for the most part so cache it as a + * ClassValue. + */ + private static final ClassValue<CompositeValueClass<?>> compositeClass = new ClassValue<CompositeValueClass<?>>() { - public static final <T extends CompositeValue> CompositeValueClass<T> create(Class<T> c) { - return new CompositeValueClass<>(c); + @Override + protected CompositeValueClass<?> computeValue(Class<?> type) { + CompositeValueClass<?> compositeValueClass = new CompositeValueClass<>(type); + assert compositeValueClass.values.getDirectCount() == compositeValueClass.values.getCount() : "only direct fields are allowed in composites"; + return compositeValueClass; + } + + }; + + public static CompositeValueClass<?> get(Class<?> type) { + return compositeClass.get(type); } - public CompositeValueClass(Class<T> clazz) { - this(clazz, new FieldsScanner.DefaultCalcOffset()); - } + private final Class<?> clazz; + private final Values values; + private final Fields data; - public CompositeValueClass(Class<T> clazz, FieldsScanner.CalcOffset calcOffset) { - super(clazz); + private CompositeValueClass(Class<T> clazz) { + this.clazz = clazz; - CompositeValueFieldsScanner vfs = new CompositeValueFieldsScanner(calcOffset); + CompositeValueFieldsScanner vfs = new CompositeValueFieldsScanner(new FieldsScanner.DefaultCalcOffset()); vfs.scan(clazz, CompositeValue.class, false); values = new Values(vfs.valueAnnotations.get(CompositeValue.Component.class)); @@ -80,7 +96,7 @@ @Override public String toString() { StringBuilder str = new StringBuilder(); - str.append(getClass().getSimpleName()).append(" ").append(getClazz().getSimpleName()).append(" components["); + str.append(getClass().getSimpleName()).append(" ").append(clazz.getSimpleName()).append(" components["); values.appendFields(str); str.append("] data["); data.appendFields(str); @@ -88,31 +104,16 @@ return str.toString(); } - 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, values, mode, proc, outerPosition); - } - - public String toString(CompositeValue obj) { + public static String format(CompositeValue obj) { + CompositeValueClass<?> valueClass = compositeClass.get(obj.getClass()); StringBuilder result = new StringBuilder(); - appendValues(result, obj, "", "", "{", "}", new String[]{""}, values); + LIRIntrospection.appendValues(result, obj, "", "", "{", "}", new String[]{""}, valueClass.values); - for (int i = 0; i < data.getCount(); i++) { - result.append(" ").append(data.getName(i)).append(": ").append(getFieldString(obj, i, data)); + for (int i = 0; i < valueClass.data.getCount(); i++) { + result.append(" ").append(valueClass.data.getName(i)).append(": ").append(LIRIntrospection.getFieldString(obj, i, valueClass.data)); } return result.toString(); } - - void copyValueArrays(CompositeValue compositeValue) { - for (int i = values.getDirectCount(); i < values.getCount(); i++) { - Value[] valueArray = values.getValueArray(compositeValue, i); - Value[] newValueArray = Arrays.copyOf(valueArray, valueArray.length); - values.setValueArray(compositeValue, i, newValueArray); - } - } }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InstructionValueConsumer.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InstructionValueConsumer.java Wed Apr 15 11:03:04 2015 -0700 @@ -29,10 +29,11 @@ import com.oracle.graal.lir.LIRInstruction.OperandMode; /** - * Non-modifying version of {@link InstructionValueProcedure}. + * Functional interface for iterating over a list of values without modifying them. See + * {@link InstructionValueProcedure} for a version that can modify values. */ @FunctionalInterface -public interface InstructionValueConsumer extends InstructionValueProcedure { +public interface InstructionValueConsumer { /** * Iterator method to be overwritten. @@ -43,9 +44,4 @@ * @param flags A set of flags for the value. */ void visitValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet<OperandFlag> flags); - - default Value doValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet<OperandFlag> flags) { - visitValue(instruction, value, mode, flags); - return value; - } }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InstructionValueProcedure.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/InstructionValueProcedure.java Wed Apr 15 11:03:04 2015 -0700 @@ -29,7 +29,8 @@ import com.oracle.graal.lir.LIRInstruction.OperandMode; /** - * Functional interface for iterating over a list of values. + * Functional interface for iterating over a list of values, possibly returning a value to replace + * the old value. */ @FunctionalInterface public interface InstructionValueProcedure {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Wed Apr 15 11:03:04 2015 -0700 @@ -75,6 +75,22 @@ } /** + * Iterates the frame state and calls the {@link InstructionValueProcedure} for every variable. + * + * @param proc The procedure called for variables. + */ + public void forEachState(LIRInstruction inst, InstructionValueConsumer proc) { + for (BytecodeFrame cur = topFrame; cur != null; cur = cur.caller()) { + processValues(inst, cur.values, proc); + } + if (virtualObjects != null) { + for (VirtualObject obj : virtualObjects) { + processValues(inst, obj.getValues(), proc); + } + } + } + + /** * We filter out constant and illegal values ourself before calling the procedure, so * {@link OperandFlag#CONST} and {@link OperandFlag#ILLEGAL} need not be set. */ @@ -83,29 +99,51 @@ 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, InstructionValueProcedure proc, Value value) { - if (value instanceof StackLockValue) { - StackLockValue monitor = (StackLockValue) value; - Value owner = monitor.getOwner(); - if (owner instanceof AllocatableValue) { - monitor.setOwner(proc.doValue(inst, owner, OperandMode.ALIVE, STATE_FLAGS)); + if (isIllegal(value)) { + continue; } - Value slot = monitor.getSlot(); - if (isVirtualStackSlot(slot)) { - monitor.setSlot(asStackSlotValue(proc.doValue(inst, slot, OperandMode.ALIVE, STATE_FLAGS))); - } - } else { - if (!isIllegal(value) && value instanceof AllocatableValue) { - return proc.doValue(inst, value, OperandMode.ALIVE, STATE_FLAGS); + if (value instanceof AllocatableValue) { + Value result = proc.doValue(inst, value, OperandMode.ALIVE, STATE_FLAGS); + if (!value.identityEquals(result)) { + values[i] = result; + } + } else if (value instanceof StackLockValue) { + StackLockValue monitor = (StackLockValue) value; + Value owner = monitor.getOwner(); + if (owner instanceof AllocatableValue) { + monitor.setOwner(proc.doValue(inst, owner, OperandMode.ALIVE, STATE_FLAGS)); + } + Value slot = monitor.getSlot(); + if (isVirtualStackSlot(slot)) { + monitor.setSlot(asStackSlotValue(proc.doValue(inst, slot, OperandMode.ALIVE, STATE_FLAGS))); + } } else { assert unprocessed(value); } } - return value; + } + + protected void processValues(LIRInstruction inst, Value[] values, InstructionValueConsumer proc) { + for (int i = 0; i < values.length; i++) { + Value value = values[i]; + if (isIllegal(value)) { + continue; + } else if (value instanceof AllocatableValue) { + proc.visitValue(inst, value, OperandMode.ALIVE, STATE_FLAGS); + } else if (value instanceof StackLockValue) { + StackLockValue monitor = (StackLockValue) value; + Value owner = monitor.getOwner(); + if (owner instanceof AllocatableValue) { + proc.visitValue(inst, owner, OperandMode.ALIVE, STATE_FLAGS); + } + Value slot = monitor.getSlot(); + if (isVirtualStackSlot(slot)) { + proc.visitValue(inst, slot, OperandMode.ALIVE, STATE_FLAGS); + } + } else { + assert unprocessed(value); + } + } } private boolean unprocessed(Value value) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Wed Apr 15 11:03:04 2015 -0700 @@ -37,8 +37,6 @@ * The base class for an {@code LIRInstruction}. */ public abstract class LIRInstruction { - public static final Value[] NO_OPERANDS = {}; - /** * Constants denoting how a LIR instruction uses an operand. */ @@ -211,23 +209,6 @@ return false; } - // ValuePositionProcedures - public final void forEachInputPos(ValuePositionProcedure proc) { - instructionClass.forEachUsePos(this, proc); - } - - public final void forEachAlivePos(ValuePositionProcedure proc) { - instructionClass.forEachAlivePos(this, proc); - } - - public final void forEachTempPos(ValuePositionProcedure proc) { - instructionClass.forEachTempPos(this, proc); - } - - public final void forEachOutputPos(ValuePositionProcedure proc) { - instructionClass.forEachDefPos(this, proc); - } - // InstructionValueProcedures public final void forEachInput(InstructionValueProcedure proc) { instructionClass.forEachUse(this, proc);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Wed Apr 15 11:03:04 2015 -0700 @@ -205,22 +205,6 @@ return false; } - final void forEachUsePos(LIRInstruction obj, ValuePositionProcedure proc) { - forEach(obj, obj, uses, OperandMode.USE, 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 forEachTempPos(LIRInstruction obj, ValuePositionProcedure proc) { - forEach(obj, obj, temps, OperandMode.TEMP, 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, InstructionValueProcedure proc) { forEach(obj, uses, OperandMode.USE, proc); } @@ -237,6 +221,22 @@ forEach(obj, defs, OperandMode.DEF, proc); } + final void forEachUse(LIRInstruction obj, InstructionValueConsumer proc) { + forEach(obj, uses, OperandMode.USE, proc); + } + + final void forEachAlive(LIRInstruction obj, InstructionValueConsumer proc) { + forEach(obj, alives, OperandMode.ALIVE, proc); + } + + final void forEachTemp(LIRInstruction obj, InstructionValueConsumer proc) { + forEach(obj, temps, OperandMode.TEMP, proc); + } + + final void forEachDef(LIRInstruction obj, InstructionValueConsumer proc) { + forEach(obj, defs, OperandMode.DEF, proc); + } + final void forEachState(LIRInstruction obj, InstructionValueProcedure proc) { for (int i = 0; i < states.getCount(); i++) { LIRFrameState state = (LIRFrameState) states.getObject(obj, i); @@ -246,6 +246,15 @@ } } + final void forEachState(LIRInstruction obj, InstructionValueConsumer proc) { + for (int i = 0; i < states.getCount(); i++) { + LIRFrameState state = (LIRFrameState) states.getObject(obj, i); + if (state != null) { + state.forEachState(obj, proc); + } + } + } + final void forEachState(LIRInstruction obj, InstructionStateProcedure proc) { for (int i = 0; i < states.getCount(); i++) { LIRFrameState state = (LIRFrameState) states.getObject(obj, i);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java Wed Apr 15 11:03:04 2015 -0700 @@ -235,83 +235,34 @@ } } - protected static CompositeValue forEachComponent(LIRInstruction inst, CompositeValue obj, Values values, OperandMode mode, InstructionValueProcedure proc) { - CompositeValue newCompValue = null; + protected static void forEach(LIRInstruction inst, Values values, OperandMode mode, InstructionValueConsumer proc) { for (int i = 0; i < values.getCount(); i++) { assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(values.getFlags(i)); if (i < values.getDirectCount()) { - Value value = values.getValue(obj, i); - Value newValue; + Value value = values.getValue(inst, i); if (value instanceof CompositeValue) { CompositeValue composite = (CompositeValue) value; - newValue = composite.forEachComponent(inst, mode, proc); + composite.forEachComponent(inst, mode, proc); } else { - newValue = proc.doValue(inst, value, mode, values.getFlags(i)); - } - if (!value.identityEquals(newValue)) { - // lazy initialize - if (newCompValue == null) { - newCompValue = obj.clone(); - } - values.setValue(newCompValue, i, newValue); + proc.visitValue(inst, value, mode, values.getFlags(i)); } } else { - Value[] valueArray = values.getValueArray(obj, i); - Value[] newValues = null; + 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); + composite.forEachComponent(inst, mode, proc); } else { - newValue = proc.doValue(inst, value, mode, values.getFlags(i)); - } - if (!value.identityEquals(newValue)) { - // lazy initialize - if (newValues == null) { - if (newCompValue == null) { - newCompValue = obj.clone(); - } - newValues = values.getValueArray(newCompValue, i); - } - newValues[j] = newValue; + proc.visitValue(inst, value, mode, values.getFlags(i)); } } } } - return newCompValue != null ? newCompValue : obj; - } - - 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 < values.getDirectCount()) { - Value value = values.getValue(obj, i); - doForValue(inst, values, mode, proc, outerPosition, i, ValuePosition.NO_SUBINDEX, value); - } else { - Value[] valueArray = values.getValueArray(obj, i); - for (int j = 0; j < valueArray.length; j++) { - Value value = valueArray[j]; - doForValue(inst, values, mode, proc, outerPosition, i, j, value); - } - } - } } - private static void doForValue(LIRInstruction inst, Values values, OperandMode mode, ValuePositionProcedure proc, ValuePosition outerPosition, int index, int subIndex, Value value) { - ValuePosition position = new ValuePosition(values, index, subIndex, outerPosition); - if (value instanceof CompositeValue) { - CompositeValue composite = (CompositeValue) value; - composite.forEachComponent(inst, mode, proc, position); - } else { - proc.doValue(inst, position); - } - } - - protected void appendValues(StringBuilder sb, Object obj, String start, String end, String startMultiple, String endMultiple, String[] prefix, Fields... fieldsList) { + protected static void appendValues(StringBuilder sb, Object obj, String start, String end, String startMultiple, String endMultiple, String[] prefix, Fields... fieldsList) { int total = 0; for (Fields fields : fieldsList) { total += fields.getCount(); @@ -343,7 +294,7 @@ sb.append(end); } - protected String getFieldString(Object obj, int index, Fields fields) { + protected static String getFieldString(Object obj, int index, Fields fields) { Object value = fields.get(obj, index); Class<?> type = fields.getType(index); if (value == null || type.isPrimitive() || !type.isArray()) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValueConsumer.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValueConsumer.java Wed Apr 15 11:03:04 2015 -0700 @@ -32,7 +32,7 @@ * Non-modifying version of {@link ValueProcedure}. */ @FunctionalInterface -public interface ValueConsumer extends InstructionValueProcedure { +public interface ValueConsumer extends InstructionValueConsumer { /** * Iterator method to be overwritten. @@ -43,8 +43,7 @@ */ void visitValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags); - default Value doValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet<OperandFlag> flags) { + default void visitValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet<OperandFlag> flags) { visitValue(value, mode, flags); - return value; } }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValuePosition.java Wed Apr 15 10:21:02 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,177 +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.OperandFlag; -import com.oracle.graal.lir.LIRIntrospection.Values; - -/** - * Describes an operand slot for a {@link LIRInstruction}. - */ -public final class ValuePosition { - - /** - * The {@linkplain Values offsets} to the fields of the containing element (either - * {@link LIRInstruction} or {@link CompositeValue}). - */ - private final Values values; - /** - * The index into {@link #values}. - * - * @see Values#getValue(Object, int) - */ - private final int index; - /** - * The sub-index if {@link #index} points to a value array, otherwise {@link #NO_SUBINDEX}. - * - * @see Values#getDirectCount() - * @see Values#getValueArray(Object, int) - */ - private final int subIndex; - /** - * The {@link ValuePosition} of the containing {@link CompositeValue} if this value is part of a - * {@link CompositeValue}, otherwise {@link #ROOT_VALUE_POSITION}. - */ - private final ValuePosition outerPosition; - - public static final int NO_SUBINDEX = -1; - public static final ValuePosition ROOT_VALUE_POSITION = null; - - ValuePosition(Values values, int index, int subIndex, ValuePosition outerPosition) { - this.values = values; - this.index = index; - this.subIndex = subIndex; - this.outerPosition = outerPosition; - } - - /** - * @return True if the value denoted by this {@linkplain ValuePosition position} is part of a - * {@link CompositeValue}. - */ - private boolean isCompositePosition() { - return outerPosition != ROOT_VALUE_POSITION; - } - - /** - * @param inst The instruction this {@linkplain ValuePosition position} belongs to. - * @return The value denoted by this {@linkplain ValuePosition position}. - */ - public Value get(LIRInstruction inst) { - Object obj = inst; - if (isCompositePosition()) { - obj = outerPosition.get(inst); - assert obj instanceof CompositeValue : "The holder of a composite position is not a CompositeValue? " + obj; - } - if (index < values.getDirectCount()) { - return values.getValue(obj, index); - } - return values.getValueArray(obj, index)[subIndex]; - } - - /** - * Sets the value denoted by this {@linkplain ValuePosition position}. - * - * @param inst The instruction this {@linkplain ValuePosition position} belongs to. - */ - public void set(LIRInstruction inst, Value value) { - Object obj = inst; - if (isCompositePosition()) { - CompositeValue compValue = (CompositeValue) outerPosition.get(inst); - CompositeValue newCompValue = compValue.clone(); - outerPosition.set(inst, newCompValue); - obj = newCompValue; - } - if (index < values.getDirectCount()) { - values.setValue(obj, index, value); - } else { - values.getValueArray(obj, index)[subIndex] = value; - } - } - - /** - * @return The flags associated with the value denoted by this {@linkplain ValuePosition - * position}. - */ - public EnumSet<OperandFlag> getFlags() { - return values.getFlags(index); - } - - @Override - public String toString() { - String str = "(" + index + (subIndex < 0 ? "" : "/" + subIndex) + ")"; - if (isCompositePosition()) { - return outerPosition.toString() + "[" + str + "]"; - } - return str; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + index; - result = prime * result + subIndex; - result = prime * result + ((outerPosition == null) ? 0 : outerPosition.hashCode()); - result = prime * result + ((values == null) ? 0 : values.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - ValuePosition other = (ValuePosition) obj; - if (index != other.index) { - return false; - } - if (subIndex != other.subIndex) { - return false; - } - if (outerPosition == null) { - if (other.outerPosition != null) { - return false; - } - } else if (!outerPosition.equals(other.outerPosition)) { - return false; - } - if (values == null) { - if (other.values != null) { - return false; - } - } else if (!values.equals(other.values)) { - return false; - } - return true; - } - -}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValuePositionProcedure.java Wed Apr 15 10:21:02 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +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; - -/** - * Iterator for iterating over a list of {@linkplain ValuePosition value positions}. - */ -@FunctionalInterface -public interface ValuePositionProcedure { - - /** - * 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 position The position of the value that is iterated. - */ - void doValue(LIRInstruction instruction, ValuePosition position); -}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScan.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScan.java Wed Apr 15 11:03:04 2015 -0700 @@ -554,7 +554,9 @@ // move target is a stack slot that is always correct, so eliminate // instruction if (Debug.isLogEnabled()) { - Debug.log("eliminating move from interval %d to %d", operandNumber(move.getInput()), operandNumber(move.getResult())); + if (Debug.isLogEnabled()) { + Debug.log("eliminating move from interval %d to %d", operandNumber(move.getInput()), operandNumber(move.getResult())); + } } // null-instructions are deleted by assignRegNum instructions.set(j, null); @@ -582,7 +584,9 @@ insertionBuffer.append(j + 1, getSpillMoveFactory().createMove(toLocation, fromLocation)); - Debug.log("inserting move after definition of interval %d to stack slot %s at opId %d", interval.operandNumber, interval.spillSlot(), opId); + if (Debug.isLogEnabled()) { + Debug.log("inserting move after definition of interval %d to stack slot %s at opId %d", interval.operandNumber, interval.spillSlot(), opId); + } } interval = interval.next; } @@ -612,7 +616,9 @@ assert temp.spillDefinitionPos() >= temp.from() : "invalid order"; assert temp.spillDefinitionPos() <= temp.from() + 2 : "only intervals defined once at their start-pos can be optimized"; - Debug.log("interval %d (from %d to %d) must be stored at %d", temp.operandNumber, temp.from(), temp.to(), temp.spillDefinitionPos()); + if (Debug.isLogEnabled()) { + Debug.log("interval %d (from %d to %d) must be stored at %d", temp.operandNumber, temp.from(), temp.to(), temp.spillDefinitionPos()); + } prev = temp; temp = temp.next; @@ -695,7 +701,9 @@ int operandNum = operandNumber(operand); if (!liveKill.get(operandNum)) { liveGen.set(operandNum); - Debug.log("liveGen for operand %d", operandNum); + if (Debug.isLogEnabled()) { + Debug.log("liveGen for operand %d", operandNum); + } } if (block.getLoop() != null) { intervalInLoop.setBit(operandNum, block.getLoop().getIndex()); @@ -711,7 +719,9 @@ int operandNum = operandNumber(operand); if (!liveKill.get(operandNum)) { liveGen.set(operandNum); - Debug.log("liveGen in state for operand %d", operandNum); + if (Debug.isLogEnabled()) { + Debug.log("liveGen in state for operand %d", operandNum); + } } } }; @@ -719,7 +729,9 @@ if (isVariable(operand)) { int varNum = operandNumber(operand); liveKill.set(varNum); - Debug.log("liveKill for operand %d", varNum); + if (Debug.isLogEnabled()) { + Debug.log("liveKill for operand %d", varNum); + } if (block.getLoop() != null) { intervalInLoop.setBit(varNum, block.getLoop().getIndex()); } @@ -754,8 +766,10 @@ blockSets.liveIn = new BitSet(liveSize); blockSets.liveOut = new BitSet(liveSize); - Debug.log("liveGen B%d %s", block.getId(), blockSets.liveGen); - Debug.log("liveKill B%d %s", block.getId(), blockSets.liveKill); + if (Debug.isLogEnabled()) { + Debug.log("liveGen B%d %s", block.getId(), blockSets.liveGen); + Debug.log("liveKill B%d %s", block.getId(), blockSets.liveKill); + } } } // end of block iteration @@ -845,7 +859,9 @@ liveIn.andNot(blockSets.liveKill); liveIn.or(blockSets.liveGen); - Debug.log("block %d: livein = %s, liveout = %s", block.getId(), liveIn, blockSets.liveOut); + if (Debug.isLogEnabled()) { + Debug.log("block %d: livein = %s, liveout = %s", block.getId(), liveIn, blockSets.liveOut); + } } } iterationCount++; @@ -983,7 +999,9 @@ // Register use position at even instruction id. interval.addUsePos(to & ~1, registerPriority); - Debug.log("add use: %s, from %d to %d (%s)", interval, from, to, registerPriority.name()); + if (Debug.isLogEnabled()) { + Debug.log("add use: %s, from %d to %d (%s)", interval, from, to, registerPriority.name()); + } } void addTemp(AllocatableValue operand, int tempPos, RegisterPriority registerPriority, LIRKind kind) { @@ -1000,7 +1018,9 @@ interval.addUsePos(tempPos, registerPriority); interval.addMaterializationValue(null); - Debug.log("add temp: %s tempPos %d (%s)", interval, tempPos, RegisterPriority.MustHaveRegister.name()); + if (Debug.isLogEnabled()) { + Debug.log("add temp: %s tempPos %d (%s)", interval, tempPos, RegisterPriority.MustHaveRegister.name()); + } } boolean isProcessed(Value operand) { @@ -1030,7 +1050,9 @@ // also add register priority for dead intervals interval.addRange(defPos, defPos + 1); interval.addUsePos(defPos, registerPriority); - Debug.log("Warning: def of operand %s at %d occurs without use", operand, defPos); + if (Debug.isLogEnabled()) { + Debug.log("Warning: def of operand %s at %d occurs without use", operand, defPos); + } } changeSpillDefinitionPos(interval, defPos); @@ -1040,7 +1062,9 @@ } interval.addMaterializationValue(LinearScan.getMaterializedValue(op, operand, interval)); - Debug.log("add def: %s defPos %d (%s)", interval, defPos, registerPriority.name()); + if (Debug.isLogEnabled()) { + Debug.log("add def: %s defPos %d (%s)", interval, defPos, registerPriority.name()); + } } /** @@ -1092,7 +1116,9 @@ assert blockForId(op.id()).getPredecessorCount() == 0 : "move from stack must be in first block"; assert isVariable(move.getResult()) : "result of move must be a variable"; - Debug.log("found move from stack slot %s to %s", slot, move.getResult()); + if (Debug.isLogEnabled()) { + Debug.log("found move from stack slot %s to %s", slot, move.getResult()); + } } Interval interval = intervalFor(move.getResult()); @@ -1116,7 +1142,9 @@ } else { from.setLocationHint(to); } - Debug.log("operation at opId %d: added hint from interval %d to %d", op.id(), from.operandNumber, to.operandNumber); + if (Debug.isLogEnabled()) { + Debug.log("operation at opId %d: added hint from interval %d to %d", op.id(), from.operandNumber, to.operandNumber); + } return registerHint; } @@ -1191,7 +1219,9 @@ for (int operandNum = live.nextSetBit(0); operandNum >= 0; operandNum = live.nextSetBit(operandNum + 1)) { assert live.get(operandNum) : "should not stop here otherwise"; AllocatableValue operand = intervalFor(operandNum).operand; - Debug.log("live in %d: %s", operandNum, operand); + if (Debug.isLogEnabled()) { + Debug.log("live in %d: %s", operandNum, operand); + } addUse(operand, blockFrom, blockTo + 2, RegisterPriority.None, LIRKind.Illegal); @@ -1220,7 +1250,9 @@ addTemp(r.asValue(), opId, RegisterPriority.None, LIRKind.Illegal); } } - Debug.log("operation destroys all caller-save registers"); + if (Debug.isLogEnabled()) { + Debug.log("operation destroys all caller-save registers"); + } } op.visitEachOutput(outputConsumer); @@ -1413,24 +1445,20 @@ Interval result = interval.getSplitChildAtOpId(opId, mode, this); if (result != null) { - Debug.log("Split child at pos %d of interval %s is %s", opId, interval, result); + if (Debug.isLogEnabled()) { + Debug.log("Split child at pos %d of interval %s is %s", opId, interval, result); + } return result; } throw new BailoutException("LinearScan: interval is null"); } - Interval intervalAtBlockBegin(AbstractBlockBase<?> block, int operandNumber) { - return splitChildAtOpId(intervalFor(operandNumber), getFirstLirInstructionId(block), LIRInstruction.OperandMode.DEF); - } - - Interval intervalAtBlockEnd(AbstractBlockBase<?> block, int operandNumber) { - return splitChildAtOpId(intervalFor(operandNumber), getLastLirInstructionId(block) + 1, LIRInstruction.OperandMode.DEF); - } - void resolveCollectMappings(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock, MoveResolver moveResolver) { assert moveResolver.checkEmpty(); + int toBlockFirstInstructionId = getFirstLirInstructionId(toBlock); + int fromBlockLastInstructionId = getLastLirInstructionId(fromBlock) + 1; int numOperands = operandSize(); BitSet liveAtEdge = blockData.get(toBlock).liveIn; @@ -1439,8 +1467,8 @@ assert operandNum < numOperands : "live information set for not exisiting interval"; assert blockData.get(fromBlock).liveOut.get(operandNum) && blockData.get(toBlock).liveIn.get(operandNum) : "interval not live at this edge"; - Interval fromInterval = intervalAtBlockEnd(fromBlock, operandNum); - Interval toInterval = intervalAtBlockBegin(toBlock, operandNum); + Interval fromInterval = splitChildAtOpId(intervalFor(operandNum), fromBlockLastInstructionId, LIRInstruction.OperandMode.DEF); + Interval toInterval = splitChildAtOpId(intervalFor(operandNum), toBlockFirstInstructionId, LIRInstruction.OperandMode.DEF); if (fromInterval != toInterval && !fromInterval.location().equals(toInterval.location())) { // need to insert move instruction @@ -1451,7 +1479,9 @@ void resolveFindInsertPos(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock, MoveResolver moveResolver) { if (fromBlock.getSuccessorCount() <= 1) { - Debug.log("inserting moves at end of fromBlock B%d", fromBlock.getId()); + if (Debug.isLogEnabled()) { + Debug.log("inserting moves at end of fromBlock B%d", fromBlock.getId()); + } List<LIRInstruction> instructions = ir.getLIRforBlock(fromBlock); LIRInstruction instr = instructions.get(instructions.size() - 1); @@ -1463,7 +1493,9 @@ } } else { - Debug.log("inserting moves at beginning of toBlock B%d", toBlock.getId()); + if (Debug.isLogEnabled()) { + Debug.log("inserting moves at beginning of toBlock B%d", toBlock.getId()); + } if (DetailedAsserts.getValue()) { assert ir.getLIRforBlock(fromBlock).get(0) instanceof StandardOp.LabelOp : "block does not start with a label"; @@ -1508,7 +1540,9 @@ // prevent optimization of two consecutive blocks if (!blockCompleted.get(pred.getLinearScanNumber()) && !blockCompleted.get(sux.getLinearScanNumber())) { - Debug.log(" optimizing empty block B%d (pred: B%d, sux: B%d)", block.getId(), pred.getId(), sux.getId()); + if (Debug.isLogEnabled()) { + Debug.log(" optimizing empty block B%d (pred: B%d, sux: B%d)", block.getId(), pred.getId(), sux.getId()); + } blockCompleted.set(block.getLinearScanNumber()); @@ -1535,7 +1569,9 @@ // check for duplicate edges between the same blocks (can happen with switch // blocks) if (!alreadyResolved.get(toBlock.getLinearScanNumber())) { - Debug.log("processing edge between B%d and B%d", fromBlock.getId(), toBlock.getId()); + if (Debug.isLogEnabled()) { + Debug.log("processing edge between B%d and B%d", fromBlock.getId(), toBlock.getId()); + } alreadyResolved.set(toBlock.getLinearScanNumber()); @@ -1841,7 +1877,9 @@ // iterate all blocks where the interval has use positions for (AbstractBlockBase<?> splitBlock : blocksForInterval(splitChild)) { if (dominates(defBlock, splitBlock)) { - Debug.log("Split interval %s, block %s", splitChild, splitBlock); + if (Debug.isLogEnabled()) { + Debug.log("Split interval %s, block %s", splitChild, splitBlock); + } if (spillBlock == null) { spillBlock = splitBlock; } else { @@ -1868,14 +1906,18 @@ assert firstSpillChild != null; if (!defBlock.equals(spillBlock) && spillBlock.equals(blockForId(firstSpillChild.from()))) { AbstractBlockBase<?> dom = spillBlock.getDominator(); - Debug.log("Spill block (%s) is the beginning of a spill child -> use dominator (%s)", spillBlock, dom); + if (Debug.isLogEnabled()) { + Debug.log("Spill block (%s) is the beginning of a spill child -> use dominator (%s)", spillBlock, dom); + } spillBlock = dom; } if (!defBlock.equals(spillBlock)) { assert dominates(defBlock, spillBlock); betterSpillPos.increment(); - Debug.log("Better spill position found (Block %s)", spillBlock); + if (Debug.isLogEnabled()) { + Debug.log("Better spill position found (Block %s)", spillBlock); + } if (defBlock.probability() <= spillBlock.probability()) { // better spill block has the same probability -> do nothing
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanWalker.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanWalker.java Wed Apr 15 11:03:04 2015 -0700 @@ -297,7 +297,9 @@ int optimalSplitPos = -1; if (minSplitPos == maxSplitPos) { // trivial case, no optimization of split position possible - Debug.log("min-pos and max-pos are equal, no optimization possible"); + if (Debug.isLogEnabled()) { + Debug.log("min-pos and max-pos are equal, no optimization possible"); + } optimalSplitPos = minSplitPos; } else { @@ -319,7 +321,9 @@ assert minBlock.getLinearScanNumber() <= maxBlock.getLinearScanNumber() : "invalid order"; if (minBlock == maxBlock) { // split position cannot be moved to block boundary : so split as late as possible - Debug.log("cannot move split pos to block boundary because minPos and maxPos are in same block"); + if (Debug.isLogEnabled()) { + Debug.log("cannot move split pos to block boundary because minPos and maxPos are in same block"); + } optimalSplitPos = maxSplitPos; } else { @@ -329,19 +333,25 @@ // as mustHaveRegister) with a hole before each definition. When the register is // needed // for the second definition : an earlier reloading is unnecessary. - Debug.log("interval has hole just before maxSplitPos, so splitting at maxSplitPos"); + if (Debug.isLogEnabled()) { + Debug.log("interval has hole just before maxSplitPos, so splitting at maxSplitPos"); + } optimalSplitPos = maxSplitPos; } else { // seach optimal block boundary between minSplitPos and maxSplitPos - Debug.log("moving split pos to optimal block boundary between block B%d and B%d", minBlock.getId(), maxBlock.getId()); + if (Debug.isLogEnabled()) { + Debug.log("moving split pos to optimal block boundary between block B%d and B%d", minBlock.getId(), maxBlock.getId()); + } if (doLoopOptimization) { // Loop optimization: if a loop-end marker is found between min- and // max-position : // then split before this loop int loopEndPos = interval.nextUsageExact(RegisterPriority.LiveAtLoopEnd, allocator.getLastLirInstructionId(minBlock) + 2); - Debug.log("loop optimization: loop end found at pos %d", loopEndPos); + if (Debug.isLogEnabled()) { + Debug.log("loop optimization: loop end found at pos %d", loopEndPos); + } assert loopEndPos > minSplitPos : "invalid order"; if (loopEndPos < maxSplitPos) { @@ -354,15 +364,22 @@ // of the interval (normally, only mustHaveRegister causes a reloading) AbstractBlockBase<?> loopBlock = allocator.blockForId(loopEndPos); - Debug.log("interval is used in loop that ends in block B%d, so trying to move maxBlock back from B%d to B%d", loopBlock.getId(), maxBlock.getId(), loopBlock.getId()); + if (Debug.isLogEnabled()) { + Debug.log("interval is used in loop that ends in block B%d, so trying to move maxBlock back from B%d to B%d", loopBlock.getId(), maxBlock.getId(), loopBlock.getId()); + } assert loopBlock != minBlock : "loopBlock and minBlock must be different because block boundary is needed between"; - optimalSplitPos = findOptimalSplitPos(minBlock, loopBlock, allocator.getLastLirInstructionId(loopBlock) + 2); - if (optimalSplitPos == allocator.getLastLirInstructionId(loopBlock) + 2) { + int maxSpillPos = allocator.getLastLirInstructionId(loopBlock) + 2; + optimalSplitPos = findOptimalSplitPos(minBlock, loopBlock, maxSpillPos); + if (optimalSplitPos == maxSpillPos) { optimalSplitPos = -1; - Debug.log("loop optimization not necessary"); + if (Debug.isLogEnabled()) { + Debug.log("loop optimization not necessary"); + } } else { - Debug.log("loop optimization successful"); + if (Debug.isLogEnabled()) { + Debug.log("loop optimization successful"); + } } } } @@ -374,7 +391,9 @@ } } } - Debug.log("optimal split position: %d", optimalSplitPos); + if (Debug.isLogEnabled()) { + Debug.log("optimal split position: %d", optimalSplitPos); + } return optimalSplitPos; } @@ -401,7 +420,9 @@ if (optimalSplitPos == interval.to() && interval.nextUsage(RegisterPriority.MustHaveRegister, minSplitPos) == Integer.MAX_VALUE) { // the split position would be just before the end of the interval // . no split at all necessary - Debug.log("no split necessary because optimal split position is at end of interval"); + if (Debug.isLogEnabled()) { + Debug.log("no split necessary because optimal split position is at end of interval"); + } return; } @@ -414,7 +435,9 @@ optimalSplitPos = (optimalSplitPos - 1) | 1; } - Debug.log("splitting at position %d", optimalSplitPos); + if (Debug.isLogEnabled()) { + Debug.log("splitting at position %d", optimalSplitPos); + } assert allocator.isBlockBegin(optimalSplitPos) || ((optimalSplitPos & 1) == 1) : "split pos must be odd when not on block boundary"; assert !allocator.isBlockBegin(optimalSplitPos) || ((optimalSplitPos & 1) == 0) : "split pos must be even on block boundary"; @@ -472,7 +495,9 @@ if (isRegister(parent.location())) { if (parent.firstUsage(RegisterPriority.ShouldHaveRegister) == Integer.MAX_VALUE) { // parent is never used, so kick it out of its assigned register - Debug.log("kicking out interval %d out of its register because it is never used", parent.operandNumber); + if (Debug.isLogEnabled()) { + Debug.log("kicking out interval %d out of its register because it is never used", parent.operandNumber); + } allocator.assignSpillSlot(parent); handleSpillSlot(parent); } else { @@ -507,7 +532,9 @@ allocator.changeSpillState(spilledPart, optimalSplitPos); if (!allocator.isBlockBegin(optimalSplitPos)) { - Debug.log("inserting move from interval %d to %d", interval.operandNumber, spilledPart.operandNumber); + if (Debug.isLogEnabled()) { + Debug.log("inserting move from interval %d to %d", interval.operandNumber, spilledPart.operandNumber); + } insertMove(optimalSplitPos, interval, spilledPart); } @@ -599,7 +626,9 @@ Interval locationHint = interval.locationHint(true); if (locationHint != null && locationHint.location() != null && isRegister(locationHint.location())) { hint = asRegister(locationHint.location()); - Debug.log("hint register %d from interval %s", hint.number, locationHint); + if (Debug.isLogEnabled()) { + Debug.log("hint register %d from interval %s", hint.number, locationHint); + } } assert interval.location() == null : "register already assigned to interval"; @@ -641,7 +670,9 @@ splitPos = usePos[reg.number]; interval.assignLocation(reg.asValue(interval.kind())); - Debug.log("selected register %d", reg.number); + if (Debug.isLogEnabled()) { + Debug.log("selected register %d", reg.number); + } assert splitPos > 0 : "invalid splitPos"; if (needSplit) { @@ -710,7 +741,9 @@ int regUsePos = (reg == null ? 0 : usePos[reg.number]); if (regUsePos <= firstUsage) { - Debug.log("able to spill current interval. firstUsage(register): %d, usePos: %d", firstUsage, regUsePos); + if (Debug.isLogEnabled()) { + Debug.log("able to spill current interval. firstUsage(register): %d, usePos: %d", firstUsage, regUsePos); + } if (firstUsage <= interval.from() + 1) { String description = "cannot spill interval that is used in first instruction (possible reason: no register found) firstUsage=" + firstUsage + ", interval.from()=" + @@ -729,7 +762,9 @@ int splitPos = blockPos[reg.number]; - Debug.log("decided to use register %d", reg.number); + if (Debug.isLogEnabled()) { + Debug.log("decided to use register %d", reg.number); + } assert splitPos > 0 : "invalid splitPos"; assert needSplit || splitPos > interval.from() : "splitting interval at from"; @@ -756,7 +791,9 @@ if (isOdd(pos)) { // the current instruction is a call that blocks all registers if (pos < allocator.maxOpId() && allocator.hasCall(pos + 1) && interval.to() > pos + 1) { - Debug.log("free register cannot be available because all registers blocked by following call"); + if (Debug.isLogEnabled()) { + Debug.log("free register cannot be available because all registers blocked by following call"); + } // safety check that there is really no register available assert !allocFreeRegister(interval) : "found a register for this interval"; @@ -852,7 +889,9 @@ // activating an interval that has a stack slot assigned . split it at first use // position // used for method parameters - Debug.log("interval has spill slot assigned (method parameter) . split it before first use"); + if (Debug.isLogEnabled()) { + Debug.log("interval has spill slot assigned (method parameter) . split it before first use"); + } splitStackInterval(interval); result = false; @@ -860,7 +899,9 @@ if (interval.location() == null) { // interval has not assigned register . normal allocation // (this is the normal case for most intervals) - Debug.log("normal allocation of register"); + if (Debug.isLogEnabled()) { + Debug.log("normal allocation of register"); + } // assign same spill slot to non-intersecting intervals combineSpilledIntervals(interval); @@ -884,7 +925,9 @@ assert interval.isSplitChild(); assert interval.currentSplitChild() != null; assert !interval.currentSplitChild().operand.equals(operand) : "cannot insert move between same interval"; - Debug.log("Inserting move from interval %d to %d because insertMoveWhenActivated is set", interval.currentSplitChild().operandNumber, interval.operandNumber); + if (Debug.isLogEnabled()) { + Debug.log("Inserting move from interval %d to %d because insertMoveWhenActivated is set", interval.currentSplitChild().operandNumber, interval.operandNumber); + } insertMove(interval.from(), interval.currentSplitChild(), interval); }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java Wed Apr 15 11:03:04 2015 -0700 @@ -54,10 +54,55 @@ @Override protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory) { - new Marker(lirGenRes.getLIR(), lirGenRes.getFrameMap()).build(); + new Marker<B>(lirGenRes.getLIR(), lirGenRes.getFrameMap()).build(); } - private static final class Marker { + /** + * Ensures that an element is only in the worklist once. + * + * @param <T> + */ + static class UniqueWorkList<T extends AbstractBlockBase<T>> extends ArrayDeque<T> { + private static final long serialVersionUID = 8009554570990975712L; + BitSet valid; + + public UniqueWorkList(int size) { + this.valid = new BitSet(size); + } + + @Override + public T poll() { + T result = super.poll(); + if (result != null) { + valid.set(result.getId(), false); + } + return result; + } + + @Override + public boolean add(T pred) { + if (!valid.get(pred.getId())) { + valid.set(pred.getId(), true); + return super.add(pred); + } + return false; + } + + @Override + public boolean addAll(Collection<? extends T> collection) { + boolean changed = false; + for (T element : collection) { + if (!valid.get(element.getId())) { + valid.set(element.getId(), true); + super.add(element); + changed = true; + } + } + return changed; + } + } + + private static final class Marker<T extends AbstractBlockBase<T>> { private final LIR lir; private final FrameMap frameMap; private final RegisterAttributes[] registerAttributes; @@ -72,16 +117,17 @@ liveOutMap = new BlockMap<>(lir.getControlFlowGraph()); } - private void build() { - Deque<AbstractBlockBase<?>> worklist = new ArrayDeque<>(); + @SuppressWarnings("unchecked") + void build() { + UniqueWorkList<T> worklist = new UniqueWorkList<>(lir.getControlFlowGraph().getBlocks().size()); for (int i = lir.getControlFlowGraph().getBlocks().size() - 1; i >= 0; i--) { - worklist.add(lir.getControlFlowGraph().getBlocks().get(i)); + worklist.add((T) lir.getControlFlowGraph().getBlocks().get(i)); } for (AbstractBlockBase<?> block : lir.getControlFlowGraph().getBlocks()) { liveInMap.put(block, frameMap.initReferenceMap(true)); } while (!worklist.isEmpty()) { - AbstractBlockBase<?> block = worklist.poll(); + AbstractBlockBase<T> block = worklist.poll(); processBlock(block, worklist); } } @@ -101,7 +147,7 @@ return false; } - private void processBlock(AbstractBlockBase<?> block, Deque<AbstractBlockBase<?>> worklist) { + private void processBlock(AbstractBlockBase<T> block, UniqueWorkList<T> worklist) { if (updateOutBlock(block)) { try (Indent indent = Debug.logAndIndent("handle block %s", block)) { BlockClosure closure = new BlockClosure(liveOutMap.get(block).clone()); @@ -119,14 +165,6 @@ private static final EnumSet<OperandFlag> REGISTER_FLAG_SET = EnumSet.of(OperandFlag.REG); private static final LIRKind REFERENCE_KIND = LIRKind.reference(Kind.Object); - private void forEachDestroyedCallerSavedRegister(LIRInstruction op, ValueConsumer consumer) { - if (op.destroysCallerSavedRegisters()) { - for (Register reg : frameMap.getRegisterConfig().getCallerSaveRegisters()) { - consumer.visitValue(reg.asValue(REFERENCE_KIND), OperandMode.TEMP, REGISTER_FLAG_SET); - } - } - } - private final class BlockClosure { private final ReferenceMap currentSet; @@ -145,50 +183,57 @@ private void processInstructionBottomUp(LIRInstruction op) { try (Indent indent = Debug.logAndIndent("handle op %d, %s", op.id(), op)) { // kills - op.visitEachTemp(this::defConsumer); - op.visitEachOutput(this::defConsumer); - forEachDestroyedCallerSavedRegister(op, this::defConsumer); + + op.visitEachTemp(defConsumer); + op.visitEachOutput(defConsumer); + if (op.destroysCallerSavedRegisters()) { + for (Register reg : frameMap.getRegisterConfig().getCallerSaveRegisters()) { + defConsumer.visitValue(reg.asValue(REFERENCE_KIND), OperandMode.TEMP, REGISTER_FLAG_SET); + } + } // gen - values that are considered alive for this state - op.visitEachAlive(this::useConsumer); - op.visitEachState(this::useConsumer); + op.visitEachAlive(useConsumer); + op.visitEachState(useConsumer); // mark locations - op.forEachState((inst, info) -> markLocation(inst, info, this.getCurrentSet())); + op.forEachState(stateConsumer); // gen - op.visitEachInput(this::useConsumer); + op.visitEachInput(useConsumer); } } - /** - * @see InstructionValueConsumer - * @param operand - * @param mode - * @param flags - */ - private void useConsumer(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) { - LIRKind kind = operand.getLIRKind(); - if (shouldProcessValue(operand) && !kind.isValue() && !kind.isDerivedReference()) { - // no need to insert values and derived reference - Debug.log("set operand: %s", operand); - frameMap.setReference(operand, currentSet); + InstructionStateProcedure stateConsumer = new InstructionStateProcedure() { + public void doState(LIRInstruction inst, LIRFrameState info) { + markLocation(inst, info, getCurrentSet()); } - } + }; - /** - * @see InstructionValueConsumer - * @param operand - * @param mode - * @param flags - */ - private void defConsumer(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) { - if (shouldProcessValue(operand)) { - Debug.log("clear operand: %s", operand); - frameMap.clearReference(operand, currentSet); - } else { - assert isIllegal(operand) || operand.getPlatformKind() != Kind.Illegal || mode == OperandMode.TEMP : String.format("Illegal PlatformKind is only allowed for TEMP mode: %s, %s", - operand, mode); + ValueConsumer useConsumer = new ValueConsumer() { + public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) { + LIRKind kind = operand.getLIRKind(); + if (shouldProcessValue(operand) && !kind.isValue() && !kind.isDerivedReference()) { + // no need to insert values and derived reference + if (Debug.isLogEnabled()) { + Debug.log("set operand: %s", operand); + } + frameMap.setReference(operand, currentSet); + } } - } + }; + + ValueConsumer defConsumer = new ValueConsumer() { + public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) { + if (shouldProcessValue(operand)) { + if (Debug.isLogEnabled()) { + Debug.log("clear operand: %s", operand); + } + frameMap.clearReference(operand, currentSet); + } else { + assert isIllegal(operand) || operand.getPlatformKind() != Kind.Illegal || mode == OperandMode.TEMP : String.format( + "Illegal PlatformKind is only allowed for TEMP mode: %s, %s", operand, mode); + } + } + }; protected boolean shouldProcessValue(Value operand) { return (isRegister(operand) && attributes(asRegister(operand)).isAllocatable() || isStackSlot(operand)) && operand.getPlatformKind() != Kind.Illegal;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/MoveResolver.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/MoveResolver.java Wed Apr 15 11:03:04 2015 -0700 @@ -206,7 +206,9 @@ insertionBuffer.append(insertIdx, allocator.getSpillMoveFactory().createMove(toOpr, fromOpr)); - Debug.log("insert move from %s to %s at %d", fromInterval, toInterval, insertIdx); + if (Debug.isLogEnabled()) { + Debug.log("insert move from %s to %s at %d", fromInterval, toInterval, insertIdx); + } } private void insertMove(Value fromOpr, Interval toInterval) { @@ -216,7 +218,9 @@ AllocatableValue toOpr = toInterval.operand; insertionBuffer.append(insertIdx, allocator.getSpillMoveFactory().createMove(toOpr, fromOpr)); - Debug.log("insert move from value %s to %s at %d", fromOpr, toInterval, insertIdx); + if (Debug.isLogEnabled()) { + Debug.log("insert move from value %s to %s at %d", fromOpr, toInterval, insertIdx); + } } private void resolveMappings() { @@ -286,7 +290,9 @@ } spillInterval.assignLocation(spillSlot); - Debug.log("created new Interval for spilling: %s", spillInterval); + if (Debug.isLogEnabled()) { + Debug.log("created new Interval for spilling: %s", spillInterval); + } // insert a move from register to stack and update the mapping insertMove(fromInterval, spillInterval); @@ -328,7 +334,9 @@ void addMapping(Interval fromInterval, Interval toInterval) { if (isIllegal(toInterval.location()) && toInterval.canMaterialize()) { - Debug.log("no store to rematerializable interval %s needed", toInterval); + if (Debug.isLogEnabled()) { + Debug.log("no store to rematerializable interval %s needed", toInterval); + } return; } if (isIllegal(fromInterval.location()) && fromInterval.canMaterialize()) { @@ -337,7 +345,9 @@ addMapping(rematValue, toInterval); return; } - Debug.log("add move mapping from %s to %s", fromInterval, toInterval); + if (Debug.isLogEnabled()) { + Debug.log("add move mapping from %s to %s", fromInterval, toInterval); + } assert !fromInterval.operand.equals(toInterval.operand) : "from and to interval equal: " + fromInterval; assert fromInterval.kind().equals(toInterval.kind()); @@ -347,7 +357,9 @@ } void addMapping(Value fromOpr, Interval toInterval) { - Debug.log("add move mapping from %s to %s", fromOpr, toInterval); + if (Debug.isLogEnabled()) { + Debug.log("add move mapping from %s to %s", fromOpr, toInterval); + } assert isConstant(fromOpr) : "only for constants";
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java Wed Apr 15 11:03:04 2015 -0700 @@ -214,8 +214,8 @@ // set instruction id to the index in the lir instruction list inst.setId(opId++); inst.visitEachOutput(loadConsumer); - inst.forEachInput(useConsumer); - inst.forEachAlive(useConsumer); + inst.visitEachInput(useConsumer); + inst.visitEachAlive(useConsumer); } }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantTree.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantTree.java Wed Apr 15 11:03:04 2015 -0700 @@ -161,7 +161,11 @@ } public void markBlocks() { - stream(Flags.USAGE).forEach(block -> setDominatorPath(Flags.SUBTREE, block)); + for (AbstractBlockBase<?> block : getBlocks()) { + if (get(Flags.USAGE, block)) { + setDominatorPath(Flags.SUBTREE, block); + } + } } public boolean isMarked(AbstractBlockBase<?> block) { @@ -169,7 +173,12 @@ } public boolean isLeafBlock(AbstractBlockBase<?> block) { - return block.getDominated().stream().noneMatch(this::isMarked); + for (AbstractBlockBase<?> dom : block.getDominated()) { + if (isMarked(dom)) { + return false; + } + } + return true; } public void setSolution(AbstractBlockBase<?> block) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/FixPointIntervalBuilder.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/FixPointIntervalBuilder.java Wed Apr 15 11:03:04 2015 -0700 @@ -172,55 +172,42 @@ private void processInstructionBottomUp(LIRInstruction op) { try (Indent indent = Debug.logAndIndent("handle op %d, %s", op.id(), op)) { // kills - op.visitEachTemp(this::defConsumer); - op.visitEachOutput(this::defConsumer); + op.visitEachTemp(defConsumer); + op.visitEachOutput(defConsumer); // gen - values that are considered alive for this state - op.visitEachAlive(this::useConsumer); - op.visitEachState(this::useConsumer); + op.visitEachAlive(useConsumer); + op.visitEachState(useConsumer); // mark locations // gen - op.visitEachInput(this::useConsumer); + op.visitEachInput(useConsumer); } } - /** - * @see InstructionValueConsumer - * - * @param inst - * @param operand - * @param mode - * @param flags - */ - private void useConsumer(LIRInstruction inst, Value operand, OperandMode mode, EnumSet<OperandFlag> flags) { - if (isVirtualStackSlot(operand)) { - VirtualStackSlot vslot = asVirtualStackSlot(operand); - addUse(vslot, inst, flags); - usePos.add(inst); - Debug.log("set operand: %s", operand); - currentSet.set(vslot.getId()); + InstructionValueConsumer useConsumer = new InstructionValueConsumer() { + public void visitValue(LIRInstruction inst, Value operand, OperandMode mode, EnumSet<OperandFlag> flags) { + if (isVirtualStackSlot(operand)) { + VirtualStackSlot vslot = asVirtualStackSlot(operand); + addUse(vslot, inst, flags); + usePos.add(inst); + Debug.log("set operand: %s", operand); + currentSet.set(vslot.getId()); + } } - } + }; - /** - * - * @see InstructionValueConsumer - * - * @param inst - * @param operand - * @param mode - * @param flags - */ - private void defConsumer(LIRInstruction inst, Value operand, OperandMode mode, EnumSet<OperandFlag> flags) { - if (isVirtualStackSlot(operand)) { - VirtualStackSlot vslot = asVirtualStackSlot(operand); - addDef(vslot, inst); - usePos.add(inst); - Debug.log("clear operand: %s", operand); - currentSet.clear(vslot.getId()); + InstructionValueConsumer defConsumer = new InstructionValueConsumer() { + public void visitValue(LIRInstruction inst, Value operand, OperandMode mode, EnumSet<OperandFlag> flags) { + if (isVirtualStackSlot(operand)) { + VirtualStackSlot vslot = asVirtualStackSlot(operand); + addDef(vslot, inst); + usePos.add(inst); + Debug.log("clear operand: %s", operand); + currentSet.clear(vslot.getId()); + } + } - - } + }; private void addUse(VirtualStackSlot stackSlot, LIRInstruction inst, EnumSet<OperandFlag> flags) { StackInterval interval = getOrCreateInterval(stackSlot);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/LSStackSlotAllocator.java Wed Apr 15 10:21:02 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/LSStackSlotAllocator.java Wed Apr 15 11:03:04 2015 -0700 @@ -363,30 +363,26 @@ private void assignStackSlots(Set<LIRInstruction> usePos) { for (LIRInstruction op : usePos) { - op.forEachInput(this::assignSlot); - op.forEachAlive(this::assignSlot); - op.forEachState(this::assignSlot); + op.forEachInput(assignSlot); + op.forEachAlive(assignSlot); + op.forEachState(assignSlot); - op.forEachTemp(this::assignSlot); - op.forEachOutput(this::assignSlot); + op.forEachTemp(assignSlot); + op.forEachOutput(assignSlot); } } - /** - * @see ValueProcedure - * @param value - * @param mode - * @param flags - */ - private Value assignSlot(Value value, OperandMode mode, EnumSet<OperandFlag> flags) { - if (isVirtualStackSlot(value)) { - VirtualStackSlot slot = asVirtualStackSlot(value); - StackInterval interval = get(slot); - assert interval != null; - return interval.location(); + ValueProcedure assignSlot = new ValueProcedure() { + public Value doValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) { + if (isVirtualStackSlot(value)) { + VirtualStackSlot slot = asVirtualStackSlot(value); + StackInterval interval = get(slot); + assert interval != null; + return interval.location(); + } + return value; } - return value; - } + }; // ==================== //
--- a/src/share/vm/classfile/systemDictionary.hpp Wed Apr 15 10:21:02 2015 -0700 +++ b/src/share/vm/classfile/systemDictionary.hpp Wed Apr 15 11:03:04 2015 -0700 @@ -208,6 +208,7 @@ GRAAL_ONLY(do_klass(HotSpotCompiledRuntimeStub_klass, com_oracle_graal_hotspot_HotSpotCompiledRuntimeStub, Graal)) \ GRAAL_ONLY(do_klass(HotSpotForeignCallLinkageImpl_klass, com_oracle_graal_hotspot_HotSpotForeignCallLinkageImpl, Graal)) \ GRAAL_ONLY(do_klass(HotSpotReferenceMap_klass, com_oracle_graal_hotspot_HotSpotReferenceMap, Graal)) \ + GRAAL_ONLY(do_klass(HotSpotOopMap_klass, com_oracle_graal_hotspot_HotSpotReferenceMap_HotSpotOopMap, Graal)) \ GRAAL_ONLY(do_klass(HotSpotInstalledCode_klass, com_oracle_graal_hotspot_meta_HotSpotInstalledCode, Graal)) \ GRAAL_ONLY(do_klass(HotSpotNmethod_klass, com_oracle_graal_hotspot_meta_HotSpotNmethod, Graal)) \ GRAAL_ONLY(do_klass(HotSpotResolvedJavaMethodImpl_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethodImpl, Graal)) \
--- a/src/share/vm/classfile/vmSymbols.hpp Wed Apr 15 10:21:02 2015 -0700 +++ b/src/share/vm/classfile/vmSymbols.hpp Wed Apr 15 11:03:04 2015 -0700 @@ -310,6 +310,7 @@ GRAAL_ONLY(template(com_oracle_graal_hotspot_HotSpotCompiledRuntimeStub, "com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_HotSpotForeignCallLinkageImpl, "com/oracle/graal/hotspot/HotSpotForeignCallLinkageImpl")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_HotSpotReferenceMap, "com/oracle/graal/hotspot/HotSpotReferenceMap")) \ + GRAAL_ONLY(template(com_oracle_graal_hotspot_HotSpotReferenceMap_HotSpotOopMap, "com/oracle/graal/hotspot/HotSpotReferenceMap$HotSpotOopMap")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_bridge_CompilerToVMImpl, "com/oracle/graal/hotspot/bridge/CompilerToVMImpl")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotInstalledCode, "com/oracle/graal/hotspot/meta/HotSpotInstalledCode")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotNmethod, "com/oracle/graal/hotspot/meta/HotSpotNmethod")) \
--- a/src/share/vm/graal/graalCodeInstaller.cpp Wed Apr 15 10:21:02 2015 -0700 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Wed Apr 15 11:03:04 2015 -0700 @@ -71,35 +71,39 @@ const int MapWordBits = 64; -static bool is_bit_set(typeArrayOop words, int i) { +static int entry_value(typeArrayOop words, int i) { jint words_idx = i / MapWordBits; assert(words_idx >= 0 && words_idx < words->length(), "unexpected index"); jlong word = words->long_at(words_idx); - return (word & (1LL << (i % MapWordBits))) != 0; + return (word >> (i % MapWordBits)) & 15LL; } -static int bitset_size(oop bitset) { - typeArrayOop arr = BitSet::words(bitset); +static int fixedmap_size(oop bitset) { + typeArrayOop arr = HotSpotOopMap::words(bitset); return arr->length() * MapWordBits; } static void set_vmreg_oops(OopMap* map, VMReg reg, typeArrayOop words, int idx) { - bool is_oop = is_bit_set(words, 3 * idx); - if (is_oop) { - bool narrow1 = is_bit_set(words, 3 * idx + 1); - bool narrow2 = is_bit_set(words, 3 * idx + 2); - if (narrow1 || narrow2) { - if (narrow1) { - map->set_narrowoop(reg); - } - if (narrow2) { - map->set_narrowoop(reg->next()); - } - } else { + int value = entry_value(words, 4 * idx); + switch (value) { + case 10: map->set_oop(reg); - } - } else { - map->set_value(reg); + break; + case 5: + map->set_narrowoop(reg); + map->set_narrowoop(reg->next()); + break; + case 1: + map->set_narrowoop(reg); + break; + case 4: + map->set_narrowoop(reg->next()); + break; + case 0: + break; + default: + assert(false, err_msg("unexpected bit pattern at %d = 0x%x", idx, value)); + ShouldNotReachHere(); } } @@ -112,30 +116,30 @@ oop callee_save_info = (oop) DebugInfo::calleeSaveInfo(debug_info); if (register_map != NULL) { - typeArrayOop words = BitSet::words(register_map); + typeArrayOop words = HotSpotOopMap::words(register_map); + int mapIdx = 0; for (jint i = 0; i < RegisterImpl::number_of_registers; i++) { - set_vmreg_oops(map, as_Register(i)->as_VMReg(), words, i); + set_vmreg_oops(map, as_Register(i)->as_VMReg(), words, mapIdx); + mapIdx++; } #ifdef TARGET_ARCH_x86 for (jint i = 0; i < XMMRegisterImpl::number_of_registers; i++) { VMReg reg = as_XMMRegister(i)->as_VMReg(); - int idx = RegisterImpl::number_of_registers + 4 * i; for (jint j = 0; j < 4; j++) { - set_vmreg_oops(map, reg->next(2 * j), words, idx + j); + set_vmreg_oops(map, reg->next(2 * j), words, mapIdx++); } } #endif #ifdef TARGET_ARCH_sparc for (jint i = 0; i < FloatRegisterImpl::number_of_registers; i++) { VMReg reg = as_FloatRegister(i)->as_VMReg(); - int idx = RegisterImpl::number_of_registers + i; - set_vmreg_oops(map, reg, words, idx); + set_vmreg_oops(map, reg, words, mapIdx++); } #endif } - typeArrayOop words = BitSet::words(frame_map); - int size = bitset_size(frame_map) / 3; + typeArrayOop words = HotSpotOopMap::words(frame_map); + int size = fixedmap_size(frame_map) / 4; for (jint i = 0; i < size; i++) { // HotSpot stack slots are 4 bytes VMReg reg = VMRegImpl::stack2reg(i * VMRegImpl::slots_per_word); @@ -161,7 +165,6 @@ #endif } } - return map; }
--- a/src/share/vm/graal/graalJavaAccess.hpp Wed Apr 15 10:21:02 2015 -0700 +++ b/src/share/vm/graal/graalJavaAccess.hpp Wed Apr 15 11:03:04 2015 -0700 @@ -162,15 +162,15 @@ objArrayOop_field(DebugInfo, virtualObjectMapping, "[Lcom/oracle/graal/api/meta/Value;") \ end_class \ start_class(HotSpotReferenceMap) \ - oop_field(HotSpotReferenceMap, registerRefMap, "Ljava/util/BitSet;") \ - oop_field(HotSpotReferenceMap, frameRefMap, "Ljava/util/BitSet;") \ + oop_field(HotSpotReferenceMap, registerRefMap, "Lcom/oracle/graal/hotspot/HotSpotReferenceMap$HotSpotOopMap;") \ + oop_field(HotSpotReferenceMap, frameRefMap, "Lcom/oracle/graal/hotspot/HotSpotReferenceMap$HotSpotOopMap;") \ end_class \ start_class(RegisterSaveLayout) \ objArrayOop_field(RegisterSaveLayout, registers, "[Lcom/oracle/graal/api/code/Register;") \ typeArrayOop_field(RegisterSaveLayout, slots, "[I") \ end_class \ - start_class(BitSet) \ - typeArrayOop_field(BitSet, words, "[J") \ + start_class(HotSpotOopMap) \ + typeArrayOop_field(HotSpotOopMap, words, "[J") \ end_class \ start_class(BytecodeFrame) \ objArrayOop_field(BytecodeFrame, values, "[Lcom/oracle/graal/api/meta/Value;") \