changeset 5456:a5e43a18ac52

added computation of array base offset and index scaling into CiKind and used it to remove a hard coded assumption in canonicalization of LoadIndexedNode
author Doug Simon <doug.simon@oracle.com>
date Wed, 30 May 2012 18:34:11 +0200
parents 271e83dcfcef
children 87dfecd51e71
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiKind.java
diffstat 3 files changed, 89 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java	Wed May 30 18:07:38 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java	Wed May 30 18:34:11 2012 +0200
@@ -221,18 +221,19 @@
         if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) {
             throw new IndexOutOfBoundsException();
         }
+        final int scale = arrayIndexScale(CiKind.Object);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            copyObjectsDown(src, srcPos * 8L, dest, destPos * 8L, length);
+            copyObjectsDown(src, srcPos * scale, dest, destPos * scale, length);
         } else {
-            copyObjectsUp(src, srcPos * 8L, dest, destPos * 8L, length);
+            copyObjectsUp(src, srcPos * scale, dest, destPos * scale, length);
         }
         if (length > 0) {
-            int header = arrayHeaderSizeFor(CiKind.Object);
+            int header = arrayBaseOffset(CiKind.Object);
             int cardShift = cardTableShift();
             long cardStart = cardTableStart();
             long dstAddr = GetObjectAddressNode.get(dest);
-            long start = (dstAddr + header + destPos * 8L) >>> cardShift;
-            long end = (dstAddr + header + (destPos + length - 1) * 8L) >>> cardShift;
+            long start = (dstAddr + header + destPos * scale) >>> cardShift;
+            long end = (dstAddr + header + (destPos + length - 1) * scale) >>> cardShift;
             long count = end - start + 1;
             while (count-- > 0) {
                 DirectStoreNode.store((start + cardStart) + count, false);
@@ -242,7 +243,7 @@
 
     @Snippet
     public static void copyBytesDown(Object src, int srcPos, Object dest, int destPos, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Byte);
+        int header = arrayBaseOffset(CiKind.Byte);
         for (long i = length - 1; i >= 0; i--) {
             Byte a = UnsafeLoadNode.load(src, header, i + srcPos, CiKind.Byte);
             UnsafeStoreNode.store(dest, header, i + destPos, a.byteValue(), CiKind.Byte);
@@ -251,7 +252,7 @@
 
     @Snippet
     public static void copyShortsDown(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Short);
+        int header = arrayBaseOffset(CiKind.Short);
         for (long i = (length - 1) * 2; i >= 0; i -= 2) {
             Character a = UnsafeLoadNode.load(src, header, i + srcOffset, CiKind.Short);
             UnsafeStoreNode.store(dest, header, i + destOffset, a.charValue(), CiKind.Short);
@@ -260,7 +261,7 @@
 
     @Snippet
     public static void copyIntsDown(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Int);
+        int header = arrayBaseOffset(CiKind.Int);
         for (long i = (length - 1) * 4; i >= 0; i -= 4) {
             Integer a = UnsafeLoadNode.load(src, header, i + srcOffset, CiKind.Int);
             UnsafeStoreNode.store(dest, header, i + destOffset, a.intValue(), CiKind.Int);
@@ -269,7 +270,7 @@
 
     @Snippet
     public static void copyLongsDown(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Long);
+        int header = arrayBaseOffset(CiKind.Long);
         for (long i = (length - 1) * 8; i >= 0; i -= 8) {
             Long a = UnsafeLoadNode.load(src, header, i + srcOffset, CiKind.Long);
             UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), CiKind.Long);
@@ -279,8 +280,9 @@
     // Does NOT perform store checks
     @Snippet
     public static void copyObjectsDown(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Object);
-        for (long i = (length - 1) * wordSize(); i >= 0; i -= wordSize()) {
+        int header = arrayBaseOffset(CiKind.Object);
+        final int scale = arrayIndexScale(CiKind.Object);
+        for (long i = (length - 1) * scale; i >= 0; i -= scale) {
             Object a = UnsafeLoadNode.load(src, header, i + srcOffset, CiKind.Object);
             DirectObjectStoreNode.store(dest, header, i + destOffset, a);
         }
@@ -295,7 +297,7 @@
      */
     @Snippet
     public static void copyBytesUp(Object src, int srcPos, Object dest, int destPos, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Byte);
+        int header = arrayBaseOffset(CiKind.Byte);
         for (long i = 0; i < length; i++) {
             Byte a = UnsafeLoadNode.load(src, header, i + srcPos, CiKind.Byte);
             UnsafeStoreNode.store(dest, header, i + destPos, a.byteValue(), CiKind.Byte);
@@ -312,7 +314,7 @@
      */
     @Snippet
     public static void copyShortsUp(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Short);
+        int header = arrayBaseOffset(CiKind.Short);
         for (long i = 0; i < length * 2L; i += 2) {
             Character a = UnsafeLoadNode.load(src, header, i + srcOffset, CiKind.Short);
             UnsafeStoreNode.store(dest, header, i + destOffset, a.charValue(), CiKind.Short);
@@ -321,7 +323,7 @@
 
     @Snippet
     public static void copyIntsUp(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Int);
+        int header = arrayBaseOffset(CiKind.Int);
         for (long i = 0; i < length * 4L; i += 4) {
             Integer a = UnsafeLoadNode.load(src, header, i + srcOffset, CiKind.Int);
             UnsafeStoreNode.store(dest, header, i + destOffset, a.intValue(), CiKind.Int);
@@ -330,7 +332,7 @@
 
     @Snippet
     public static void copyLongsUp(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Long);
+        int header = arrayBaseOffset(CiKind.Long);
         for (long i = 0; i < length * 8L; i += 8) {
             Long a = UnsafeLoadNode.load(src, header, i + srcOffset, CiKind.Long);
             UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), CiKind.Long);
@@ -340,20 +342,33 @@
     // Does NOT perform store checks
     @Snippet
     public static void copyObjectsUp(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Object);
-        for (long i = 0; i < length * wordSize(); i += wordSize()) {
+        int header = arrayBaseOffset(CiKind.Object);
+        final int scale = arrayIndexScale(CiKind.Object);
+        for (long i = 0; i < length * scale; i += scale) {
             Object a = UnsafeLoadNode.load(src, header, i + srcOffset, CiKind.Object);
             DirectObjectStoreNode.store(dest, header, i + destOffset, a);
         }
     }
+
     @Fold
-    private static int wordSize() {
-        return CompilerImpl.getInstance().getTarget().wordSize;
+    static int arrayBaseOffset(CiKind elementKind) {
+        return elementKind.arrayBaseOffset();
     }
 
     @Fold
-    static int arrayHeaderSizeFor(CiKind elementKind) {
-        return CompilerImpl.getInstance().getConfig().getArrayOffset(elementKind);
+    static int arrayIndexScale(CiKind elementKind) {
+        return elementKind.arrayIndexScale();
+    }
+
+    static {
+        assert arrayIndexScale(CiKind.Byte) == 1;
+        assert arrayIndexScale(CiKind.Boolean) == 1;
+        assert arrayIndexScale(CiKind.Char) == 2;
+        assert arrayIndexScale(CiKind.Short) == 2;
+        assert arrayIndexScale(CiKind.Int) == 4;
+        assert arrayIndexScale(CiKind.Long) == 8;
+        assert arrayIndexScale(CiKind.Float) == 4;
+        assert arrayIndexScale(CiKind.Double) == 8;
     }
 
     @Fold
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Wed May 30 18:07:38 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Wed May 30 18:34:11 2012 +0200
@@ -24,8 +24,6 @@
 
 import java.lang.reflect.*;
 
-import sun.misc.*;
-
 import com.oracle.graal.cri.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -71,7 +69,7 @@
                 int length = Array.getLength(array);
                 if (index >= 0 && index < length) {
                     return ConstantNode.forCiConstant(elementKind().readUnsafeConstant(array,
-                                    Unsafe.ARRAY_OBJECT_BASE_OFFSET + index * Unsafe.ARRAY_OBJECT_INDEX_SCALE), tool.runtime(), graph());
+                                    elementKind().arrayBaseOffset() + index * elementKind().arrayIndexScale()), tool.runtime(), graph());
                 }
             }
         }
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiKind.java	Wed May 30 18:07:38 2012 +0200
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiKind.java	Wed May 30 18:34:11 2012 +0200
@@ -344,6 +344,58 @@
         return Character.toUpperCase(typeChar);
     }
 
+    public final int arrayBaseOffset() {
+        switch(this) {
+            case Boolean:
+                return Unsafe.ARRAY_BOOLEAN_BASE_OFFSET;
+            case Byte:
+                return Unsafe.ARRAY_BYTE_BASE_OFFSET;
+            case Char:
+                return Unsafe.ARRAY_CHAR_BASE_OFFSET;
+            case Short:
+                return Unsafe.ARRAY_SHORT_BASE_OFFSET;
+            case Int:
+                return Unsafe.ARRAY_INT_BASE_OFFSET;
+            case Long:
+                return Unsafe.ARRAY_LONG_BASE_OFFSET;
+            case Float:
+                return Unsafe.ARRAY_FLOAT_BASE_OFFSET;
+            case Double:
+                return Unsafe.ARRAY_DOUBLE_BASE_OFFSET;
+            case Object:
+                return Unsafe.ARRAY_OBJECT_BASE_OFFSET;
+            default:
+                assert false : "unexpected kind: " + this;
+                return -1;
+        }
+    }
+
+    public final int arrayIndexScale() {
+        switch(this) {
+            case Boolean:
+                return Unsafe.ARRAY_BOOLEAN_INDEX_SCALE;
+            case Byte:
+                return Unsafe.ARRAY_BYTE_INDEX_SCALE;
+            case Char:
+                return Unsafe.ARRAY_CHAR_INDEX_SCALE;
+            case Short:
+                return Unsafe.ARRAY_SHORT_INDEX_SCALE;
+            case Int:
+                return Unsafe.ARRAY_INT_INDEX_SCALE;
+            case Long:
+                return Unsafe.ARRAY_LONG_INDEX_SCALE;
+            case Float:
+                return Unsafe.ARRAY_FLOAT_INDEX_SCALE;
+            case Double:
+                return Unsafe.ARRAY_DOUBLE_INDEX_SCALE;
+            case Object:
+                return Unsafe.ARRAY_OBJECT_INDEX_SCALE;
+            default:
+                assert false : "unexpected kind: " + this;
+                return -1;
+        }
+    }
+
     public CiConstant readUnsafeConstant(Object value, long displacement) {
         assert value != null;
         Unsafe u = Unsafe.getUnsafe();