# HG changeset patch # User Doug Simon # Date 1371755466 -7200 # Node ID 6447890af1bf4832457adbffe7301a2a4f6dd333 # Parent 7a0d4d95f84cf27f4106149340669c78ea2cc228# Parent b724895db5c02a23e6dc12cb975c1095eb99d81f Merge. diff -r 7a0d4d95f84c -r 6447890af1bf graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Thu Jun 20 17:38:53 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Thu Jun 20 21:11:06 2013 +0200 @@ -37,5 +37,7 @@ appendPhase(new ExpandLogicPhase()); appendPhase(new DeadCodeEliminationPhase()); + + appendPhase(new RemoveValueProxyPhase()); } } diff -r 7a0d4d95f84c -r 6447890af1bf graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Jun 20 17:38:53 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Jun 20 21:11:06 2013 +0200 @@ -51,6 +51,8 @@ import static com.oracle.graal.phases.GraalOptions.*; import static com.oracle.graal.replacements.Log.*; import static com.oracle.graal.replacements.MathSubstitutionsX86.*; +import static com.oracle.graal.hotspot.nodes.G1PostWriteBarrierStubCall.*; +import static com.oracle.graal.hotspot.nodes.G1PreWriteBarrierStubCall.*; import java.lang.reflect.*; import java.util.*; @@ -294,7 +296,8 @@ linkForeignCall(r, THREAD_IS_INTERRUPTED, c.threadIsInterruptedAddress, PREPEND_THREAD, NOT_REEXECUTABLE, ANY_LOCATION); linkForeignCall(r, VM_ERROR, c.vmErrorAddress, PREPEND_THREAD, REEXECUTABLE, NO_LOCATIONS); linkForeignCall(r, OSR_MIGRATION_END, c.osrMigrationEndAddress, DONT_PREPEND_THREAD, NOT_REEXECUTABLE, NO_LOCATIONS); - + linkForeignCall(r, G1WBPRECALL, c.writeBarrierPreAddress, PREPEND_THREAD, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(r, G1WBPOSTCALL, c.writeBarrierPostAddress, PREPEND_THREAD, REEXECUTABLE, NO_LOCATIONS); if (IntrinsifyObjectMethods.getValue()) { r.registerSubstitutions(ObjectSubstitutions.class); } @@ -325,6 +328,8 @@ writeBarrierSnippets = new WriteBarrierSnippets.Templates(this, r, graalRuntime.getTarget()); boxingSnippets = new BoxingSnippets.Templates(this, r, graalRuntime.getTarget()); exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(this, r, graalRuntime.getTarget()); + + r.registerSnippetTemplateCache(new UnsafeArrayCopySnippets.Templates(this, r, graalRuntime.getTarget())); } public HotSpotGraalRuntime getGraalRuntime() { diff -r 7a0d4d95f84c -r 6447890af1bf graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PostWriteBarrierStubCall.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PostWriteBarrierStubCall.java Thu Jun 20 21:11:06 2013 +0200 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.nodes; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.word.*; + +public class G1PostWriteBarrierStubCall extends DeoptimizingStubCall implements LIRGenLowerable { + + @Input private ValueNode cardAddress; + public static final ForeignCallDescriptor G1WBPOSTCALL = new ForeignCallDescriptor("write_barrier_post", void.class, Word.class); + + public G1PostWriteBarrierStubCall(ValueNode cardAddress) { + super(StampFactory.forVoid()); + this.cardAddress = cardAddress; + } + + @Override + public void generate(LIRGenerator gen) { + ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(G1PostWriteBarrierStubCall.G1WBPOSTCALL); + gen.emitForeignCall(linkage, this, gen.operand(cardAddress)); + } + + @NodeIntrinsic + public static native void call(Word cardAddress); +} diff -r 7a0d4d95f84c -r 6447890af1bf graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrierStubCall.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrierStubCall.java Thu Jun 20 21:11:06 2013 +0200 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.nodes; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; + +public class G1PreWriteBarrierStubCall extends DeoptimizingStubCall implements LIRGenLowerable { + + @Input private ValueNode object; + public static final ForeignCallDescriptor G1WBPRECALL = new ForeignCallDescriptor("write_barrier_pre", void.class, Object.class); + + public G1PreWriteBarrierStubCall(ValueNode object) { + super(StampFactory.forVoid()); + this.object = object; + } + + @Override + public void generate(LIRGenerator gen) { + ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(G1PreWriteBarrierStubCall.G1WBPRECALL); + gen.emitForeignCall(linkage, this, gen.operand(object)); + } + + @NodeIntrinsic + public static native void call(Object hub); +} diff -r 7a0d4d95f84c -r 6447890af1bf graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Thu Jun 20 17:38:53 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Thu Jun 20 21:11:06 2013 +0200 @@ -41,8 +41,10 @@ for (CompareAndSwapNode node : graph.getNodes(CompareAndSwapNode.class)) { addCASBarriers(node, graph); } - for (GenericArrayRangeWriteBarrier node : graph.getNodes(GenericArrayRangeWriteBarrier.class)) { - addArrayRangeBarriers(node, graph); + for (ArrayRangeWriteNode node : graph.getNodes(ArrayRangeWriteNode.class)) { + if (node.isObjectArray()) { + addArrayRangeBarriers(node, graph); + } } } @@ -69,9 +71,9 @@ } } - private static void addArrayRangeBarriers(GenericArrayRangeWriteBarrier node, StructuredGraph graph) { - SerialArrayRangeWriteBarrier serialArrayRangeWriteBarrier = graph.add(new SerialArrayRangeWriteBarrier(node.getDstObject(), node.getDstPos(), node.getLength())); - graph.replaceFixedWithFixed(node, serialArrayRangeWriteBarrier); + private static void addArrayRangeBarriers(ArrayRangeWriteNode node, StructuredGraph graph) { + SerialArrayRangeWriteBarrier serialArrayRangeWriteBarrier = graph.add(new SerialArrayRangeWriteBarrier(node.getArray(), node.getIndex(), node.getLength())); + graph.addAfterFixed(node, serialArrayRangeWriteBarrier); } } diff -r 7a0d4d95f84c -r 6447890af1bf 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 Jun 20 17:38:53 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Thu Jun 20 21:11:06 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,35 +76,11 @@ private static final Kind VECTOR_KIND = Kind.Long; private static final long VECTOR_SIZE = arrayIndexScale(Kind.Long); - private static void vectorizedCopy(Object src, int srcPos, Object dest, int destPos, int length, Kind baseKind) { + private static void checkedCopy(Object src, int srcPos, Object dest, int destPos, int length, Kind baseKind) { checkNonNull(src); checkNonNull(dest); checkLimits(src, srcPos, dest, destPos, length); - int header = arrayBaseOffset(baseKind); - int elementSize = arrayIndexScale(baseKind); - long byteLength = (long) length * elementSize; - long nonVectorBytes = byteLength % VECTOR_SIZE; - long srcOffset = (long) srcPos * elementSize; - long destOffset = (long) destPos * elementSize; - if (probability(NOT_FREQUENT_PROBABILITY, src == dest) && probability(NOT_FREQUENT_PROBABILITY, srcPos < destPos)) { - // bad aliased case - for (long i = byteLength - elementSize; i >= byteLength - nonVectorBytes; i -= elementSize) { - UnsafeStoreNode.store(dest, header, i + destOffset, UnsafeLoadNode.load(src, header, i + srcOffset, baseKind), baseKind); - } - long vectorLength = byteLength - nonVectorBytes; - for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); - } - } else { - for (long i = 0; i < nonVectorBytes; i += elementSize) { - UnsafeStoreNode.store(dest, header, i + destOffset, UnsafeLoadNode.load(src, header, i + srcOffset, baseKind), baseKind); - } - for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); - } - } + UnsafeArrayCopyNode.arraycopy(src, srcPos, dest, destPos, length, baseKind); } public static void checkNonNull(Object obj) { @@ -149,85 +125,49 @@ @Snippet public static void arraycopy(byte[] src, int srcPos, byte[] dest, int destPos, int length) { byteCounter.inc(); - vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Byte); + checkedCopy(src, srcPos, dest, destPos, length, Kind.Byte); } @Snippet public static void arraycopy(boolean[] src, int srcPos, boolean[] dest, int destPos, int length) { booleanCounter.inc(); - vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Byte); + checkedCopy(src, srcPos, dest, destPos, length, Kind.Boolean); } @Snippet public static void arraycopy(char[] src, int srcPos, char[] dest, int destPos, int length) { charCounter.inc(); - vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Char); + checkedCopy(src, srcPos, dest, destPos, length, Kind.Char); } @Snippet public static void arraycopy(short[] src, int srcPos, short[] dest, int destPos, int length) { shortCounter.inc(); - vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Short); + checkedCopy(src, srcPos, dest, destPos, length, Kind.Short); } @Snippet public static void arraycopy(int[] src, int srcPos, int[] dest, int destPos, int length) { intCounter.inc(); - vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Int); + checkedCopy(src, srcPos, dest, destPos, length, Kind.Int); } @Snippet public static void arraycopy(float[] src, int srcPos, float[] dest, int destPos, int length) { floatCounter.inc(); - vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Float); + checkedCopy(src, srcPos, dest, destPos, length, Kind.Float); } @Snippet public static void arraycopy(long[] src, int srcPos, long[] dest, int destPos, int length) { longCounter.inc(); - checkNonNull(src); - checkNonNull(dest); - checkLimits(src, srcPos, dest, destPos, length); - Kind baseKind = Kind.Long; - int header = arrayBaseOffset(baseKind); - long byteLength = (long) length * arrayIndexScale(baseKind); - long srcOffset = (long) srcPos * arrayIndexScale(baseKind); - long destOffset = (long) destPos * arrayIndexScale(baseKind); - if (src == dest && srcPos < destPos) { // bad aliased case - for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); - } - } else { - for (long i = 0; i < byteLength; i += VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); - } - } + checkedCopy(src, srcPos, dest, destPos, length, Kind.Long); } @Snippet public static void arraycopy(double[] src, int srcPos, double[] dest, int destPos, int length) { doubleCounter.inc(); - checkNonNull(src); - checkNonNull(dest); - checkLimits(src, srcPos, dest, destPos, length); - Kind baseKind = Kind.Double; - int header = arrayBaseOffset(baseKind); - long byteLength = (long) length * arrayIndexScale(baseKind); - long srcOffset = (long) srcPos * arrayIndexScale(baseKind); - long destOffset = (long) destPos * arrayIndexScale(baseKind); - if (src == dest && srcPos < destPos) { // bad aliased case - for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); - } - } else { - for (long i = 0; i < byteLength; i += VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); - } - } + checkedCopy(src, srcPos, dest, destPos, length, Kind.Double); } @Snippet @@ -239,48 +179,25 @@ @Snippet public static void arrayObjectCopy(Object src, int srcPos, Object dest, int destPos, int length) { objectCounter.inc(); - checkNonNull(src); - checkNonNull(dest); - checkLimits(src, srcPos, dest, destPos, length); - final int scale = arrayIndexScale(Kind.Object); - int header = arrayBaseOffset(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, header, i + (long) srcPos * scale, Kind.Object); - DirectObjectStoreNode.storeObject(dest, header, i + (long) destPos * scale, a); - } - } else { - long end = (long) length * scale; - 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); - - } - } - if (length > 0) { - GenericArrayRangeWriteBarrier.insertWriteBarrier(dest, destPos, length); - } + checkedCopy(src, srcPos, dest, destPos, length, Kind.Object); } @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 (probability(FAST_PATH_PROBABILITY, srcHub.equal(destHub)) && probability(FAST_PATH_PROBABILITY, src != dest)) { + int layoutHelper = checkArrayType(srcHub); + final boolean isObjectArray = ((layoutHelper & layoutHelperElementTypePrimitiveInPlace()) == 0); - if (probability(FAST_PATH_PROBABILITY, srcHub.equal(destHub)) && probability(FAST_PATH_PROBABILITY, src != dest)) { checkLimits(src, srcPos, dest, destPos, length); if (probability(FAST_PATH_PROBABILITY, isObjectArray)) { genericObjectExactCallCounter.inc(); arrayObjectCopy(src, srcPos, dest, destPos, length); } else { genericPrimitiveCallCounter.inc(); - arraycopyInnerloop(src, srcPos, dest, destPos, length, layoutHelper); + UnsafeArrayCopyNode.arraycopyPrimitive(src, srcPos, dest, destPos, length, layoutHelper); } } else { genericObjectCallCounter.inc(); @@ -288,33 +205,6 @@ } } - public static void arraycopyInnerloop(Object src, int srcPos, Object dest, int destPos, int length, int layoutHelper) { - int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask(); - int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask(); - - Word memory = (Word) Word.fromObject(src); - - Word srcOffset = (Word) Word.fromObject(src).add(headerSize).add(srcPos << log2ElementSize); - Word destOffset = (Word) Word.fromObject(dest).add(headerSize).add(destPos << log2ElementSize); - Word destStart = destOffset; - long sizeInBytes = ((long) length) << log2ElementSize; - Word destEnd = destOffset.add(Word.unsigned(length).shiftLeft(log2ElementSize)); - - int nonVectorBytes = (int) (sizeInBytes % VECTOR_SIZE); - Word destNonVectorEnd = destStart.add(nonVectorBytes); - - while (destOffset.belowThan(destNonVectorEnd)) { - destOffset.writeByte(0, srcOffset.readByte(0, ANY_LOCATION), ANY_LOCATION); - destOffset = destOffset.add(1); - srcOffset = srcOffset.add(1); - } - while (destOffset.belowThan(destEnd)) { - destOffset.writeWord(0, srcOffset.readWord(0, ANY_LOCATION), ANY_LOCATION); - destOffset = destOffset.add(wordSize()); - srcOffset = srcOffset.add(wordSize()); - } - } - private static final SnippetCounter.Group checkCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("System.arraycopy checkInputs") : null; private static final SnippetCounter checkSuccessCounter = new SnippetCounter(checkCounters, "checkSuccess", "checkSuccess"); private static final SnippetCounter checkNPECounter = new SnippetCounter(checkCounters, "checkNPE", "checkNPE"); diff -r 7a0d4d95f84c -r 6447890af1bf graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopyNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopyNode.java Thu Jun 20 21:11:06 2013 +0200 @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.replacements; + +import static com.oracle.graal.api.meta.LocationIdentity.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.replacements.SnippetTemplate.Arguments; + +public final class UnsafeArrayCopyNode extends ArrayRangeWriteNode implements Lowerable, MemoryCheckpoint.Single { + + @Input private ValueNode src; + @Input private ValueNode srcPos; + @Input private ValueNode dest; + @Input private ValueNode destPos; + @Input private ValueNode length; + @Input private ValueNode layoutHelper; + + private Kind elementKind; + + private UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode layoutHelper, Kind elementKind) { + super(StampFactory.forVoid()); + assert layoutHelper == null || elementKind == null; + this.src = src; + this.srcPos = srcPos; + this.dest = dest; + this.destPos = destPos; + this.length = length; + this.layoutHelper = layoutHelper; + this.elementKind = elementKind; + } + + private UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, Kind elementKind) { + this(src, srcPos, dest, destPos, length, null, elementKind); + } + + private UnsafeArrayCopyNode(ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length, ValueNode layoutHelper) { + this(src, srcPos, dest, destPos, length, layoutHelper, null); + } + + @Override + public ValueNode getArray() { + return dest; + } + + @Override + public ValueNode getIndex() { + return destPos; + } + + @Override + public ValueNode getLength() { + return length; + } + + @Override + public boolean isObjectArray() { + return elementKind == Kind.Object; + } + + public Kind getElementKind() { + return elementKind; + } + + @Override + public void lower(LoweringTool tool, LoweringType loweringType) { + if (loweringType == LoweringType.AFTER_GUARDS) { + UnsafeArrayCopySnippets.Templates templates = tool.getReplacements().getSnippetTemplateCache(UnsafeArrayCopySnippets.Templates.class); + templates.lower(this); + } + } + + public void addSnippetArguments(Arguments args) { + args.add("src", src); + args.add("srcPos", srcPos); + args.add("dest", dest); + args.add("destPos", destPos); + args.add("length", length); + if (layoutHelper != null) { + args.add("layoutHelper", layoutHelper); + } + } + + @Override + public LocationIdentity getLocationIdentity() { + if (elementKind == null) { + return ANY_LOCATION; + } else { + return NamedLocationIdentity.getArrayLocation(elementKind); + } + } + + @NodeIntrinsic + public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length, @ConstantNodeParameter Kind elementKind); + + @NodeIntrinsic + public static native void arraycopyPrimitive(Object src, int srcPos, Object dest, int destPos, int length, int layoutHelper); +} diff -r 7a0d4d95f84c -r 6447890af1bf graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Thu Jun 20 21:11:06 2013 +0200 @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.replacements; + +import static com.oracle.graal.api.meta.LocationIdentity.*; +import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.replacements.SnippetTemplate.*; +import static com.oracle.graal.replacements.nodes.BranchProbabilityNode.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.replacements.*; +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.*; + +public class UnsafeArrayCopySnippets implements Snippets { + + private static final Kind VECTOR_KIND = Kind.Long; + private static final long VECTOR_SIZE = arrayIndexScale(Kind.Long); + + private static void vectorizedCopy(Object src, int srcPos, Object dest, int destPos, int length, Kind baseKind) { + int header = arrayBaseOffset(baseKind); + int elementSize = arrayIndexScale(baseKind); + long byteLength = (long) length * elementSize; + long nonVectorBytes = byteLength % VECTOR_SIZE; + long srcOffset = (long) srcPos * elementSize; + long destOffset = (long) destPos * elementSize; + if (probability(NOT_FREQUENT_PROBABILITY, src == dest) && probability(NOT_FREQUENT_PROBABILITY, srcPos < destPos)) { + // bad aliased case + for (long i = byteLength - elementSize; i >= byteLength - nonVectorBytes; i -= elementSize) { + UnsafeStoreNode.store(dest, header, i + destOffset, UnsafeLoadNode.load(src, header, i + srcOffset, baseKind), baseKind); + } + long vectorLength = byteLength - nonVectorBytes; + for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { + Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); + } + } else { + for (long i = 0; i < nonVectorBytes; i += elementSize) { + UnsafeStoreNode.store(dest, header, i + destOffset, UnsafeLoadNode.load(src, header, i + srcOffset, baseKind), baseKind); + } + for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) { + Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); + } + } + } + + @Snippet + public static void arraycopyByte(byte[] src, int srcPos, byte[] dest, int destPos, int length) { + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Byte); + } + + @Snippet + public static void arraycopyBoolean(boolean[] src, int srcPos, boolean[] dest, int destPos, int length) { + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Byte); + } + + @Snippet + public static void arraycopyChar(char[] src, int srcPos, char[] dest, int destPos, int length) { + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Char); + } + + @Snippet + public static void arraycopyShort(short[] src, int srcPos, short[] dest, int destPos, int length) { + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Short); + } + + @Snippet + public static void arraycopyInt(int[] src, int srcPos, int[] dest, int destPos, int length) { + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Int); + } + + @Snippet + public static void arraycopyFloat(float[] src, int srcPos, float[] dest, int destPos, int length) { + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Float); + } + + @Snippet + public static void arraycopyLong(long[] src, int srcPos, long[] dest, int destPos, int length) { + Kind baseKind = Kind.Long; + int header = arrayBaseOffset(baseKind); + long byteLength = (long) length * arrayIndexScale(baseKind); + long srcOffset = (long) srcPos * arrayIndexScale(baseKind); + long destOffset = (long) destPos * arrayIndexScale(baseKind); + if (src == dest && srcPos < destPos) { // bad aliased case + for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { + Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); + } + } else { + for (long i = 0; i < byteLength; i += VECTOR_SIZE) { + Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); + } + } + } + + @Snippet + public static void arraycopyDouble(double[] src, int srcPos, double[] dest, int destPos, int length) { + Kind baseKind = Kind.Double; + int header = arrayBaseOffset(baseKind); + long byteLength = (long) length * arrayIndexScale(baseKind); + long srcOffset = (long) srcPos * arrayIndexScale(baseKind); + long destOffset = (long) destPos * arrayIndexScale(baseKind); + if (src == dest && srcPos < destPos) { // bad aliased case + for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { + Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); + } + } else { + for (long i = 0; i < byteLength; i += VECTOR_SIZE) { + Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND); + } + } + } + + /** + * Does NOT perform store checks. + */ + @Snippet + public static void arraycopyObject(Object[] src, int srcPos, Object[] dest, int destPos, int length) { + final int scale = arrayIndexScale(Kind.Object); + int header = arrayBaseOffset(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, header, i + (long) srcPos * scale, Kind.Object); + DirectObjectStoreNode.storeObject(dest, header, i + (long) destPos * scale, a); + } + } else { + long end = (long) length * scale; + 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); + } + } + } + + @Snippet + public static void arraycopyPrimitive(Object src, int srcPos, Object dest, int destPos, int length, int layoutHelper) { + int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask(); + int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask(); + + Word srcOffset = (Word) Word.fromObject(src).add(headerSize).add(srcPos << log2ElementSize); + Word destOffset = (Word) Word.fromObject(dest).add(headerSize).add(destPos << log2ElementSize); + Word destStart = destOffset; + long sizeInBytes = ((long) length) << log2ElementSize; + Word destEnd = destOffset.add(Word.unsigned(length).shiftLeft(log2ElementSize)); + + int nonVectorBytes = (int) (sizeInBytes % VECTOR_SIZE); + Word destNonVectorEnd = destStart.add(nonVectorBytes); + + while (destOffset.belowThan(destNonVectorEnd)) { + destOffset.writeByte(0, srcOffset.readByte(0, ANY_LOCATION), ANY_LOCATION); + destOffset = destOffset.add(1); + srcOffset = srcOffset.add(1); + } + while (destOffset.belowThan(destEnd)) { + destOffset.writeWord(0, srcOffset.readWord(0, ANY_LOCATION), ANY_LOCATION); + destOffset = destOffset.add(wordSize()); + srcOffset = srcOffset.add(wordSize()); + } + } + + public static class Templates extends AbstractTemplates { + + private final SnippetInfo[] arraycopySnippets; + private final SnippetInfo genericPrimitiveSnippet; + + public Templates(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) { + super(runtime, replacements, target); + + arraycopySnippets = new SnippetInfo[Kind.values().length]; + arraycopySnippets[Kind.Boolean.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyBoolean"); + arraycopySnippets[Kind.Byte.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyByte"); + arraycopySnippets[Kind.Short.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyShort"); + arraycopySnippets[Kind.Char.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyChar"); + arraycopySnippets[Kind.Int.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyInt"); + arraycopySnippets[Kind.Long.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyLong"); + arraycopySnippets[Kind.Float.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyFloat"); + arraycopySnippets[Kind.Double.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyDouble"); + arraycopySnippets[Kind.Object.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyObject"); + + genericPrimitiveSnippet = snippet(UnsafeArrayCopySnippets.class, "arraycopyPrimitive"); + } + + public void lower(UnsafeArrayCopyNode node) { + Kind elementKind = node.getElementKind(); + SnippetInfo snippet; + if (elementKind == null) { + // primitive array of unknown kind + snippet = genericPrimitiveSnippet; + } else { + snippet = arraycopySnippets[elementKind.ordinal()]; + assert snippet != null : "arraycopy snippet for " + elementKind.name() + " not found"; + } + + Arguments args = new Arguments(snippet); + node.addSnippetArguments(args); + + SnippetTemplate template = template(args); + template.instantiate(runtime, node, DEFAULT_REPLACER, args); + } + } +} diff -r 7a0d4d95f84c -r 6447890af1bf graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/G1PostWriteBarrier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/G1PostWriteBarrier.java Thu Jun 20 21:11:06 2013 +0200 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes; + +import com.oracle.graal.nodes.extended.*; + +public class G1PostWriteBarrier extends WriteBarrier { + + @Input private ValueNode value; + + public ValueNode getValue() { + return value; + } + + public G1PostWriteBarrier(ValueNode object, ValueNode value, LocationNode location, boolean precise) { + super(object, location, precise); + this.value = value; + } +} diff -r 7a0d4d95f84c -r 6447890af1bf graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/G1PreWriteBarrier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/G1PreWriteBarrier.java Thu Jun 20 21:11:06 2013 +0200 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes; + +import com.oracle.graal.nodes.extended.*; + +public class G1PreWriteBarrier extends WriteBarrier { + + @Input private ValueNode expectedObject; + private final boolean doLoad; + + public ValueNode getExpectedObject() { + return expectedObject; + } + + public boolean doLoad() { + return doLoad; + } + + public G1PreWriteBarrier(ValueNode object, ValueNode expectedObject, LocationNode location, boolean doLoad) { + super(object, location, true); + this.doLoad = doLoad; + this.expectedObject = expectedObject; + } +} diff -r 7a0d4d95f84c -r 6447890af1bf graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GenericArrayRangeWriteBarrier.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GenericArrayRangeWriteBarrier.java Thu Jun 20 17:38:53 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.nodes; - -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.type.*; - -public final class GenericArrayRangeWriteBarrier extends FixedWithNextNode implements Node.IterableNodeType { - - @Input private ValueNode dstObject; - @Input private ValueNode dstPos; - @Input private ValueNode length; - - public ValueNode getDstObject() { - return dstObject; - } - - public ValueNode getDstPos() { - return dstPos; - } - - public ValueNode getLength() { - return length; - } - - public GenericArrayRangeWriteBarrier(ValueNode dstObject, ValueNode dstPos, ValueNode length) { - super(StampFactory.forVoid()); - this.dstObject = dstObject; - this.dstPos = dstPos; - this.length = length; - - } - - @NodeIntrinsic - public static native void insertWriteBarrier(Object dstObject, int dstPos, int length); -} diff -r 7a0d4d95f84c -r 6447890af1bf graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SerialWriteBarrier.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SerialWriteBarrier.java Thu Jun 20 17:38:53 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SerialWriteBarrier.java Thu Jun 20 21:11:06 2013 +0200 @@ -22,39 +22,11 @@ */ package com.oracle.graal.nodes; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -public final class SerialWriteBarrier extends FixedWithNextNode implements Lowerable, Node.IterableNodeType { - - @Input private ValueNode object; - @Input private LocationNode location; - private final boolean precise; - public ValueNode getObject() { - return object; - } - - public LocationNode getLocation() { - return location; - } - - public boolean usePrecise() { - return precise; - } +public class SerialWriteBarrier extends WriteBarrier { public SerialWriteBarrier(ValueNode object, LocationNode location, boolean precise) { - super(StampFactory.forVoid()); - this.object = object; - this.location = location; - this.precise = precise; - } - - @Override - public void lower(LoweringTool generator, LoweringType loweringType) { - assert loweringType == LoweringType.AFTER_GUARDS; - generator.getRuntime().lower(this, generator); + super(object, location, precise); } } diff -r 7a0d4d95f84c -r 6447890af1bf graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/WriteBarrier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/WriteBarrier.java Thu Jun 20 21:11:06 2013 +0200 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +public class WriteBarrier extends FixedWithNextNode implements Lowerable, Node.IterableNodeType { + + @Input private ValueNode object; + @Input private LocationNode location; + private final boolean precise; + + public ValueNode getObject() { + return object; + } + + public LocationNode getLocation() { + return location; + } + + public boolean usePrecise() { + return precise; + } + + public WriteBarrier(ValueNode object, LocationNode location, boolean precise) { + super(StampFactory.forVoid()); + this.object = object; + this.location = location; + this.precise = precise; + } + + @Override + public void lower(LoweringTool generator, LoweringType loweringType) { + assert loweringType == LoweringType.AFTER_GUARDS; + generator.getRuntime().lower(this, generator); + } +} diff -r 7a0d4d95f84c -r 6447890af1bf graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ArrayRangeWriteNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ArrayRangeWriteNode.java Thu Jun 20 21:11:06 2013 +0200 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes.extended; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; + +/** + * Base class for nodes that modify a range of an array. + */ +public abstract class ArrayRangeWriteNode extends AbstractStateSplit implements Node.IterableNodeType { + + protected ArrayRangeWriteNode(Stamp stamp) { + super(stamp); + } + + /** + * The array that is written to. + */ + public abstract ValueNode getArray(); + + /** + * The first modified index. + */ + public abstract ValueNode getIndex(); + + /** + * The length of the modified range. + */ + public abstract ValueNode getLength(); + + /** + * Return true if the written array is an object array, false if it is a primitive array. + */ + public abstract boolean isObjectArray(); +} diff -r 7a0d4d95f84c -r 6447890af1bf src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Thu Jun 20 17:38:53 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Thu Jun 20 21:11:06 2013 +0200 @@ -871,6 +871,8 @@ set_int("g1SATBQueueMarkingOffset", in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active())); set_int("g1SATBQueueIndexOffset", in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_index())); set_int("g1SATBQueueBufferOffset", in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_buf())); + set_address("writeBarrierPreAddress", GraalRuntime::write_barrier_pre); + set_address("writeBarrierPostAddress", GraalRuntime::write_barrier_post); BarrierSet* bs = Universe::heap()->barrier_set(); switch (bs->kind()) { diff -r 7a0d4d95f84c -r 6447890af1bf src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Thu Jun 20 17:38:53 2013 +0200 +++ b/src/share/vm/graal/graalRuntime.cpp Thu Jun 20 21:11:06 2013 +0200 @@ -358,6 +358,14 @@ } JRT_END +JRT_LEAF(void, GraalRuntime::write_barrier_pre(JavaThread* thread, oopDesc* obj)) + thread->satb_mark_queue().enqueue(obj); +JRT_END + +JRT_LEAF(void, GraalRuntime::write_barrier_post(JavaThread* thread, void* card_addr)) + thread->dirty_card_queue().enqueue(card_addr); +JRT_END + JRT_ENTRY(void, GraalRuntime::vm_error(JavaThread* thread, oop where, oop format, jlong value)) ResourceMark rm; assert(where == NULL || java_lang_String::is_instance(where), "must be"); diff -r 7a0d4d95f84c -r 6447890af1bf src/share/vm/graal/graalRuntime.hpp --- a/src/share/vm/graal/graalRuntime.hpp Thu Jun 20 17:38:53 2013 +0200 +++ b/src/share/vm/graal/graalRuntime.hpp Thu Jun 20 21:11:06 2013 +0200 @@ -52,6 +52,8 @@ LOG_OBJECT_ADDRESS = 0x04 }; static void log_object(JavaThread* thread, oop msg, jint flags); + static void write_barrier_pre(JavaThread* thread, oopDesc* obj); + static void write_barrier_post(JavaThread* thread, void* card); }; #endif // SHARE_VM_GRAAL_GRAAL_RUNTIME_HPP