# HG changeset patch # User Bernhard Urban # Date 1382632467 -7200 # Node ID bc0ed539018f20a921e09ae2c98fc1a33662e2ee # Parent 110c3faa57e92042ebd41fad30b2ca8e30ff07a0 UnsafeArrayCopySnippets: use DirectObjectStoreNode again for kind object. add location identity to DirectObjectStoreNode. diff -r 110c3faa57e9 -r bc0ed539018f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Thu Oct 24 18:31:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Thu Oct 24 18:34:27 2013 +0200 @@ -31,6 +31,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; +import com.oracle.graal.hotspot.phases.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; @@ -38,16 +39,15 @@ import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo; +import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.word.*; /** * As opposed to {@link ArrayCopySnippets}, these Snippets do not perform store checks. */ public class UnsafeArrayCopySnippets implements Snippets { - private static final boolean supportsUnalignedMemoryAccess = runtime().getTarget().arch.supportsUnalignedMemoryAccess(); - // TODO: make vector kind architecture dependent private static final Kind VECTOR_KIND = Kind.Long; private static final long VECTOR_SIZE = arrayIndexScale(VECTOR_KIND); @@ -182,9 +182,30 @@ vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Double, getArrayLocation(Kind.Double)); } + /** + * For this kind, Object, we want to avoid write barriers between writes, but instead have them + * at the end of the snippet. This is done by using {@link DirectObjectStoreNode}, and rely on + * {@link WriteBarrierAdditionPhase} to put write barriers after the {@link UnsafeArrayCopyNode} + * with kind Object. + */ @Snippet public static void arraycopyObject(Object[] src, int srcPos, Object[] dest, int destPos, int length) { - vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Object, getArrayLocation(Kind.Object)); + final int scale = arrayIndexScale(Kind.Object); + int arrayBaseOffset = arrayBaseOffset(Kind.Object); + LocationIdentity arrayLocation = getArrayLocation(Kind.Object); + if (src == dest && srcPos < destPos) { // bad aliased case + long start = (long) (length - 1) * scale; + for (long i = start; i >= 0; i -= scale) { + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, Kind.Object, arrayLocation); + DirectObjectStoreNode.storeObject(dest, arrayBaseOffset, i + (long) destPos * scale, a, getArrayLocation(Kind.Object)); + } + } else { + long end = (long) length * scale; + for (long i = 0; i < end; i += scale) { + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, Kind.Object, arrayLocation); + DirectObjectStoreNode.storeObject(dest, arrayBaseOffset, i + (long) destPos * scale, a, getArrayLocation(Kind.Object)); + } + } } @Snippet diff -r 110c3faa57e9 -r bc0ed539018f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Thu Oct 24 18:31:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Thu Oct 24 18:34:27 2013 +0200 @@ -442,7 +442,7 @@ public static void validateObject(Object parent, Object child) { if (verifyOops() && child != null && !validateOop(VALIDATE_OBJECT, parent, child)) { log(true, "Verification ERROR, Parent: %p Child: %p\n", Word.fromObject(parent).rawValue(), Word.fromObject(child).rawValue()); - DirectObjectStoreNode.storeWord(null, 0, 0, Word.zero()); + DirectObjectStoreNode.storeObject(null, 0, 0, null, LocationIdentity.ANY_LOCATION); } } diff -r 110c3faa57e9 -r bc0ed539018f graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounter.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounter.java Thu Oct 24 18:31:21 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounter.java Thu Oct 24 18:34:27 2013 +0200 @@ -24,13 +24,14 @@ //JaCoCo Exclude -import static com.oracle.graal.graph.FieldIntrospection.*; +import static com.oracle.graal.graph.UnsafeAccess.*; import java.io.*; import java.util.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; -import com.oracle.graal.replacements.Snippet.*; +import com.oracle.graal.replacements.Snippet.Fold; import com.oracle.graal.replacements.nodes.*; /** @@ -133,7 +134,8 @@ */ public void inc() { if (group != null) { - DirectObjectStoreNode.storeLong(this, countOffset(), 0, value + 1); + // TODO: instead of ANY_LOCATION we should actually use the location for the field "value". + DirectObjectStoreNode.storeLong(this, countOffset(), 0, value + 1, LocationIdentity.ANY_LOCATION); } } diff -r 110c3faa57e9 -r bc0ed539018f graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java Thu Oct 24 18:31:21 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java Thu Oct 24 18:34:27 2013 +0200 @@ -22,15 +22,12 @@ */ package com.oracle.graal.replacements.nodes; -import static com.oracle.graal.api.meta.LocationIdentity.*; - import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -import com.oracle.graal.word.*; /** * A special purpose store node that differs from {@link UnsafeStoreNode} in that it is not a @@ -42,30 +39,26 @@ @Input private ValueNode value; @Input private ValueNode offset; private final int displacement; + private final LocationIdentity locationIdentity; - public DirectObjectStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value) { + public DirectObjectStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value, LocationIdentity locationIdentity) { super(StampFactory.forVoid()); this.object = object; this.value = value; this.offset = offset; this.displacement = displacement; + this.locationIdentity = locationIdentity; } @NodeIntrinsic - public static native void storeObject(Object obj, @ConstantNodeParameter int displacement, long offset, Object value); + public static native void storeObject(Object obj, @ConstantNodeParameter int displacement, long offset, Object value, @ConstantNodeParameter LocationIdentity locationIdentity); @NodeIntrinsic - public static native void storeLong(Object obj, @ConstantNodeParameter int displacement, long offset, long value); - - @NodeIntrinsic - public static native void storeWord(Object obj, @ConstantNodeParameter int displacement, long offset, Word value); - - @NodeIntrinsic - public static native void storeInt(Object obj, @ConstantNodeParameter int displacement, long offset, int value); + public static native void storeLong(Object obj, @ConstantNodeParameter int displacement, long offset, long value, @ConstantNodeParameter LocationIdentity locationIdenity); @Override public void lower(LoweringTool tool) { - IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, value.kind(), displacement, offset, graph(), 1); + IndexedLocationNode location = IndexedLocationNode.create(locationIdentity, value.kind(), displacement, offset, graph(), 1); WriteNode write = graph().add(new WriteNode(object, value, location, BarrierType.NONE, value.kind() == Kind.Object)); graph().replaceFixedWithFixed(this, write); }