changeset 16093:39be5bc00046

Support XMM registers in oop maps.
author Roland Schatz <roland.schatz@oracle.com>
date Fri, 13 Jun 2014 11:11:44 +0200
parents 51ba6c521922
children c0b8d395368b
files graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java src/share/vm/graal/graalCodeInstaller.cpp
diffstat 6 files changed, 70 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java	Fri Jun 13 11:08:16 2014 +0200
+++ b/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java	Fri Jun 13 11:11:44 2014 +0200
@@ -38,7 +38,6 @@
 public class AMD64 extends Architecture {
 
     public static final RegisterCategory CPU = new RegisterCategory("CPU");
-    public static final RegisterCategory XMM = new RegisterCategory("XMM");
 
     // @formatter:off
 
@@ -66,6 +65,10 @@
         r8, r9, r10, r11, r12, r13, r14, r15
     };
 
+    private static final int XMM_REFERENCE_MAP_SHIFT = 2;
+
+    public static final RegisterCategory XMM = new RegisterCategory("XMM", cpuRegisters.length, XMM_REFERENCE_MAP_SHIFT);
+
     // XMM registers
     public static final Register xmm0 = new Register(16, 0, "xmm0", XMM);
     public static final Register xmm1 = new Register(17, 1, "xmm1", XMM);
@@ -135,7 +138,7 @@
     private final EnumSet<CPUFeature> features;
 
     public AMD64(EnumSet<CPUFeature> features) {
-        super("AMD64", 8, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_STORE | STORE_STORE, 1, r15.encoding + 1, 8);
+        super("AMD64", 8, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_STORE | STORE_STORE, 1, cpuRegisters.length + xmmRegisters.length << XMM_REFERENCE_MAP_SHIFT, 8);
         this.features = features;
         assert features.contains(CPUFeature.SSE2) : "minimum config for x64";
     }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java	Fri Jun 13 11:08:16 2014 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java	Fri Jun 13 11:11:44 2014 +0200
