# HG changeset patch # User Christos Kotselidis # Date 1361786886 -3600 # Node ID 286a49d423c9c005a0f272162da9cdf26268a8df # Parent 9cf5e381df059f23e839dcf23768b5442b219193 -Snippetization of CMS WriteBarriers diff -r 9cf5e381df05 -r 286a49d423c9 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 Wed Feb 20 17:29:40 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Mon Feb 25 11:08:06 2013 +0100 @@ -614,8 +614,8 @@ graph.addAfterFixed(memoryWrite, writeBarrier); last = writeBarrier; } else { - WriteBarrierPre writeBarrierPre = graph.add(new WriteBarrierPre(memoryWrite.object(), null, true)); - WriteBarrierPost writeBarrierPost = graph.add(new WriteBarrierPost(memoryWrite.object(), memoryWrite.value())); + WriteBarrierPre writeBarrierPre = graph.add(new WriteBarrierPre(memoryWrite.object(), null, null, true)); + WriteBarrierPost writeBarrierPost = graph.add(new WriteBarrierPost(memoryWrite.object(), memoryWrite.value(), null)); graph.addBeforeFixed(memoryWrite, writeBarrierPre); graph.addAfterFixed(memoryWrite, writeBarrierPost); last = writeBarrierPost; @@ -640,19 +640,19 @@ FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(cas.object())); graph.addAfterFixed(cas, writeBarrier); } else { - WriteBarrierPre writeBarrierPre = graph.add(new WriteBarrierPre(cas.object(), cas.expected(), false)); - WriteBarrierPost writeBarrierPost = graph.add(new WriteBarrierPost(cas.object(), cas.newValue())); + WriteBarrierPre writeBarrierPre = graph.add(new WriteBarrierPre(cas.object(), cas.expected(), null, false)); + WriteBarrierPost writeBarrierPost = graph.add(new WriteBarrierPost(cas.object(), cas.newValue(), null)); graph.addAfterFixed(cas, writeBarrierPre); graph.addAfterFixed(cas, writeBarrierPost); } } else { + LocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, cas.expected().kind(), cas.displacement(), cas.offset(), graph, false); // This may be an array store so use an array write barrier if (!config.useG1GC) { - LocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, cas.expected().kind(), cas.displacement(), cas.offset(), graph, false); - graph.addAfterFixed(cas, graph.add(new ArrayWriteBarrier(cas.object(), location))); + graph.addAfterFixed(cas, graph.add(new ArrayWriteBarrier(cas.object(), (IndexedLocationNode) location))); } else { - graph.addBeforeFixed(cas, graph.add(new WriteBarrierPre(cas.object(), cas.expected(), false))); - graph.addAfterFixed(cas, graph.add(new WriteBarrierPost(cas.object(), cas.newValue()))); + graph.addBeforeFixed(cas, graph.add(new WriteBarrierPre(cas.object(), cas.expected(), location, false))); + graph.addAfterFixed(cas, graph.add(new WriteBarrierPost(cas.object(), cas.newValue(), location))); } } } @@ -700,10 +700,10 @@ if (elementKind == Kind.Object && !value.objectStamp().alwaysNull()) { if (!config.useG1GC) { - graph.addAfterFixed(memoryWrite, graph.add(new ArrayWriteBarrier(array, arrayLocation))); + graph.addAfterFixed(memoryWrite, graph.add(new ArrayWriteBarrier(array, (IndexedLocationNode) arrayLocation))); } else { - graph.addBeforeFixed(memoryWrite, graph.add(new WriteBarrierPre(array, null, true))); - graph.addAfterFixed(memoryWrite, graph.add(new WriteBarrierPost(array, value))); + graph.addBeforeFixed(memoryWrite, graph.add(new WriteBarrierPre(array, null, arrayLocation, true))); + graph.addAfterFixed(memoryWrite, graph.add(new WriteBarrierPost(array, value, arrayLocation))); } } } else if (n instanceof UnsafeLoadNode) { @@ -731,8 +731,8 @@ FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(object)); graph.addAfterFixed(write, writeBarrier); } else { - graph.addBeforeFixed(write, graph.add(new WriteBarrierPre(object, null, true))); - graph.addAfterFixed(write, graph.add(new WriteBarrierPost(object, write.value()))); + graph.addBeforeFixed(write, graph.add(new WriteBarrierPre(object, null, null, true))); + graph.addAfterFixed(write, graph.add(new WriteBarrierPost(object, write.value(), null))); } } else { // This may be an array store so use an array write barrier @@ -740,8 +740,8 @@ ArrayWriteBarrier writeBarrier = graph.add(new ArrayWriteBarrier(object, location)); graph.addAfterFixed(write, writeBarrier); } else { - graph.addBeforeFixed(write, graph.add(new WriteBarrierPre(object, null, true))); - graph.addAfterFixed(write, graph.add(new WriteBarrierPost(object, store.value()))); + graph.addBeforeFixed(write, graph.add(new WriteBarrierPre(object, null, location, true))); + graph.addAfterFixed(write, graph.add(new WriteBarrierPost(object, store.value(), location))); } } } diff -r 9cf5e381df05 -r 286a49d423c9 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayWriteBarrier.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayWriteBarrier.java Wed Feb 20 17:29:40 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayWriteBarrier.java Mon Feb 25 11:08:06 2013 +0100 @@ -29,17 +29,17 @@ public final class ArrayWriteBarrier extends WriteBarrier implements Lowerable { @Input private ValueNode object; - @Input private LocationNode location; + @Input private IndexedLocationNode location; public ValueNode object() { return object; } - public LocationNode location() { + public IndexedLocationNode location() { return location; } - public ArrayWriteBarrier(ValueNode object, LocationNode location) { + public ArrayWriteBarrier(ValueNode object, IndexedLocationNode location) { this.object = object; this.location = location; } diff -r 9cf5e381df05 -r 286a49d423c9 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 Wed Feb 20 17:29:40 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPost.java Mon Feb 25 11:08:06 2013 +0100 @@ -23,12 +23,14 @@ package com.oracle.graal.hotspot.nodes; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; public final class WriteBarrierPost extends WriteBarrier implements Lowerable { @Input private ValueNode object; @Input private ValueNode value; + @Input private LocationNode location; public ValueNode object() { return object; @@ -38,9 +40,14 @@ return value; } - public WriteBarrierPost(ValueNode object, ValueNode value) { + public LocationNode location() { + return location; + } + + public WriteBarrierPost(ValueNode object, ValueNode value, LocationNode location) { this.object = object; this.value = value; + this.location = location; } public void lower(LoweringTool generator) { diff -r 9cf5e381df05 -r 286a49d423c9 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPre.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPre.java Wed Feb 20 17:29:40 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPre.java Mon Feb 25 11:08:06 2013 +0100 @@ -23,12 +23,14 @@ package com.oracle.graal.hotspot.nodes; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; public final class WriteBarrierPre extends WriteBarrier implements Lowerable { @Input private ValueNode object; @Input private ValueNode previousValue; + @Input private LocationNode location; private boolean doLoad; public ValueNode object() { @@ -43,10 +45,15 @@ return doLoad; } - public WriteBarrierPre(ValueNode object, ValueNode previousValue, boolean doLoad) { + public LocationNode location() { + return location; + } + + public WriteBarrierPre(ValueNode object, ValueNode previousValue, LocationNode location, boolean doLoad) { this.object = object; this.previousValue = previousValue; this.doLoad = doLoad; + this.location = location; } public void lower(LoweringTool generator) { diff -r 9cf5e381df05 -r 286a49d423c9 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java Wed Feb 20 17:29:40 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java Mon Feb 25 11:08:06 2013 +0100 @@ -48,7 +48,8 @@ @Fold public static boolean verifyOops() { - return config().verifyOops; + return true; + // return config().verifyOops; } @Fold diff -r 9cf5e381df05 -r 286a49d423c9 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/WriteBarrierSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/WriteBarrierSnippets.java Wed Feb 20 17:29:40 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/WriteBarrierSnippets.java Mon Feb 25 11:08:06 2013 +0100 @@ -28,8 +28,10 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.snippets.*; +import com.oracle.graal.snippets.Snippet.ConstantParameter; import com.oracle.graal.snippets.Snippet.Parameter; import com.oracle.graal.snippets.SnippetTemplate.AbstractTemplates; import com.oracle.graal.snippets.SnippetTemplate.Arguments; @@ -85,8 +87,7 @@ base = base.add(Word.unsigned(cardTableStart())); } - // if (value != null) { - if (true) { + if (value.notEqual(0)) { Word xorResult = (((Word) oop.xor(value)).unsignedShiftRight(HotSpotSnippetUtils.logOfHRGrainBytes())); if (xorResult.notEqual(Word.zero())) { if (value.notEqual(Word.zero())) { @@ -116,7 +117,7 @@ @Snippet public static void serialFieldWriteBarrier(@Parameter("object") Object object) { - // verifyOop(object); + verifyOop(object); Pointer oop = Word.fromObject(object); Word base = (Word) oop.unsignedShiftRight(cardTableShift()); long startAddress = cardTableStart(); @@ -127,13 +128,11 @@ base = base.add(Word.unsigned(cardTableStart())); } base.writeWord(displacement, Word.zero()); - // WriteBarrierStubCall.call(object); } @Snippet - public static void serialArrayWriteBarrier(@Parameter("object") Object object) { - // verifyOop(object); - Pointer oop = Word.fromObject(object); + public static void serialArrayWriteBarrier(@Parameter("object") Object object, @Parameter("location") Object location) { + Pointer oop = Word.fromArray(object, location); Word base = (Word) oop.unsignedShiftRight(cardTableShift()); long startAddress = cardTableStart(); int displacement = 0; @@ -156,7 +155,7 @@ public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target, boolean useG1GC) { super(runtime, assumptions, target, WriteBarrierSnippets.class); serialFieldWriteBarrier = snippet("serialFieldWriteBarrier", Object.class); - serialArrayWriteBarrier = snippet("serialArrayWriteBarrier", Object.class); + serialArrayWriteBarrier = snippet("serialArrayWriteBarrier", Object.class, Object.class); g1PreWriteBarrier = snippet("g1PreWriteBarrier", Object.class, Word.class, boolean.class); g1PostWriteBarrier = snippet("g1PostWriteBarrier", Object.class, Word.class); this.useG1GC = useG1GC; @@ -167,6 +166,7 @@ Key key = new Key(method); Arguments arguments = new Arguments(); arguments.add("object", arrayWriteBarrier.object()); + arguments.add("location", arrayWriteBarrier.location()); SnippetTemplate template = cache.get(key, assumptions); template.instantiate(runtime, arrayWriteBarrier, DEFAULT_REPLACER, arguments); } @@ -200,5 +200,6 @@ SnippetTemplate template = cache.get(key, assumptions); template.instantiate(runtime, writeBarrierPost, DEFAULT_REPLACER, arguments); } + } } diff -r 9cf5e381df05 -r 286a49d423c9 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadArrayElementAddressNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadArrayElementAddressNode.java Mon Feb 25 11:08:06 2013 +0100 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2009, 2011, 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.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * The {@code UnsafeCastNode} produces the same value as its input, but with a different type. + */ +public class ReadArrayElementAddressNode extends FloatingNode implements Canonicalizable, LIRLowerable { + + @Input private ValueNode object; + @Input private ValueNode location; + + public ValueNode object() { + return object; + } + + public LocationNode location() { + return (LocationNode) location; + } + + public ReadArrayElementAddressNode(ValueNode object, ValueNode location, Stamp stamp) { + super(stamp); + this.object = object; + this.location = location; + } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + return this; + } + + @Override + public void generate(LIRGeneratorTool gen) { + Value addr = gen.emitLea(gen.makeAddress(location(), object())); + gen.setResult(this, addr); + } +} diff -r 9cf5e381df05 -r 286a49d423c9 graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java Wed Feb 20 17:29:40 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java Mon Feb 25 11:08:06 2013 +0100 @@ -64,6 +64,7 @@ FROM_UNSIGNED, FROM_SIGNED, FROM_OBJECT, + FROM_ARRAY, TO_OBJECT, TO_RAW_VALUE, } @@ -147,6 +148,9 @@ @Operation(opcode = Opcode.FROM_OBJECT) public static native Pointer fromObject(Object val); + @Operation(opcode = Opcode.FROM_ARRAY) + public static native Pointer fromArray(Object oop, Object location); + @Override @Operation(opcode = Opcode.TO_OBJECT) public native Object toObject(); diff -r 9cf5e381df05 -r 286a49d423c9 graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Wed Feb 20 17:29:40 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Mon Feb 25 11:08:06 2013 +0100 @@ -177,6 +177,11 @@ replace(invoke, graph.unique(new UnsafeCastNode(arguments.get(0), StampFactory.forKind(wordKind)))); break; + case FROM_ARRAY: + assert arguments.size() == 2; + replace(invoke, graph.unique(new ReadArrayElementAddressNode(arguments.get(0), arguments.get(1), StampFactory.forKind(wordKind)))); + break; + case TO_OBJECT: assert arguments.size() == 1; replace(invoke, graph.unique(new UnsafeCastNode(arguments.get(0), invoke.node().stamp()))); diff -r 9cf5e381df05 -r 286a49d423c9 src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Wed Feb 20 17:29:40 2013 +0100 +++ b/src/share/vm/graal/graalRuntime.cpp Mon Feb 25 11:08:06 2013 +0100 @@ -485,6 +485,9 @@ JRT_LEAF(void, GraalRuntime::graal_wb_pre_call(JavaThread* thread, oopDesc* obj)) tty->print_cr("HELLO PRE WRITE BARRIER"); +if(!obj->is_oop()) { + tty->print_cr("ERROR in pre writebarrier address is not object " INTPTR_FORMAT, obj); +} JRT_END JRT_LEAF(void, GraalRuntime::graal_wb_post_call(JavaThread* thread, oopDesc* obj))