changeset 18607:6383574293f9

Introduce FrameMap.clearReference().
author Josef Eisl <josef.eisl@jku.at>
date Wed, 03 Dec 2014 17:16:08 +0100
parents 3d0422b6f8fa
children 66e31efead2f
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMap.java
diffstat 3 files changed, 81 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- 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();
--- 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();
--- 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);
+        }
+    }
 }