# HG changeset patch # User Christos Kotselidis # Date 1361373343 -3600 # Node ID 1567c6cc65610b466650827753e2b8d85b020616 # Parent 92d21814cf7b3bc593c247a935c0669746e8ef5b Towards porting G1 WBs diff -r 92d21814cf7b -r 1567c6cc6561 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Tue Feb 19 17:57:14 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Wed Feb 20 16:15:43 2013 +0100 @@ -36,7 +36,8 @@ import static com.oracle.graal.hotspot.nodes.ThreadIsInterruptedStubCall.*; import static com.oracle.graal.hotspot.nodes.VMErrorNode.*; import static com.oracle.graal.hotspot.nodes.VerifyOopStubCall.*; -import static com.oracle.graal.hotspot.nodes.WriteBarrierStubCall.*; +import static com.oracle.graal.hotspot.nodes.WriteBarrierPreStubCall.*; +import static com.oracle.graal.hotspot.nodes.WriteBarrierPostStubCall.*; import static com.oracle.graal.hotspot.snippets.AESCryptSubstitutions.DecryptBlockStubCall.*; import static com.oracle.graal.hotspot.snippets.AESCryptSubstitutions.EncryptBlockStubCall.*; import static com.oracle.graal.hotspot.snippets.CipherBlockChainingSubstitutions.DecryptAESCryptStubCall.*; @@ -88,11 +89,16 @@ /* arg0: object */ javaCallingConvention(Kind.Object, /* arg1: lock */ word)); - addRuntimeCall(G1_WB_SLOW, config.g1WBSlowStub, - /* temps */ null, - /* ret */ ret(Kind.Void), - /* arg0: object */ javaCallingConvention(Kind.Object)); - + addRuntimeCall(WBPRECALL, config.wbPreCallStub, + /* temps */ null, + /* ret */ ret(Kind.Void), + /* arg0: object */ javaCallingConvention(Kind.Object)); + + addRuntimeCall(WBPOSTCALL, config.wbPostCallStub, + /* temps */ null, + /* ret */ ret(Kind.Void), + /* arg0: object */ javaCallingConvention(Kind.Object)); + addRuntimeCall(MONITOREXIT, config.monitorExitStub, /* temps */ null, /* ret */ ret(Kind.Void), diff -r 92d21814cf7b -r 1567c6cc6561 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Feb 19 17:57:14 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Wed Feb 20 16:15:43 2013 +0100 @@ -213,6 +213,16 @@ public boolean isPollingPageFar; /** + * G1 Collector Related Values. + */ + public int g1CardQueueIndexOffset; + public int g1CardQueueBufferOffset; + public int logOfHRGrainBytes; + public int g1SATBQueueMarkingOffset; + public int g1SATBQueueIndexOffset; + public int g1SATBQueueBufferOffset; + + /** * The offset of the _java_mirror field (of type {@link Class}) in a Klass. */ public int classMirrorOffset; @@ -316,7 +326,8 @@ public long handleDeoptStub; public long monitorEnterStub; public long monitorExitStub; - public long g1WBSlowStub; + public long wbPreCallStub; + public long wbPostCallStub; public long verifyOopStub; public long vmErrorStub; public long deoptimizeStub; diff -r 92d21814cf7b -r 1567c6cc6561 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 Feb 19 17:57:14 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Wed Feb 20 16:15:43 2013 +0100 @@ -609,9 +609,18 @@ graph.replaceFixedWithFixed(storeField, memoryWrite); FixedWithNextNode last = memoryWrite; if (field.getKind() == Kind.Object && !memoryWrite.value().objectStamp().alwaysNull()) { - FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(memoryWrite.object())); - graph.addAfterFixed(memoryWrite, writeBarrier); - last = writeBarrier; + if (!config.useG1GC) { + FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(memoryWrite.object())); + graph.addAfterFixed(memoryWrite, writeBarrier); + last = writeBarrier; + } else { + WriteBarrierPre writeBarrierPre = graph.add(new WriteBarrierPre(memoryWrite.object())); + WriteBarrierPost writeBarrierPost = graph.add(new WriteBarrierPost(memoryWrite.object())); + graph.addBeforeFixed(memoryWrite, writeBarrierPre); + graph.addAfterFixed(memoryWrite, writeBarrierPost); + last = writeBarrierPost; + + } } if (storeField.isVolatile()) { MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_WRITE)); @@ -627,12 +636,24 @@ ResolvedJavaType type = cas.object().objectStamp().type(); if (type != null && !type.isArray() && !MetaUtil.isJavaLangObject(type)) { // Use a field write barrier since it's not an array store - FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(cas.object())); - graph.addAfterFixed(cas, writeBarrier); + if (!config.useG1GC) { + FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(cas.object())); + graph.addAfterFixed(cas, writeBarrier); + } else { + WriteBarrierPre writeBarrierPre = graph.add(new WriteBarrierPre(cas.object())); + WriteBarrierPost writeBarrierPost = graph.add(new WriteBarrierPost(cas.object())); + graph.addAfterFixed(cas, writeBarrierPre); + graph.addAfterFixed(cas, writeBarrierPost); + } } else { // This may be an array store so use an array write barrier - 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))); + 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))); + } else { + graph.addBeforeFixed(cas, graph.add(new WriteBarrierPre(cas.object()))); + graph.addAfterFixed(cas, graph.add(new WriteBarrierPost(cas.object()))); + } } } } else if (n instanceof LoadIndexedNode) { @@ -678,7 +699,12 @@ graph.replaceFixedWithFixed(storeIndexed, memoryWrite); if (elementKind == Kind.Object && !value.objectStamp().alwaysNull()) { - graph.addAfterFixed(memoryWrite, graph.add(new ArrayWriteBarrier(array, arrayLocation))); + if (!config.useG1GC) { + graph.addAfterFixed(memoryWrite, graph.add(new ArrayWriteBarrier(array, arrayLocation))); + } else { + graph.addBeforeFixed(memoryWrite, graph.add(new WriteBarrierPre(array))); + graph.addAfterFixed(memoryWrite, graph.add(new WriteBarrierPost(array))); + } } } else if (n instanceof UnsafeLoadNode) { UnsafeLoadNode load = (UnsafeLoadNode) n; @@ -701,14 +727,23 @@ // WriteBarrier writeBarrier; if (type != null && !type.isArray() && !MetaUtil.isJavaLangObject(type)) { // Use a field write barrier since it's not an array store - FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(object)); - graph.addAfterFixed(write, writeBarrier); + if (!config.useG1GC) { + FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(object)); + graph.addAfterFixed(write, writeBarrier); + } else { + graph.addBeforeFixed(write, graph.add(new WriteBarrierPre(object))); + graph.addAfterFixed(write, graph.add(new WriteBarrierPost(object))); + } } else { // This may be an array store so use an array write barrier - ArrayWriteBarrier writeBarrier = graph.add(new ArrayWriteBarrier(object, location)); - graph.addAfterFixed(write, writeBarrier); + if (!config.useG1GC) { + ArrayWriteBarrier writeBarrier = graph.add(new ArrayWriteBarrier(object, location)); + graph.addAfterFixed(write, writeBarrier); + } else { + graph.addBeforeFixed(write, graph.add(new WriteBarrierPre(object))); + graph.addAfterFixed(write, graph.add(new WriteBarrierPost(object))); + } } - } } else if (n instanceof LoadHubNode) { LoadHubNode loadHub = (LoadHubNode) n; @@ -744,6 +779,10 @@ writeBarrierSnippets.lower((FieldWriteBarrier) n, tool); } else if (n instanceof ArrayWriteBarrier) { writeBarrierSnippets.lower((ArrayWriteBarrier) n, tool); + } else if (n instanceof WriteBarrierPre) { + writeBarrierSnippets.lower((WriteBarrierPre) n, tool); + } else if (n instanceof WriteBarrierPost) { + writeBarrierSnippets.lower((WriteBarrierPost) n, tool); } else if (n instanceof TLABAllocateNode) { newObjectSnippets.lower((TLABAllocateNode) n, tool); } else if (n instanceof InitializeObjectNode) { diff -r 92d21814cf7b -r 1567c6cc6561 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 Tue Feb 19 17:57:14 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayWriteBarrier.java Wed Feb 20 16:15:43 2013 +0100 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot.nodes; -import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; diff -r 92d21814cf7b -r 1567c6cc6561 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPost.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPost.java Wed Feb 20 16:15:43 2013 +0100 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2012, 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.nodes.*; +import com.oracle.graal.nodes.spi.*; + +public final class WriteBarrierPost extends WriteBarrier implements Lowerable { + + @Input private ValueNode object; + + public ValueNode object() { + return object; + } + + public WriteBarrierPost(ValueNode object) { + this.object = object; + } + + public void lower(LoweringTool generator) { + generator.getRuntime().lower(this, generator); + } +} diff -r 92d21814cf7b -r 1567c6cc6561 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPostStubCall.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPostStubCall.java Wed Feb 20 16:15:43 2013 +0100 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2012, 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.code.RuntimeCallTarget.Descriptor; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; + +/** + * Node implementing a call to HotSpot's {@code graal_monitorenter} stub. + */ +public class WriteBarrierPostStubCall extends FixedWithNextNode implements LIRGenLowerable { + + @Input private final ValueNode object; + public static final Descriptor WBPOSTCALL = new Descriptor("wbpostcall", true, void.class, Object.class); + + public WriteBarrierPostStubCall(ValueNode object) { + super(StampFactory.forVoid()); + this.object = object; + } + + @Override + public void generate(LIRGenerator gen) { + RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(WriteBarrierPostStubCall.WBPOSTCALL); + gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(object)); + } + + @NodeIntrinsic + public static native void call(Object hub); +} diff -r 92d21814cf7b -r 1567c6cc6561 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPre.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPre.java Wed Feb 20 16:15:43 2013 +0100 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2012, 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.nodes.*; +import com.oracle.graal.nodes.spi.*; + +public final class WriteBarrierPre extends WriteBarrier implements Lowerable { + + @Input private ValueNode object; + + public ValueNode object() { + return object; + } + + public WriteBarrierPre(ValueNode object) { + this.object = object; + } + + public void lower(LoweringTool generator) { + generator.getRuntime().lower(this, generator); + } +} diff -r 92d21814cf7b -r 1567c6cc6561 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPreStubCall.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPreStubCall.java Wed Feb 20 16:15:43 2013 +0100 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2012, 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.code.RuntimeCallTarget.Descriptor; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; + +/** + * Node implementing a call to HotSpot's {@code graal_monitorenter} stub. + */ +public class WriteBarrierPreStubCall extends FixedWithNextNode implements LIRGenLowerable { + + @Input private final ValueNode object; + public static final Descriptor WBPRECALL = new Descriptor("wbprecall", true, void.class, Object.class); + + public WriteBarrierPreStubCall(ValueNode object) { + super(StampFactory.forVoid()); + this.object = object; + } + + @Override + public void generate(LIRGenerator gen) { + RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(WriteBarrierPreStubCall.WBPRECALL); + gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(object)); + } + + @NodeIntrinsic + public static native void call(Object hub); +} diff -r 92d21814cf7b -r 1567c6cc6561 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 Tue Feb 19 17:57:14 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java Wed Feb 20 16:15:43 2013 +0100 @@ -227,6 +227,36 @@ } @Fold + public static int g1CardQueueIndexOffset() { + return config().g1CardQueueIndexOffset; + } + + @Fold + public static int g1CardQueueBufferOffset() { + return config().g1CardQueueBufferOffset; + } + + @Fold + public static int logOfHRGrainBytes() { + return config().logOfHRGrainBytes; + } + + @Fold + public static int g1SATBQueueMarkingOffset() { + return config().g1SATBQueueMarkingOffset; + } + + @Fold + public static int g1SATBQueueIndexOffset() { + return config().g1SATBQueueIndexOffset; + } + + @Fold + public static int g1SATBQueueBufferOffset() { + return config().g1SATBQueueBufferOffset; + } + + @Fold public static int superCheckOffsetOffset() { return config().superCheckOffsetOffset; } diff -r 92d21814cf7b -r 1567c6cc6561 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 Tue Feb 19 17:57:14 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/WriteBarrierSnippets.java Wed Feb 20 16:15:43 2013 +0100 @@ -40,13 +40,72 @@ public class WriteBarrierSnippets implements SnippetsInterface { @Snippet - public static void g1PreWriteBarrier(@Parameter("object") Object object) { + public static void g1PreWriteBarrier(@Parameter("object") Object object, @Parameter("previousValue") Word previousValue, @Parameter("load") boolean doLoad) { + Word thread = thread(); + Pointer oop = Word.fromObject(object); + Word markingAddress = thread.add(HotSpotSnippetUtils.g1SATBQueueMarkingOffset()); + Word bufferAddress = thread.add(HotSpotSnippetUtils.g1SATBQueueBufferOffset()); + Word indexAddress = thread.add(HotSpotSnippetUtils.g1SATBQueueIndexOffset()); + Word prevValue = previousValue; + Word marking = markingAddress.readWord(0); + if (marking.notEqual(Word.zero())) { + if (doLoad) { + prevValue = (Word) Word.fromObject(oop.readObject(0)); + } + + if (prevValue.notEqual(Word.zero())) { + if (indexAddress.readInt(0) != 0) { + Word nextIndex = indexAddress.subtract(Word.signed(HotSpotSnippetUtils.wordSize())); + Word nextIndexX = nextIndex; + Word logAddress = bufferAddress.add(nextIndexX); + logAddress.writeWord(0, prevValue); + indexAddress.writeWord(0, nextIndex); + } else { + WriteBarrierPostStubCall.call(object); + } + } + } } @Snippet - public static void g1PostWriteBarrier(@Parameter("object") Object object) { + public static void g1PostWriteBarrier(@Parameter("object") Object object, @Parameter("value") Word value) { + Word thread = thread(); + Pointer oop = Word.fromObject(object); + + Word bufferAddress = thread.add(HotSpotSnippetUtils.g1CardQueueBufferOffset()); + Word indexAddress = thread.add(HotSpotSnippetUtils.g1CardQueueIndexOffset()); + + // Card Table + Word base = (Word) oop.unsignedShiftRight(cardTableShift()); + long startAddress = cardTableStart(); + int displacement = 0; + if (((int) startAddress) == startAddress) { + displacement = (int) startAddress; + } else { + base = base.add(Word.unsigned(cardTableStart())); + } + if (value != null) { + Word xorResult = (((Word) oop.xor(value)).unsignedShiftRight(HotSpotSnippetUtils.logOfHRGrainBytes())); + if (xorResult.notEqual(Word.zero())) { + if (value.notEqual(Word.zero())) { + Word cardValue = base.readWord(displacement); + if (cardValue.notEqual(Word.zero())) { + base.writeWord(displacement, Word.zero()); // smash zero into card + if (indexAddress.readInt(0) != 0) { + Word nextIndex = indexAddress.subtract(Word.signed(HotSpotSnippetUtils.wordSize())); + Word nextIndexX = nextIndex; + Word logAddress = bufferAddress.add(nextIndexX); + logAddress.writeWord(0, base.add(displacement)); + indexAddress.writeWord(0, nextIndex); + } else { + WriteBarrierPostStubCall.call(object); + } + } + } + } + } } private static void trace(boolean enabled, String format, WordBase value) { @@ -68,7 +127,7 @@ base = base.add(Word.unsigned(cardTableStart())); } base.writeWord(displacement, Word.zero()); - WriteBarrierStubCall.call(object); + // WriteBarrierStubCall.call(object); } @Snippet @@ -104,7 +163,7 @@ } public void lower(ArrayWriteBarrier arrayWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) { - ResolvedJavaMethod method = !useG1GC ? serialArrayWriteBarrier : serialArrayWriteBarrier; + ResolvedJavaMethod method = serialArrayWriteBarrier; Key key = new Key(method); Arguments arguments = new Arguments(); arguments.add("object", arrayWriteBarrier.object()); @@ -113,12 +172,30 @@ } public void lower(FieldWriteBarrier fieldWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) { - ResolvedJavaMethod method = !useG1GC ? serialFieldWriteBarrier : serialFieldWriteBarrier; + ResolvedJavaMethod method = serialFieldWriteBarrier; Key key = new Key(method); Arguments arguments = new Arguments(); arguments.add("object", fieldWriteBarrier.object()); SnippetTemplate template = cache.get(key, assumptions); template.instantiate(runtime, fieldWriteBarrier, DEFAULT_REPLACER, arguments); } + + public void lower(WriteBarrierPre writeBarrierPre, @SuppressWarnings("unused") LoweringTool tool) { + ResolvedJavaMethod method = g1PreWriteBarrier; + Key key = new Key(method); + Arguments arguments = new Arguments(); + arguments.add("object", writeBarrierPre.object()); + SnippetTemplate template = cache.get(key, assumptions); + template.instantiate(runtime, writeBarrierPre, DEFAULT_REPLACER, arguments); + } + + public void lower(WriteBarrierPost writeBarrierPost, @SuppressWarnings("unused") LoweringTool tool) { + ResolvedJavaMethod method = g1PostWriteBarrier; + Key key = new Key(method); + Arguments arguments = new Arguments(); + arguments.add("object", writeBarrierPost.object()); + SnippetTemplate template = cache.get(key, assumptions); + template.instantiate(runtime, writeBarrierPost, DEFAULT_REPLACER, arguments); + } } } diff -r 92d21814cf7b -r 1567c6cc6561 src/cpu/x86/vm/graalRuntime_x86.cpp --- a/src/cpu/x86/vm/graalRuntime_x86.cpp Tue Feb 19 17:57:14 2013 +0100 +++ b/src/cpu/x86/vm/graalRuntime_x86.cpp Wed Feb 20 16:15:43 2013 +0100 @@ -1191,25 +1191,43 @@ } __ ret(0); break; - } - case graal_g1_wb_slow_id: { - Register obj = j_rarg0; - { - GraalStubFrame f(sasm, "graal_g1_wb_slow", dont_gc_arguments); - OopMap* map = save_live_registers(sasm, 2, save_fpu_registers); + } + case graal_wb_pre_call_id: { + Register obj = j_rarg0; + { + GraalStubFrame f(sasm, "graal_wb_pre_call", dont_gc_arguments); + OopMap* map = save_live_registers(sasm, 2, save_fpu_registers); + + // note: really a leaf routine but must setup last java sp + // => use call_RT for now (speed can be improved by + // doing last java sp setup manually) + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, graal_wb_pre_call), obj); - // note: really a leaf routine but must setup last java sp - // => use call_RT for now (speed can be improved by - // doing last java sp setup manually) - int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, graal_g1_wb_slow), obj); + oop_maps = new OopMapSet(); + oop_maps->add_gc_map(call_offset, map); + restore_live_registers(sasm, save_fpu_registers); + } + __ ret(0); + break; + } + case graal_wb_post_call_id: { + Register obj = j_rarg0; + { + GraalStubFrame f(sasm, "graal_wb_post_call", dont_gc_arguments); + OopMap* map = save_live_registers(sasm, 2, save_fpu_registers); - oop_maps = new OopMapSet(); - oop_maps->add_gc_map(call_offset, map); - restore_live_registers(sasm, save_fpu_registers); - } - __ ret(0); - break; - } + // note: really a leaf routine but must setup last java sp + // => use call_RT for now (speed can be improved by + // doing last java sp setup manually) + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, graal_wb_post_call), obj); + + oop_maps = new OopMapSet(); + oop_maps->add_gc_map(call_offset, map); + restore_live_registers(sasm, save_fpu_registers); + } + __ ret(0); + break; + } case graal_identity_hash_code_id: { Register obj = j_rarg0; // Incoming __ set_info("identity_hash_code", dont_gc_arguments); diff -r 92d21814cf7b -r 1567c6cc6561 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Tue Feb 19 17:57:14 2013 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Wed Feb 20 16:15:43 2013 +0100 @@ -38,6 +38,7 @@ #include "graal/graalCodeInstaller.hpp" #include "graal/graalVMToCompiler.hpp" #include "graal/graalVmIds.hpp" +#include "gc_implementation/g1/heapRegion.hpp" Method* getMethodFromHotSpotMethod(oop hotspot_method) { @@ -720,7 +721,8 @@ set_long("handleDeoptStub", VmIds::addStub(SharedRuntime::deopt_blob()->unpack())); set_long("monitorEnterStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_monitorenter_id))); set_long("monitorExitStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_monitorexit_id))); - set_long("g1WBSlowStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_g1_wb_slow_id))); + set_long("wbPreCallStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_wb_pre_call_id))); + set_long("wbPostCallStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_wb_post_call_id))); set_long("verifyOopStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_verify_oop_id))); set_long("vmErrorStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_vm_error_id))); set_long("deoptimizeStub", VmIds::addStub(SharedRuntime::deopt_blob()->uncommon_trap())); @@ -764,7 +766,13 @@ set_int("deoptActionReinterpret", Deoptimization::Action_reinterpret); set_int("deoptActionMakeNotEntrant", Deoptimization::Action_make_not_entrant); set_int("deoptActionMakeNotCompilable", Deoptimization::Action_make_not_compilable); + set_int("g1CardQueueIndexOffset", in_bytes(JavaThread::dirty_card_queue_offset() + PtrQueue::byte_offset_of_index())); + set_int("g1CardQueueBufferOffset", in_bytes(JavaThread::dirty_card_queue_offset() + PtrQueue::byte_offset_of_buf())); + set_int("logOfHRGrainBytes", HeapRegion::LogOfHRGrainBytes); + 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())); BarrierSet* bs = Universe::heap()->barrier_set(); switch (bs->kind()) { diff -r 92d21814cf7b -r 1567c6cc6561 src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Tue Feb 19 17:57:14 2013 +0100 +++ b/src/share/vm/graal/graalRuntime.cpp Wed Feb 20 16:15:43 2013 +0100 @@ -483,8 +483,12 @@ } JRT_END -JRT_LEAF(void, GraalRuntime::graal_g1_wb_slow(JavaThread* thread, oopDesc* obj)) - tty->print_cr("HELLO WRITE BARRIER"); +JRT_LEAF(void, GraalRuntime::graal_wb_pre_call(JavaThread* thread, oopDesc* obj)) + tty->print_cr("HELLO PRE WRITE BARRIER"); +JRT_END + +JRT_LEAF(void, GraalRuntime::graal_wb_post_call(JavaThread* thread, oopDesc* obj)) + tty->print_cr("HELLO POST WRITE BARRIER"); JRT_END JRT_LEAF(void, GraalRuntime::graal_monitorexit(JavaThread* thread, oopDesc* obj, BasicLock* lock)) diff -r 92d21814cf7b -r 1567c6cc6561 src/share/vm/graal/graalRuntime.hpp --- a/src/share/vm/graal/graalRuntime.hpp Tue Feb 19 17:57:14 2013 +0100 +++ b/src/share/vm/graal/graalRuntime.hpp Wed Feb 20 16:15:43 2013 +0100 @@ -103,7 +103,8 @@ stub(graal_log_primitive) \ stub(graal_identity_hash_code) \ stub(graal_thread_is_interrupted) \ - stub(graal_g1_wb_slow) \ + stub(graal_wb_pre_call) \ + stub(graal_wb_post_call) \ last_entry(number_of_ids) #define DECLARE_STUB_ID(x) x ## _id , @@ -141,7 +142,8 @@ static address exception_handler_for_pc(JavaThread* thread); - static void graal_g1_wb_slow(JavaThread* thread, oopDesc* obj); + static void graal_wb_pre_call(JavaThread* thread, oopDesc* obj); + static void graal_wb_post_call(JavaThread* thread, oopDesc* obj); static void graal_create_null_exception(JavaThread* thread); static void graal_create_out_of_bounds_exception(JavaThread* thread, jint index); static void graal_monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock);