changeset 10620:260e75dc4b6e

Add tracing info to G1 Write Barriers
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Sun, 07 Jul 2013 17:10:42 +0200
parents 2fdd0e263160
children 7f1dbbfb9adf
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java
diffstat 1 files changed, 58 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Sun Jul 07 17:09:46 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Sun Jul 07 17:10:42 2013 +0200
@@ -28,11 +28,13 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.Node.*;
+import com.oracle.graal.graph.Node.ConstantNodeParameter;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
@@ -46,6 +48,7 @@
     private static final SnippetCounter.Group countersWriteBarriers = SnippetCounters.getValue() ? new SnippetCounter.Group("WriteBarriers") : null;
     private static final SnippetCounter serialFieldWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "serialFieldWriteBarrier", "Number of Serial Field Write Barriers");
     private static final SnippetCounter serialArrayWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "serialArrayWriteBarrier", "Number of Serial Array Write Barriers");
+    private static final int gcStartCycles = GraalOptions.GCDebugStartCycle.getValue();
 
     @Snippet
     public static void serialArrayWriteBarrier(Object obj, Object location, @ConstantParameter boolean usePrecise) {
@@ -85,19 +88,11 @@
         }
     }
 
-    /**
-     * Log method of debugging purposes.
-     */
-    static void log(boolean enabled, String format, WordBase value) {
-        if (enabled) {
-            Log.printf(format, value.rawValue());
-        }
-    }
-
     @Snippet
-    public static void g1PreWriteBarrier(Object object, Object expectedObject, Object location, @ConstantParameter boolean doLoad) {
+    public static void g1PreWriteBarrier(Object object, Object expectedObject, Object location, @ConstantParameter boolean doLoad, @ConstantParameter boolean trace) {
         Word thread = thread();
         Object fixedObject = FixedValueAnchorNode.getObject(object);
+        verifyOop(fixedObject);
         Object fixedExpectedObject = FixedValueAnchorNode.getObject(expectedObject);
         Word field = (Word) Word.fromArray(fixedObject, location);
         Word previousOop = (Word) Word.fromObject(fixedExpectedObject);
@@ -105,13 +100,27 @@
         Word bufferAddress = thread.readWord(g1SATBQueueBufferOffset());
         Word indexAddress = thread.add(g1SATBQueueIndexOffset());
         Word indexValue = indexAddress.readWord(0);
-
+        int gcCycle = 0;
+        if (trace) {
+            gcCycle = (int) Word.unsigned(HotSpotReplacementsUtil.gcTotalCollectionsAddress()).readLong(0);
+            log(trace, "[%d] G1-Pre Thread %p Object %p\n", gcCycle, thread.rawValue(), Word.fromObject(fixedObject).rawValue());
+            log(trace, "[%d] G1-Pre Thread %p Expected Object %p\n", gcCycle, thread.rawValue(), Word.fromObject(fixedExpectedObject).rawValue());
+            log(trace, "[%d] G1-Pre Thread %p Field %p\n", gcCycle, thread.rawValue(), field.rawValue());
+            log(trace, "[%d] G1-Pre Thread %p Marking %d\n", gcCycle, thread.rawValue(), markingValue);
+            log(trace, "[%d] G1-Pre Thread %p DoLoad %d\n", gcCycle, thread.rawValue(), doLoad ? 1L : 0L);
+        }
         // If the concurrent marker is enabled, the barrier is issued.
         if (markingValue != (byte) 0) {
             // If the previous value has to be loaded (before the write), the load is issued.
             // The load is always issued except the cases of CAS and referent field.
             if (doLoad) {
                 previousOop = (Word) Word.fromObject(field.readObjectCompressed(0));
+                if (trace) {
+                    if (previousOop.notEqual(Word.zero())) {
+                        verifyOop(previousOop.toObject());
+                    }
+                    log(trace, "[%d] G1-Pre Thread %p Previous Object %p\n ", gcCycle, thread.rawValue(), previousOop.rawValue());
+                }
             }
             // If the previous value is null the barrier should not be issued.
             if (previousOop.notEqual(0)) {
@@ -131,10 +140,12 @@
     }
 
     @Snippet
-    public static void g1PostWriteBarrier(Object object, Object value, Object location, @ConstantParameter boolean usePrecise) {
+    public static void g1PostWriteBarrier(Object object, Object value, Object location, @ConstantParameter boolean usePrecise, @ConstantParameter boolean trace) {
         Word thread = thread();
         Object fixedObject = FixedValueAnchorNode.getObject(object);
         Object fixedValue = FixedValueAnchorNode.getObject(value);
+        verifyOop(fixedObject);
+        verifyOop(fixedValue);
         Word oop = (Word) Word.fromObject(fixedObject);
         Word field;
         if (usePrecise) {
@@ -142,7 +153,12 @@
         } else {
             field = oop;
         }
-
+        int gcCycle = 0;
+        if (trace) {
+            gcCycle = (int) Word.unsigned(HotSpotReplacementsUtil.gcTotalCollectionsAddress()).readLong(0);
+            log(trace, "[%d] G1-Post Thread: %p Object: %p Field: %p\n", gcCycle, thread.rawValue(), Word.fromObject(fixedObject).rawValue());
+            log(trace, "[%d] G1-Post Thread: %p Field: %p\n", gcCycle, thread.rawValue(), field.rawValue());
+        }
         Word writtenValue = (Word) Word.fromObject(fixedValue);
         Word bufferAddress = thread.readWord(g1CardQueueBufferOffset());
         Word indexAddress = thread.add(g1CardQueueIndexOffset());
@@ -169,6 +185,7 @@
                 byte cardByte = cardAddress.readByte(0);
                 // If the card is already dirty, (hence already enqueued) skip the insertion.
                 if (cardByte != (byte) 0) {
+                    log(trace, "[%d] G1-Post Thread: %p Card: %p \n", gcCycle, thread.rawValue(), Word.unsigned(cardByte).rawValue());
                     cardAddress.writeByte(0, (byte) 0);
                     // If the thread local card queue is full, issue a native call which will
                     // initialize a new one and add the card entry.
@@ -305,6 +322,7 @@
             args.add("expectedObject", writeBarrierPre.getExpectedObject());
             args.add("location", writeBarrierPre.getLocation());
             args.addConst("doLoad", writeBarrierPre.doLoad());
+            args.addConst("trace", traceBarrier());
             template(args).instantiate(runtime, writeBarrierPre, DEFAULT_REPLACER, args);
         }
 
@@ -314,6 +332,7 @@
             args.add("value", writeBarrierPost.getValue());
             args.add("location", writeBarrierPost.getLocation());
             args.addConst("usePrecise", writeBarrierPost.usePrecise());
+            args.addConst("trace", traceBarrier());
             template(args).instantiate(runtime, writeBarrierPost, DEFAULT_REPLACER, args);
         }
 
@@ -333,4 +352,29 @@
             template(args).instantiate(runtime, arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
         }
     }
+
+    /**
+     * Log method of debugging purposes.
+     */
+    private static void log(boolean enabled, String format, long value) {
+        if (enabled) {
+            Log.printf(format, value);
+        }
+    }
+
+    private static void log(boolean enabled, String format, long value1, long value2) {
+        if (enabled) {
+            Log.printf(format, value1, value2);
+        }
+    }
+
+    private static void log(boolean enabled, String format, long value1, long value2, long value3) {
+        if (enabled) {
+            Log.printf(format, value1, value2, value3);
+        }
+    }
+
+    private static boolean traceBarrier() {
+        return gcStartCycles > 0 && ((int) Word.unsigned(HotSpotReplacementsUtil.gcTotalCollectionsAddress()).readLong(0) > gcStartCycles);
+    }
 }