@@ -79,10 +79,23 @@
      */
     public static class RegisterCategory {
 
-        private String name;
+        private final String name;
+
+        private final int referenceMapOffset;
+        private final int referenceMapShift;
 
         public RegisterCategory(String name) {
+            this(name, 0, 0);
+        }
+
+        public RegisterCategory(String name, int referenceMapOffset) {
+            this(name, referenceMapOffset, 0);
+        }
+
+        public RegisterCategory(String name, int referenceMapOffset, int referenceMapShift) {
             this.name = name;
+            this.referenceMapOffset = referenceMapOffset;
+            this.referenceMapShift = referenceMapShift;
         }
 
         @Override
@@ -107,7 +120,7 @@
 
     /**
      * Creates a {@link Register} instance.
-     * 
+     *
      * @param number unique identifier for the register
      * @param encoding the target machine encoding for the register
      * @param name the mnemonic name for the register
@@ -124,9 +137,13 @@
         return registerCategory;
     }
 
+    public int getReferenceMapIndex() {
+        return (encoding << registerCategory.referenceMapShift) + registerCategory.referenceMapOffset;
+    }
+
     /**
      * Gets this register as a {@linkplain RegisterValue value} with a specified kind.
-     * 
+     *
      * @param kind the specified kind
      * @return the {@link RegisterValue}
      */
@@ -136,7 +153,7 @@
 
     /**
      * Gets this register as a {@linkplain RegisterValue value} with no particular kind.
-     * 
+     *
      * @return a {@link RegisterValue} with {@link Kind#Illegal} kind.
      */
     public RegisterValue asValue() {
@@ -145,7 +162,7 @@
 
     /**
      * Determines if this is a valid register.
-     * 
+     *
      * @return {@code true} iff this register is valid
      */
     public boolean isValid() {
@@ -154,7 +171,7 @@
 
     /**
      * Gets the maximum register {@linkplain #number number} in a given set of registers.
-     * 
+     *
      * @param registers the set of registers to process
      * @return the maximum register number for any register in {@code registers}
      */
@@ -170,7 +187,7 @@
 
     /**
      * Gets the maximum register {@linkplain #encoding encoding} in a given set of registers.
-     * 
+     *
      * @param registers the set of registers to process
      * @return the maximum register encoding for any register in {@code registers}
      */
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java	Fri Jun 13 11:08:16 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java	Fri Jun 13 11:11:44 2014 +0200
@@ -35,11 +35,12 @@
     private static final long serialVersionUID = -1052183095979496819L;
 
     /**
-     * Contains 2 bits per register.
+     * Contains 3 bits per 64 bit register, and n*3 bits per n*64 bit vector register.
      * <ul>
      * <li>bit0 = 0: contains no references</li>
-     * <li>bit0 = 1, bit1 = 0: contains a wide oop</li>
-     * <li>bit0 = 1, bit1 = 1: contains a narrow oop</li>
+     * <li>bit0 = 1, bit1+2 = 0: contains a wide oop</li>
+     * <li>bit0 = 1, bit1 = 1: contains a narrow oop in the lower 32 bit</li>
+     * <li>bit0 = 1, bit2 = 1: contains a narrow oop in the upper 32 bit</li>
      * </ul>
      */
     private final BitSet registerRefMap;
@@ -59,7 +60,7 @@
 
     public HotSpotReferenceMap(int registerCount, int frameSlotCount, int frameSlotSize) {
         if (registerCount > 0) {
-            this.registerRefMap = new BitSet(registerCount * 2);
+            this.registerRefMap = new BitSet(registerCount * 3);
         } else {
             this.registerRefMap = null;
         }
@@ -69,25 +70,13 @@
 
     public void setRegister(int idx, PlatformKind kind) {
         if (kind == Kind.Object) {
-            registerRefMap.set(2 * idx);
+            registerRefMap.set(3 * idx);
         } else if (kind == NarrowOopStamp.NarrowOop) {
-            registerRefMap.set(2 * idx);
-            registerRefMap.set(2 * idx + 1);
+            registerRefMap.set(3 * idx);
+            registerRefMap.set(3 * idx + 1);
         }
     }
 
-    public PlatformKind getRegister(int idx) {
-        int refMapIndex = idx * 2;
-        if (registerRefMap.get(refMapIndex)) {
-            if (registerRefMap.get(refMapIndex + 1)) {
-                return NarrowOopStamp.NarrowOop;
-            } else {
-                return Kind.Object;
-            }
-        }
-        return null;
-    }
-
     public void setStackSlot(int offset, PlatformKind kind) {
         int idx = offset / frameSlotSize;
         if (kind == Kind.Object) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Fri Jun 13 11:08:16 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Fri Jun 13 11:11:44 2014 +0200
@@ -379,7 +379,7 @@
     public void setReference(Value location, ReferenceMap refMap) {
         PlatformKind kind = location.getPlatformKind();
         if (isRegister(location)) {
-            refMap.setRegister(asRegister(location).number, kind);
+            refMap.setRegister(asRegister(location).getReferenceMapIndex(), kind);
         } else if (isStackSlot(location)) {
             int offset = offsetForStackSlot(asStackSlot(location));
             refMap.setStackSlot(offset, kind);
--- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java	Fri Jun 13 11:08:16 2014 +0200
+++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java	Fri Jun 13 11:11:44 2014 +0200
@@ -36,7 +36,6 @@
 public class SPARC extends Architecture {
 
     public static final RegisterCategory CPU = new RegisterCategory("CPU");
-    public static final RegisterCategory FPU = new RegisterCategory("FPU");
 
     // General purpose registers
     public static final Register r0 = new Register(0, 0, "g0", CPU);
@@ -123,6 +122,8 @@
     };
     // @formatter:on
 
+    public static final RegisterCategory FPU = new RegisterCategory("FPU", cpuRegisters.length);
+
     // Floating point registers
     public static final Register f0 = new Register(32, 0, "f0", FPU);
     public static final Register f1 = new Register(33, 1, "f1", FPU);
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Fri Jun 13 11:08:16 2014 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Fri Jun 13 11:11:44 2014 +0200
@@ -88,6 +88,26 @@
   return arr->length() * MapWordBits;
 }
 
+static void set_vmreg_oops(OopMap* map, VMReg reg, oop bitset, int idx) {
+  bool is_oop = is_bit_set(bitset, 3 * idx);
+  if (is_oop) {
+    bool narrow1 = is_bit_set(bitset, 3 * idx + 1);
+    bool narrow2 = is_bit_set(bitset, 3 * idx + 2);
+    if (narrow1 || narrow2) {
+      if (narrow1) {
+        map->set_narrowoop(reg);
+      }
+      if (narrow2) {
+        map->set_narrowoop(reg->next());
+      }
+    } else {
+      map->set_oop(reg);
+    }
+  } else {
+    map->set_value(reg);
+  }
+}
+
 // creates a HotSpot oop map out of the byte arrays provided by DebugInfo
 static OopMap* create_oop_map(jint total_frame_size, jint parameter_count, oop debug_info) {
   OopMap* map = new OopMap(total_frame_size, parameter_count);
@@ -98,41 +118,23 @@
 
   if (register_map != NULL) {
     for (jint i = 0; i < RegisterImpl::number_of_registers; i++) {
-      bool is_oop = is_bit_set(register_map, 2 * i);
-      VMReg hotspot_reg = get_hotspot_reg(i);
-      if (is_oop) {
-        if (is_bit_set(register_map, 2 * i + 1)) {
-          map->set_narrowoop(hotspot_reg);
-        } else {
-          map->set_oop(hotspot_reg);
-        }
-      } else {
-        map->set_value(hotspot_reg);
+      set_vmreg_oops(map, as_Register(i)->as_VMReg(), register_map, i);
+    }
+#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), register_map, idx + j);
       }
     }
+#endif
   }
 
   for (jint i = 0; i < bitset_size(frame_map) / 3; i++) {
-    bool is_oop = is_bit_set(frame_map, i * 3);
     // HotSpot stack slots are 4 bytes
     VMReg reg = VMRegImpl::stack2reg(i * VMRegImpl::slots_per_word);
-    if (is_oop) {
-      bool narrow1 = is_bit_set(frame_map, i * 3 + 1);
-      bool narrow2 = is_bit_set(frame_map, i * 3 + 2);
-      if(narrow1 || narrow2) {
-        if(narrow1) {
-          map->set_narrowoop(reg);
-        }
-        if(narrow2) {
-          VMReg reg2 = VMRegImpl::stack2reg(i * VMRegImpl::slots_per_word + 1);
-          map->set_narrowoop(reg2);
-        }
-      } else {
-        map->set_oop(reg);
-      }
-    } else {
-      map->set_value(reg);
-    }
+    set_vmreg_oops(map, reg, frame_map, i);
   }
 
   if (callee_save_info != NULL) {