# HG changeset patch # User Christos Kotselidis # Date 1361289190 -3600 # Node ID 225c984588ee61a6401d48256de323a51a023813 # Parent af07019db85d3f38ddb47baf2e188afd3f2d2da7 -Snippetization of CMS write barriers diff -r af07019db85d -r 225c984588ee 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 Wed Feb 13 18:46:24 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Feb 19 16:53:10 2013 +0100 @@ -42,6 +42,7 @@ public boolean useBiasedLocking; public boolean usePopCountInstruction; public boolean useAESIntrinsics; + public boolean useG1GC; // offsets, ... public int vmPageSize; diff -r af07019db85d -r 225c984588ee 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 13 18:46:24 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Tue Feb 19 16:53:10 2013 +0100 @@ -87,6 +87,7 @@ private InstanceOfSnippets.Templates instanceofSnippets; private NewObjectSnippets.Templates newObjectSnippets; private MonitorSnippets.Templates monitorSnippets; + private WriteBarrierSnippets.Templates writeBarrierSnippets; private NewInstanceStub newInstanceStub; private NewArrayStub newArrayStub; @@ -362,16 +363,19 @@ installer.installSnippets(NewInstanceStub.class); installer.installSnippets(NewArrayStub.class); + installer.installSnippets(WriteBarrierSnippets.class); checkcastSnippets = new CheckCastSnippets.Templates(this, assumptions, graalRuntime.getTarget()); instanceofSnippets = new InstanceOfSnippets.Templates(this, assumptions, graalRuntime.getTarget()); newObjectSnippets = new NewObjectSnippets.Templates(this, assumptions, graalRuntime.getTarget(), config.useTLAB); monitorSnippets = new MonitorSnippets.Templates(this, assumptions, graalRuntime.getTarget(), config.useFastLocking); + writeBarrierSnippets = new WriteBarrierSnippets.Templates(this, assumptions, graalRuntime.getTarget(), config.useG1GC); newInstanceStub = new NewInstanceStub(this, assumptions, graalRuntime.getTarget()); newArrayStub = new NewArrayStub(this, assumptions, graalRuntime.getTarget()); newInstanceStub.install(graalRuntime.getCompiler()); newArrayStub.install(graalRuntime.getCompiler()); + } public HotSpotGraalRuntime getGraalRuntime() { @@ -694,15 +698,17 @@ graph.replaceFixedWithFixed(store, write); if (write.value().kind() == Kind.Object && !write.value().objectStamp().alwaysNull()) { ResolvedJavaType type = object.objectStamp().type(); - WriteBarrier writeBarrier; + // WriteBarrier writeBarrier; if (type != null && !type.isArray() && !MetaUtil.isJavaLangObject(type)) { // Use a field write barrier since it's not an array store - writeBarrier = graph.add(new FieldWriteBarrier(object)); + FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(object)); + graph.addAfterFixed(write, writeBarrier); } else { // This may be an array store so use an array write barrier - writeBarrier = graph.add(new ArrayWriteBarrier(object, location)); + ArrayWriteBarrier writeBarrier = graph.add(new ArrayWriteBarrier(object, location)); + graph.addAfterFixed(write, writeBarrier); } - graph.addAfterFixed(write, writeBarrier); + } } else if (n instanceof LoadHubNode) { LoadHubNode loadHub = (LoadHubNode) n; @@ -734,6 +740,10 @@ monitorSnippets.lower((MonitorEnterNode) n, tool); } else if (n instanceof MonitorExitNode) { monitorSnippets.lower((MonitorExitNode) n, tool); + } else if (n instanceof FieldWriteBarrier) { + writeBarrierSnippets.lower((FieldWriteBarrier) n, tool); + } else if (n instanceof ArrayWriteBarrier) { + writeBarrierSnippets.lower((ArrayWriteBarrier) n, tool); } else if (n instanceof TLABAllocateNode) { newObjectSnippets.lower((TLABAllocateNode) n, tool); } else if (n instanceof InitializeObjectNode) { diff -r af07019db85d -r 225c984588ee 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 13 18:46:24 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayWriteBarrier.java Tue Feb 19 16:53:10 2013 +0100 @@ -27,7 +27,7 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -public final class ArrayWriteBarrier extends WriteBarrier implements LIRLowerable { +public final class ArrayWriteBarrier extends WriteBarrier implements Lowerable { @Input private ValueNode object; @Input private LocationNode location; @@ -45,9 +45,7 @@ this.location = location; } - @Override - public void generate(LIRGeneratorTool gen) { - Value addr = gen.emitLea(gen.makeAddress(location(), object())); - generateBarrier(addr, gen); + public void lower(LoweringTool generator) { + generator.getRuntime().lower(this, generator); } } diff -r af07019db85d -r 225c984588ee graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/FieldWriteBarrier.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/FieldWriteBarrier.java Wed Feb 13 18:46:24 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/FieldWriteBarrier.java Tue Feb 19 16:53:10 2013 +0100 @@ -22,11 +22,10 @@ */ package com.oracle.graal.hotspot.nodes; -import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -public final class FieldWriteBarrier extends WriteBarrier implements LIRLowerable { +public final class FieldWriteBarrier extends WriteBarrier implements Lowerable { @Input private ValueNode object; @@ -38,10 +37,7 @@ this.object = object; } - @Override - public void generate(LIRGeneratorTool generator) { - Value obj = generator.newVariable(generator.target().wordKind); - generator.emitMove(generator.operand(object()), obj); - generateBarrier(obj, generator); + public void lower(LoweringTool generator) { + generator.getRuntime().lower(this, generator); } } diff -r af07019db85d -r 225c984588ee graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/WriteBarrierSnippets.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/WriteBarrierSnippets.java Tue Feb 19 16:53:10 2013 +0100 @@ -0,0 +1,123 @@ +/* + * 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.snippets; + +import static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*; +import static com.oracle.graal.snippets.SnippetTemplate.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.snippets.*; +import com.oracle.graal.snippets.Snippet.Parameter; +import com.oracle.graal.snippets.SnippetTemplate.AbstractTemplates; +import com.oracle.graal.snippets.SnippetTemplate.Arguments; +import com.oracle.graal.snippets.SnippetTemplate.Key; +import com.oracle.graal.word.*; + +public class WriteBarrierSnippets implements SnippetsInterface { + + @Snippet + public static void g1PreWriteBarrier(@Parameter("object") Object object) { + + } + + @Snippet + public static void g1PostWriteBarrier(@Parameter("object") Object object) { + + } + + private static void trace(boolean enabled, String format, WordBase value) { + if (enabled) { + Log.printf(format, value.rawValue()); + } + } + + @Snippet + public static void serialFieldWriteBarrier(@Parameter("object") Object object) { + // verifyOop(object); + Pointer oop = Word.fromObject(object); + 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())); + } + base.writeWord(displacement, Word.zero()); + } + + @Snippet + public static void serialArrayWriteBarrier(@Parameter("object") Object object) { + // verifyOop(object); + Pointer oop = Word.fromObject(object); + 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())); + } + base.writeWord(displacement, Word.zero()); + } + + public static class Templates extends AbstractTemplates { + + private final ResolvedJavaMethod serialFieldWriteBarrier; + private final ResolvedJavaMethod serialArrayWriteBarrier; + private final ResolvedJavaMethod g1PreWriteBarrier; + private final ResolvedJavaMethod g1PostWriteBarrier; + private final boolean useG1GC; + + 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); + g1PreWriteBarrier = snippet("g1PreWriteBarrier", Object.class); + g1PostWriteBarrier = snippet("g1PostWriteBarrier", Object.class); + this.useG1GC = useG1GC; + } + + public void lower(ArrayWriteBarrier arrayWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) { + ResolvedJavaMethod method = !useG1GC ? serialArrayWriteBarrier : serialArrayWriteBarrier; + Key key = new Key(method); + Arguments arguments = new Arguments(); + arguments.add("object", arrayWriteBarrier.object()); + SnippetTemplate template = cache.get(key, assumptions); + template.instantiate(runtime, arrayWriteBarrier, DEFAULT_REPLACER, arguments); + } + + public void lower(FieldWriteBarrier fieldWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) { + ResolvedJavaMethod method = !useG1GC ? serialFieldWriteBarrier : 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); + } + } +} diff -r af07019db85d -r 225c984588ee src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Wed Feb 13 18:46:24 2013 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Tue Feb 19 16:53:10 2013 +0100 @@ -614,6 +614,7 @@ set_boolean("usePopCountInstruction", UsePopCountInstruction); set_boolean("useAESIntrinsics", UseAESIntrinsics); set_boolean("useTLAB", UseTLAB); + set_boolean("useG1GC", UseG1GC); set_int("codeEntryAlignment", CodeEntryAlignment); set_int("vmPageSize", os::vm_page_size()); set_int("stackShadowPages", StackShadowPages);