changeset 8488:225c984588ee

-Snippetization of CMS write barriers
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Tue, 19 Feb 2013 16:53:10 +0100
parents af07019db85d
children 92d21814cf7b
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayWriteBarrier.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/FieldWriteBarrier.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/WriteBarrierSnippets.java src/share/vm/graal/graalCompilerToVM.cpp
diffstat 6 files changed, 145 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- 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;
--- 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) {
--- 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);
     }
 }
--- 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);
     }
 }
--- /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<WriteBarrierSnippets> {
+
+        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);
+        }
+    }
+}
--- 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);