changeset 13726:343541fb3b49

Support narrow oops in reference maps.
author Roland Schatz <roland.schatz@oracle.com>
date Wed, 22 Jan 2014 11:44:27 +0100
parents 8d8732e14447
children 10e6f192631f
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/Architecture.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAILRegisterConfig.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/cpu/x86/vm/graalCodeInstaller_x86.hpp src/share/vm/graal/graalCodeInstaller.cpp
diffstat 12 files changed, 106 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java	Wed Jan 22 11:27:28 2014 +0100
+++ b/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java	Wed Jan 22 11:44:27 2014 +0100
@@ -146,6 +146,7 @@
                 case Short:
                 case Int:
                 case Long:
+                case NarrowOop:
                 case Object:
                     return true;
             }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java	Wed Jan 22 11:27:28 2014 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java	Wed Jan 22 11:44:27 2014 +0100
@@ -223,6 +223,8 @@
                 return 8;
             case Object:
                 return wordSize;
+            case NarrowOop:
+                return wordSize / 2;
             default:
                 return 0;
         }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java	Wed Jan 22 11:27:28 2014 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java	Wed Jan 22 11:44:27 2014 +0100
@@ -31,24 +31,51 @@
 
     private static final long serialVersionUID = -1052183095979496819L;
 
+    /**
+     * Contains 2 bits per 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>
+     * </ul>
+     */
     private final BitSet registerRefMap;
+
+    /**
+     * Contains 3 bits per stack slot.
+     * <ul>
+     * <li>bit0 = 0: contains no references</li>
+     * <li>bit0 = 1, bit1+2 = 0: contains a wide oop</li>
+     * <li>bit0 = 1, bit1 = 1: contains a narrow oop in the lower half</li>
+     * <li>bit0 = 1, bit2 = 1: contains a narrow oop in the upper half</li>
+     * </ul>
+     */
     private final BitSet frameRefMap;
 
     public ReferenceMap(int registerCount, int frameSlotCount) {
         if (registerCount > 0) {
-            this.registerRefMap = new BitSet(registerCount);
+            this.registerRefMap = new BitSet(registerCount * 2);
         } else {
             this.registerRefMap = null;
         }
-        this.frameRefMap = new BitSet(frameSlotCount);
+        this.frameRefMap = new BitSet(frameSlotCount * 3);
     }
 
