# HG changeset patch # User Christos Kotselidis # Date 1364510412 -3600 # Node ID 9323ff2fbd1152db4d57f76195898bd6da33c34c # Parent b587343ed1847ae0faa9ed6676e9dd2e8a92ef10 Reverse ArrayCopy WB intrisification diff -r b587343ed184 -r 9323ff2fbd11 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPost.java --- 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 } diff -r b587343ed184 -r 9323ff2fbd11 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java --- 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;