changeset 5740:98325620b7e2

Array copies must be element atomic
author Gilles Duboscq <duboscq@ssw.jku.at>
date Mon, 02 Jul 2012 15:08:05 +0200
parents e1d5c642d022
children c84c75339af1
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java
diffstat 1 files changed, 33 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java	Thu Jun 28 17:39:06 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java	Mon Jul 02 15:08:05 2012 +0200
@@ -117,9 +117,9 @@
         long srcOffset = srcPos * arrayIndexScale(baseKind);
         long destOffset = destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i--) {
-                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
-                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i -= arrayIndexScale(Kind.Char)) {
+                Character a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Char);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.charValue(), Kind.Char);
             }
             long vectorLength = byteLength - nonVectorBytes;
             for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
@@ -127,9 +127,9 @@
                 UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
             }
         } else {
-            for (long i = 0; i < nonVectorBytes; i++) {
-                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
-                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            for (long i = 0; i < nonVectorBytes; i += arrayIndexScale(Kind.Char)) {
+                Character a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Char);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.charValue(), Kind.Char);
             }
             for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) {
                 Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
@@ -153,9 +153,9 @@
         long srcOffset = srcPos * arrayIndexScale(baseKind);
         long destOffset = destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i--) {
-                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
-                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i -= arrayIndexScale(Kind.Short)) {
+                Short a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Short);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.shortValue(), Kind.Short);
             }
             long vectorLength = byteLength - nonVectorBytes;
             for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
@@ -163,9 +163,9 @@
                 UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
             }
         } else {
-            for (long i = 0; i < nonVectorBytes; i++) {
-                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
-                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            for (long i = 0; i < nonVectorBytes; i += arrayIndexScale(Kind.Short)) {
+                Short a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Short);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.shortValue(), Kind.Short);
             }
             for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) {
                 Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
@@ -189,9 +189,9 @@
         long srcOffset = srcPos * arrayIndexScale(baseKind);
         long destOffset = destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i--) {
-                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
-                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i -= arrayIndexScale(Kind.Int)) {
+                Integer a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Int);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.intValue(), Kind.Int);
             }
             long vectorLength = byteLength - nonVectorBytes;
             for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
@@ -199,9 +199,9 @@
                 UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
             }
         } else {
-            for (long i = 0; i < nonVectorBytes; i++) {
-                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
-                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            for (long i = 0; i < nonVectorBytes; i += arrayIndexScale(Kind.Int)) {
+                Integer a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Int);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.intValue(), Kind.Int);
             }
             for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) {
                 Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
@@ -225,9 +225,9 @@
         long srcOffset = srcPos * arrayIndexScale(baseKind);
         long destOffset = destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i--) {
-                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
-                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i -= arrayIndexScale(Kind.Float)) {
+                Float a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Float);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.floatValue(), Kind.Float);
             }
             long vectorLength = byteLength - nonVectorBytes;
             for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
@@ -235,9 +235,9 @@
                 UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
             }
         } else {
-            for (long i = 0; i < nonVectorBytes; i++) {
-                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
-                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            for (long i = 0; i < nonVectorBytes; i += arrayIndexScale(Kind.Float)) {
+                Float a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Float);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.floatValue(), Kind.Float);
             }
             for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) {
                 Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
@@ -308,13 +308,19 @@
             throw new IndexOutOfBoundsException();
         }
         final int scale = arrayIndexScale(Kind.Object);
+        int header = arrayBaseOffset(Kind.Object);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            copyObjectsDown(src, srcPos * scale, dest, destPos * scale, length);
+            for (long i = (length - 1) * scale; i >= 0; i -= scale) {
+                Object a = UnsafeLoadNode.load(src, header, i + (long) srcPos * scale, Kind.Object);
+                DirectObjectStoreNode.store(dest, header, i + (long) destPos * scale, a);
+            }
         } else {
-            copyObjectsUp(src, srcPos * scale, dest, destPos * scale, length);
+            for (long i = 0; i < length * scale; i += scale) {
+                Object a = UnsafeLoadNode.load(src, header, i + (long) srcPos * scale, Kind.Object);
+                DirectObjectStoreNode.store(dest, header, i + (long) destPos * scale, a);
+            }
         }
         if (length > 0) {
-            int header = arrayBaseOffset(Kind.Object);
             int cardShift = cardTableShift();
             long cardStart = cardTableStart();
             long dstAddr = GetObjectAddressNode.get(dest);
@@ -327,28 +333,6 @@
         }
     }
 
-    // Does NOT perform store checks
-    @Snippet
-    public static void copyObjectsDown(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayBaseOffset(Kind.Object);
-        final int scale = arrayIndexScale(Kind.Object);
-        for (long i = (length - 1) * scale; i >= 0; i -= scale) {
-            Object a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Object);
-            DirectObjectStoreNode.store(dest, header, i + destOffset, a);
-        }
-    }
-
-    // Does NOT perform store checks
-    @Snippet
-    public static void copyObjectsUp(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayBaseOffset(Kind.Object);
-        final int scale = arrayIndexScale(Kind.Object);
-        for (long i = 0; i < length * scale; i += scale) {
-            Object a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Object);
-            DirectObjectStoreNode.store(dest, header, i + destOffset, a);
-        }
-    }
-
     @Fold
     static int arrayBaseOffset(Kind elementKind) {
         return elementKind.arrayBaseOffset();