# HG changeset patch # User Christos Kotselidis # Date 1365498815 -7200 # Node ID 63eae4723b184cfd63f6fb9a9666b6be98073268 # Parent 81ef56feff1b4c2ee369b0d185343e7e396b1a4f Creation of snippets for ArrayCopy write barriers diff -r 81ef56feff1b -r 63eae4723b18 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 Tue Apr 09 09:45:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Tue Apr 09 11:13:35 2013 +0200 @@ -688,6 +688,8 @@ monitorSnippets.lower((MonitorExitNode) n, tool); } else if (n instanceof SerialWriteBarrier) { writeBarrierSnippets.lower((SerialWriteBarrier) n, tool); + } else if (n instanceof SerialArrayRangeWriteBarrier) { + writeBarrierSnippets.lower((SerialArrayRangeWriteBarrier) n, tool); } else if (n instanceof TLABAllocateNode) { newObjectSnippets.lower((TLABAllocateNode) n, tool); } else if (n instanceof InitializeObjectNode) { diff -r 81ef56feff1b -r 63eae4723b18 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 Tue Apr 09 09:45:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Tue Apr 09 11:13:35 2013 +0200 @@ -41,6 +41,9 @@ for (CompareAndSwapNode node : graph.getNodes(CompareAndSwapNode.class)) { addCASBarriers(node, graph); } + for (GenericArrayRangeWriteBarrier node : graph.getNodes(GenericArrayRangeWriteBarrier.class)) { + addArrayRangeBarriers(node, graph); + } } private void addWriteNodeBarriers(WriteNode node, StructuredGraph graph) { @@ -57,4 +60,9 @@ } } + private void addArrayRangeBarriers(GenericArrayRangeWriteBarrier node, StructuredGraph graph) { + SerialArrayRangeWriteBarrier serialArrayRangeWriteBarrier = graph.add(new SerialArrayRangeWriteBarrier(node.getDstObject(), node.getDstPos(), node.getLength())); + graph.replaceFixedWithFixed(node, serialArrayRangeWriteBarrier); + } + } diff -r 81ef56feff1b -r 63eae4723b18 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 Tue Apr 09 09:45:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Tue Apr 09 11:13:35 2013 +0200 @@ -236,9 +236,14 @@ } } + @Snippet + public static void arraycopy(Object[] src, int srcPos, Object[] dest, int destPos, int length) { + arrayObjectCopy(src, srcPos, dest, destPos, length); + } + // Does NOT perform store checks @Snippet - public static void arraycopy(Object[] src, int srcPos, Object[] dest, int destPos, int length) { + public static void arrayObjectCopy(Object src, int srcPos, Object dest, int destPos, int length) { objectCounter.inc(); checkNonNull(src); checkNonNull(dest); @@ -260,15 +265,7 @@ } } 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); - } + GenericArrayRangeWriteBarrier.insertWriteBarrier(dest, destPos, length); } } @@ -278,14 +275,22 @@ // 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); - int layoutHelper = checkArrayType(srcHub); if (srcHub.equal(destHub) && src != dest) { probability(FAST_PATH_PROBABILITY); checkLimits(src, srcPos, dest, destPos, length); - - arraycopyInnerloop(src, srcPos, dest, destPos, length, layoutHelper); + if (isObjectArray) { + genericObjectExactCallCounter.inc(); + probability(FAST_PATH_PROBABILITY); + arrayObjectCopy(src, srcPos, dest, destPos, length); + } else { + genericPrimitiveCallCounter.inc(); + arraycopyInnerloop(src, srcPos, dest, destPos, length, layoutHelper); + } } else { genericObjectCallCounter.inc(); System.arraycopy(src, srcPos, dest, destPos, length); @@ -317,25 +322,6 @@ 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; diff -r 81ef56feff1b -r 63eae4723b18 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 Tue Apr 09 09:45:35 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Tue Apr 09 11:13:35 2013 +0200 @@ -31,6 +31,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.*; +import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.Snippet.Parameter; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; @@ -60,13 +61,30 @@ base.writeByte(displacement, (byte) 0); } + @Snippet + public static void serialArrayRangeWriteBarrier(@Parameter("dstObject") Object dest, @Parameter("destPos") int destPos, @Parameter("length") int length) { + int cardShift = cardTableShift(); + long cardStart = cardTableStart(); + final int scale = arrayIndexScale(Kind.Object); + int header = arrayBaseOffset(Kind.Object); + 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); + } + } + public static class Templates extends AbstractTemplates { private final ResolvedJavaMethod serialArrayWriteBarrier; + private final ResolvedJavaMethod serialArrayRangeWriteBarrier; public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) { super(runtime, replacements, target, WriteBarrierSnippets.class); serialArrayWriteBarrier = snippet("serialArrayWriteBarrier", Object.class, Object.class, boolean.class); + serialArrayRangeWriteBarrier = snippet("serialArrayRangeWriteBarrier", Object.class, int.class, int.class); } public void lower(SerialWriteBarrier arrayWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) { @@ -79,5 +97,16 @@ SnippetTemplate template = cache.get(key); template.instantiate(runtime, arrayWriteBarrier, DEFAULT_REPLACER, arguments); } + + public void lower(SerialArrayRangeWriteBarrier arrayRangeWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) { + ResolvedJavaMethod method = serialArrayRangeWriteBarrier; + Key key = new Key(method); + Arguments arguments = new Arguments(); + arguments.add("dstObject", arrayRangeWriteBarrier.getDstObject()); + arguments.add("destPos", arrayRangeWriteBarrier.getDstPos()); + arguments.add("length", arrayRangeWriteBarrier.getLength()); + SnippetTemplate template = cache.get(key); + template.instantiate(runtime, arrayRangeWriteBarrier, DEFAULT_REPLACER, arguments); + } } } diff -r 81ef56feff1b -r 63eae4723b18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GenericArrayRangeWriteBarrier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GenericArrayRangeWriteBarrier.java Tue Apr 09 11:13:35 2013 +0200 @@ -0,0 +1,56 @@ +/* + * 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 81ef56feff1b -r 63eae4723b18 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SerialArrayRangeWriteBarrier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SerialArrayRangeWriteBarrier.java Tue Apr 09 11:13:35 2013 +0200 @@ -0,0 +1,58 @@ +/* + * 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.spi.*; +import com.oracle.graal.nodes.type.*; + +public final class SerialArrayRangeWriteBarrier extends FixedWithNextNode implements Lowerable { + + @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 SerialArrayRangeWriteBarrier(ValueNode dstObject, ValueNode dstPos, ValueNode length) { + super(StampFactory.forVoid()); + this.dstObject = dstObject; + this.dstPos = dstPos; + this.length = length; + + } + + public void lower(LoweringTool generator) { + generator.getRuntime().lower(this, generator); + } + +}