changeset 8492:286a49d423c9

-Snippetization of CMS WriteBarriers
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Mon, 25 Feb 2013 11:08:06 +0100
parents 9cf5e381df05
children 9412b1915547
files 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/WriteBarrierPost.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPre.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/WriteBarrierSnippets.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadArrayElementAddressNode.java graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java src/share/vm/graal/graalRuntime.cpp
diffstat 10 files changed, 120 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- 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)));
                     }
                 }
             }
--- 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;
     }
--- 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) {
--- 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) {
--- 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
--- 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);
         }
+
     }
 }
--- /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);
+    }
+}
--- 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();
--- 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())));
--- 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))