changeset 8568:9323ff2fbd11

Reverse ArrayCopy WB intrisification
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Thu, 28 Mar 2013 23:40:12 +0100
parents b587343ed184
children 59eb5a38df56
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPost.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java
diffstat 2 files changed, 64 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPost.java	Thu Mar 28 14:30:30 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPost.java	Thu Mar 28 23:40:12 2013 +0100
@@ -22,9 +22,12 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+<<<<<<< local
+=======
 import static com.oracle.graal.hotspot.replacements.HotSpotSnippetUtils.*;
 
 import com.oracle.graal.api.meta.*;
+>>>>>>> other
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
@@ -70,8 +73,17 @@
         this.value = value;
         this.location = location;
         this.precise = precise;
+<<<<<<< local
     }
 
+    public void lower(LoweringTool generator) {
+        generator.getRuntime().lower(this, generator);
+=======
+>>>>>>> other
+    }
+<<<<<<< local
+=======
+
     @Override
     public void lower(LoweringTool generator) {
         StructuredGraph graph = (StructuredGraph) this.graph();
@@ -94,4 +106,5 @@
 
     @NodeIntrinsic
     public static native void arrayCopyWriteBarrier(Object array, Object value, long index);
+>>>>>>> other
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java	Thu Mar 28 14:30:30 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java	Thu Mar 28 23:40:12 2013 +0100
@@ -236,8 +236,9 @@
         }
     }
 
+    // Does NOT perform store checks
     @Snippet
-    private static void arrayObjectCopy(Object src, int srcPos, Object dest, int destPos, int length) {
+    public static void arraycopy(Object[] src, int srcPos, Object[] dest, int destPos, int length) {
         objectCounter.inc();
         checkNonNull(src);
         checkNonNull(dest);
@@ -246,49 +247,62 @@
         int header = arrayBaseOffset(Kind.Object);
         if (src == dest && srcPos < destPos) { // bad aliased case
             long start = (long) (length - 1) * scale;
+<<<<<<< local
+=======
             long j = (long) (length) - 1;
+>>>>>>> other
             for (long i = start; i >= 0; i -= scale) {
                 Object a = UnsafeLoadNode.load(src, header, i + (long) srcPos * scale, Kind.Object);
                 DirectObjectStoreNode.storeObject(dest, header, i + (long) destPos * scale, a);
+<<<<<<< local
+=======
                 WriteBarrierPost.arrayCopyWriteBarrier(dest, a, j);
                 j--;
+>>>>>>> other
             }
         } else {
             long end = (long) length * scale;
+<<<<<<< local
+=======
             long j = srcPos;
+>>>>>>> other
             for (long i = 0; i < end; i += scale) {
                 Object a = UnsafeLoadNode.load(src, header, i + (long) srcPos * scale, Kind.Object);
                 DirectObjectStoreNode.storeObject(dest, header, i + (long) destPos * scale, a);
+<<<<<<< local
+            }
+        }
+        if (length > 0) {
+            int cardShift = cardTableShift();
+            long cardStart = cardTableStart();
+            long dstAddr = GetObjectAddressNode.get(dest);
+            long start = (dstAddr + header + (long) destPos * scale) >>> cardShift;
+            long end = (dstAddr + header + ((long) destPos + length - 1) * scale) >>> cardShift;
+            long count = end - start + 1;
+            while (count-- > 0) {
+                DirectStoreNode.store((start + cardStart) + count, false, Kind.Boolean);
+=======
                 WriteBarrierPost.arrayCopyWriteBarrier(dest, a, j);
                 j++;
+>>>>>>> other
             }
         }
     }
 
-    // Does NOT perform store checks
-    @Snippet
-    public static void arraycopy(Object[] src, int srcPos, Object[] dest, int destPos, int length) {
-        arrayObjectCopy(src, srcPos, dest, destPos, length);
-    }
-
     @Snippet
     public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {
+
+        // loading the hubs also checks for nullness
         Word srcHub = loadHub(src);
         Word destHub = loadHub(dest);
+
         int layoutHelper = checkArrayType(srcHub);
-        int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask();
-        final boolean isObjectArray = ((layoutHelper & layoutHelperElementTypePrimitiveInPlace()) == 0);
         if (srcHub.equal(destHub) && src != dest) {
             probability(FAST_PATH_PROBABILITY);
+
             checkLimits(src, srcPos, dest, destPos, length);
-            if (isObjectArray) {
-                genericObjectExactCallCounter.inc();
-                probability(FAST_PATH_PROBABILITY);
-                arrayObjectCopy(src, srcPos, dest, destPos, length);
-            } else {
-                genericPrimitiveCallCounter.inc();
-                arraycopyInnerloop(src, srcPos, dest, destPos, length, layoutHelper);
-            }
+
+            arraycopyInnerloop(src, srcPos, dest, destPos, length, layoutHelper);
         } else {
             genericObjectCallCounter.inc();
             System.arraycopy(src, srcPos, dest, destPos, length);
@@ -316,11 +330,29 @@
             srcOffset = srcOffset.add(1);
         }
         while (destOffset.belowThan(destEnd)) {
-            Word word = srcOffset.readWord(0, UNKNOWN_LOCATION);
-            destOffset.writeWord(0, word, ANY_LOCATION);
+            destOffset.writeWord(0, srcOffset.readWord(0, UNKNOWN_LOCATION), ANY_LOCATION);
             destOffset = destOffset.add(wordSize());
             srcOffset = srcOffset.add(wordSize());
         }
+
+        if ((layoutHelper & layoutHelperElementTypePrimitiveInPlace()) != 0) {
+            genericPrimitiveCallCounter.inc();
+
+        } else {
+            probability(LIKELY_PROBABILITY);
+            genericObjectExactCallCounter.inc();
+
+            if (length > 0) {
+                int cardShift = cardTableShift();
+                long cardStart = cardTableStart();
+                Word destCardOffset = destStart.unsignedShiftRight(cardShift).add(Word.unsigned(cardStart));
+                Word destCardEnd = destEnd.subtract(1).unsignedShiftRight(cardShift).add(Word.unsigned(cardStart));
+                while (destCardOffset.belowOrEqual(destCardEnd)) {
+                    DirectStoreNode.store(destCardOffset.rawValue(), false, Kind.Boolean);
+                    destCardOffset = destCardOffset.add(1);
+                }
+            }
+        }
     }
 
     private static final SnippetCounter.Group checkCounters = GraalOptions.SnippetCounters ? new SnippetCounter.Group("System.arraycopy checkInputs") : null;