-    public void setRegister(int idx) {
-        registerRefMap.set(idx);
+    public void setRegister(int idx, boolean narrow) {
+        registerRefMap.set(2 * idx);
+        if (narrow) {
+            registerRefMap.set(2 * idx + 1);
+        }
     }
 
-    public void setStackSlot(int idx) {
-        frameRefMap.set(idx);
+    public void setStackSlot(int idx, boolean narrow1, boolean narrow2) {
+        frameRefMap.set(3 * idx);
+        if (narrow1) {
+            frameRefMap.set(3 * idx + 1);
+        }
+        if (narrow2) {
+            frameRefMap.set(3 * idx + 2);
+        }
     }
 
     public boolean hasRegisterRefMap() {
@@ -76,8 +103,8 @@
             formatter = new NumberedRefMapFormatter();
         }
 
-        for (int reg = registerRefMap.nextSetBit(0); reg >= 0; reg = registerRefMap.nextSetBit(reg + 1)) {
-            sb.append(' ').append(formatter.formatRegister(reg));
+        for (int reg = registerRefMap.nextSetBit(0); reg >= 0; reg = registerRefMap.nextSetBit(reg + 2)) {
+            sb.append(' ').append(formatter.formatRegister(reg / 2));
         }
     }
 
@@ -87,8 +114,8 @@
             formatter = new NumberedRefMapFormatter();
         }
 
-        for (int slot = frameRefMap.nextSetBit(0); slot >= 0; slot = frameRefMap.nextSetBit(slot + 1)) {
-            sb.append(' ').append(formatter.formatStackSlot(slot));
+        for (int slot = frameRefMap.nextSetBit(0); slot >= 0; slot = frameRefMap.nextSetBit(slot + 3)) {
+            sb.append(' ').append(formatter.formatStackSlot(slot / 3));
         }
     }
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Wed Jan 22 11:27:28 2014 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Wed Jan 22 11:44:27 2014 +0100
@@ -159,6 +159,7 @@
             case Double:
                 return asDouble();
             case Object:
+            case NarrowOop:
                 return object;
             case Illegal:
                 return this;
@@ -171,7 +172,7 @@
         if (!ignoreKind && getKind() != other.getKind()) {
             return false;
         }
-        if (getKind() == Kind.Object) {
+        if (getKind() == Kind.Object || getKind() == Kind.NarrowOop) {
             return object == other.object;
         }
         return primitive == other.primitive && getPrimitiveAnnotation() == other.getPrimitiveAnnotation();
@@ -234,12 +235,12 @@
 
     /**
      * Returns the object reference this constant represents. The constant must have kind
-     * {@link Kind#Object}.
+     * {@link Kind#Object} or {@link Kind#NarrowOop}.
      * 
      * @return the constant value
      */
     public Object asObject() {
-        assert getKind() == Kind.Object;
+        assert getKind() == Kind.Object || getKind() == Kind.NarrowOop;
         return object;
     }
 
@@ -249,7 +250,7 @@
      * @return null if this constant is not primitive or has no annotation
      */
     public Object getPrimitiveAnnotation() {
-        return getKind() == Kind.Object ? null : object;
+        return getKind() == Kind.Object || getKind() == Kind.NarrowOop ? null : object;
     }
 
     /**
@@ -259,7 +260,7 @@
      */
     @Override
     public int hashCode() {
-        if (getKind() == Kind.Object) {
+        if (getKind() == Kind.Object || getKind() == Kind.NarrowOop) {
             return System.identityHashCode(object);
         }
         return (int) primitive * getKind().ordinal();
@@ -393,6 +394,16 @@
     }
 
     /**
+     * Creates a boxed narrow oop constant.
+     * 
+     * @param o the object value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static Constant forNarrowOop(Object o) {
+        return new Constant(Kind.NarrowOop, o, 0L);
+    }
+
+    /**
      * Creates an annotated int or long constant. An annotation enables a client to associate some
      * extra semantic or debugging information with a primitive. An annotated primitive constant is
      * never {@linkplain #equals(Object) equal} to a non-annotated constant.
@@ -440,6 +451,8 @@
                 return forDouble((Double) value);
             case Object:
                 return forObject(value);
+            case NarrowOop:
+                return forNarrowOop(value);
             default:
                 throw new RuntimeException("cannot create Constant for boxed " + kind + " value");
         }
@@ -472,6 +485,8 @@
                 return LONG_0;
             case Object:
                 return NULL_OBJECT;
+            case NarrowOop:
+                return forNarrowOop(null);
             default:
                 throw new IllegalArgumentException(kind.toString());
         }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Wed Jan 22 11:27:28 2014 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Wed Jan 22 11:44:27 2014 +0100
@@ -57,6 +57,9 @@
     /** The Object kind, also used for arrays. */
     Object('a', "Object", false, null, null),
 
+    /** The narrow oop kind. */
+    NarrowOop('n', "NarrowOop", false, null, null),
+
     /** The void float kind. */
     Void('v', "void", false, java.lang.Void.TYPE, java.lang.Void.class),
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed Jan 22 11:27:28 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed Jan 22 11:44:27 2014 +0100
@@ -458,7 +458,7 @@
         if (c.getKind() == Kind.Long) {
             return Constant.forIntegerKind(Kind.Int, (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL), c.getPrimitiveAnnotation());
         } else if (c.getKind() == Kind.Object) {
-            return Constant.forIntegerKind(Kind.Int, 0xdeaddead, c.asObject());
+            return Constant.forNarrowOop(c.asObject());
         } else {
             throw GraalInternalError.shouldNotReachHere();
         }
--- a/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java	Wed Jan 22 11:27:28 2014 +0100
+++ b/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java	Wed Jan 22 11:44:27 2014 +0100
@@ -29,7 +29,6 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.Register.RegisterCategory;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
 
 /**
  * Represents the HSAIL architecture.
@@ -166,39 +165,16 @@
         Register reg;
         int encoding = 0;
         String regPrefix = null;
-        String argType = arg.getKind().getJavaName();
-        if (argType.equals("double") || argType.equals("long")) {
+        Kind kind = arg.getKind();
+        if (kind == Kind.Double || kind == Kind.Long) {
             regPrefix = "$d";
-        } else if (argType.equals("int") || argType.equals("float")) {
+        } else if (kind == Kind.Int || kind == Kind.Float || kind == Kind.NarrowOop) {
             regPrefix = "$s";
         } else {
             regPrefix = "$d";
         }
-        switch (argType) {
-            case "float":
-                reg = asFloatReg(arg);
-                encoding = reg.encoding();
-                break;
-            case "int":
-                reg = asIntReg(arg);
-                encoding = reg.encoding();
-                break;
-            case "long":
-                reg = asLongReg(arg);
-                encoding = reg.encoding();
-                break;
-            case "double":
-                reg = asDoubleReg(arg);
-                encoding = reg.encoding();
-                break;
-            case "Object":
-                reg = asObjectReg(arg);
-                encoding = reg.encoding();
-                break;
-            default:
-                GraalInternalError.shouldNotReachHere();
-                break;
-        }
+        reg = asRegister(arg);
+        encoding = reg.encoding();
         return new String(regPrefix + encoding);
     }
 
@@ -217,6 +193,7 @@
                 case Int:
                 case Long:
                 case Object:
+                case NarrowOop:
                     return true;
             }
         } else if (category == FPU) {
--- a/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAILRegisterConfig.java	Wed Jan 22 11:27:28 2014 +0100
+++ b/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAILRegisterConfig.java	Wed Jan 22 11:44:27 2014 +0100
@@ -150,6 +150,7 @@
             case Short:
             case Byte:
             case Float:
+            case NarrowOop:
                 return regBitness32.clone();
             case Long:
             case Double:
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Wed Jan 22 11:27:28 2014 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Wed Jan 22 11:44:27 2014 +0100
@@ -360,12 +360,19 @@
      * @param refMap A reference map, as created by {@link #initReferenceMap(boolean)}.
      */
     public void setReference(Value location, ReferenceMap refMap) {
-        if (location.getKind() == Kind.Object) {
+        Kind kind = location.getKind();
+        if (kind == Kind.Object || kind == Kind.NarrowOop) {
             if (isRegister(location)) {
-                refMap.setRegister(asRegister(location).number);
+                refMap.setRegister(asRegister(location).number, kind == Kind.NarrowOop);
             } else if (isStackSlot(location)) {
-                int index = indexForStackSlot(asStackSlot(location));
-                refMap.setStackSlot(index);
+                if (kind == Kind.NarrowOop) {
+                    int offset = offsetForStackSlot(asStackSlot(location));
+                    assert offset % target.wordSize == 0 || offset % target.wordSize == target.wordSize / 2;
+                    refMap.setStackSlot(offset / target.wordSize, offset % target.wordSize == 0, offset % target.wordSize != 0);
+                } else {
+                    int index = indexForStackSlot(asStackSlot(location));
+                    refMap.setStackSlot(index, false, false);
+                }
             } else {
                 assert isConstant(location);
             }
--- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java	Wed Jan 22 11:27:28 2014 +0100
+++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java	Wed Jan 22 11:44:27 2014 +0100
@@ -162,6 +162,7 @@
                 case Int:
                 case Long:
                 case Object:
+                case NarrowOop:
                     return true;
             }
         } else if (category == FPU) {
--- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp	Wed Jan 22 11:27:28 2014 +0100
+++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp	Wed Jan 22 11:44:27 2014 +0100
@@ -72,9 +72,10 @@
       case 'b':
       case 's':
       case 'c':
+      case 'i':
         fatal("int-sized values not expected in DataPatch");
         break;
-      case 'i': {
+      case 'n': {
         address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand);
         Handle obj = Constant::object(inlineData);
 
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Wed Jan 22 11:27:28 2014 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Wed Jan 22 11:44:27 2014 +0100
@@ -91,22 +91,38 @@
 
   if (register_map != NULL) {
     for (jint i = 0; i < RegisterImpl::number_of_registers; i++) {
-      bool is_oop = is_bit_set(register_map, i);
+      bool is_oop = is_bit_set(register_map, 2 * i);
       VMReg hotspot_reg = get_hotspot_reg(i);
       if (is_oop) {
-        map->set_oop(hotspot_reg);
+        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);
       }
     }
   }
 
-  for (jint i = 0; i < bitset_size(frame_map); i++) {
-    bool is_oop = is_bit_set(frame_map, i);
+  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) {
-      map->set_oop(reg);
+      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);
     }