# HG changeset patch # User Christos Kotselidis # Date 1373209842 -7200 # Node ID 260e75dc4b6e8067932dd6bacf31e465fb161ba0 # Parent 2fdd0e263160a5345717ee78609ff7a6a2fd08ce Add tracing info to G1 Write Barriers diff -r 2fdd0e263160 -r 260e75dc4b6e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java --- 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); + } }