# HG changeset patch # User Josef Eisl # Date 1417623368 -3600 # Node ID 6383574293f94846c6c50181bba1c6a6ae6c7b4f # Parent 3d0422b6f8fa8137f8b0c7d501616dda944a9b33 Introduce FrameMap.clearReference(). diff -r 3d0422b6f8fa -r 6383574293f9 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java Thu Dec 04 10:51:25 2014 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java Wed Dec 03 17:16:08 2014 +0100 @@ -29,8 +29,12 @@ void setRegister(int idx, LIRKind kind); + void clearRegister(int idx, LIRKind kind); + void setStackSlot(int offset, LIRKind kind); + void clearStackSlot(int offset, LIRKind kind); + boolean hasRegisterRefMap(); boolean hasFrameRefMap(); diff -r 3d0422b6f8fa -r 6383574293f9 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java Thu Dec 04 10:51:25 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java Wed Dec 03 17:16:08 2014 +0100 @@ -79,6 +79,8 @@ this.target = target; } + // setters + private static void setOop(BitSet map, int startIdx, LIRKind kind) { int length = kind.getPlatformKind().getVectorLength(); map.clear(BITS_PER_WORD * startIdx, BITS_PER_WORD * (startIdx + length) - 1); @@ -154,6 +156,69 @@ } } + // 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) - 1); + } + + 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 - 1); + } + + 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); + } else { + assert kind.isValue() : "unsupported reference kind " + kind; + } + } + + 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); + } + } + } + } + } else { + assert kind.isValue() : "unknown reference kind " + kind; + } + } + @Override public int hashCode() { throw new UnsupportedOperationException(); diff -r 3d0422b6f8fa -r 6383574293f9 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java Thu Dec 04 10:51:25 2014 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java Wed Dec 03 17:16:08 2014 +0100 @@ -337,4 +337,16 @@ assert isConstant(location); } } + + public void clearReference(Value location, ReferenceMap refMap) { + LIRKind kind = location.getLIRKind(); + if (isRegister(location)) { + refMap.clearRegister(asRegister(location).getReferenceMapIndex(), kind); + } else if (isStackSlot(location)) { + int offset = offsetForStackSlot(asStackSlot(location)); + refMap.clearStackSlot(offset, kind); + } else { + assert isConstant(location); + } + } }