# HG changeset patch # User tonyp # Date 1269978183 14400 # Node ID 7666957bc44d75c33b99ceec104aa04582acc303 # Parent 0bfd3fb241508b54046a8614753a86af182d2a49 6937142: G1: improvements to debugging output (S-M) Summary: Various fixes to the G1 debugging output. Reviewed-by: johnc, iveresov diff -r 0bfd3fb24150 -r 7666957bc44d src/share/vm/gc_implementation/g1/concurrentMark.cpp --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp Tue Apr 13 13:52:10 2010 -0700 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp Tue Mar 30 15:43:03 2010 -0400 @@ -767,7 +767,8 @@ _has_aborted = false; if (G1PrintReachableAtInitialMark) { - print_reachable(true, "before"); + print_reachable("at-cycle-start", + true /* use_prev_marking */, true /* all */); } // Initialise marking structures. This has to be done in a STW phase. @@ -1979,19 +1980,21 @@ #ifndef PRODUCT -class ReachablePrinterOopClosure: public OopClosure { +class PrintReachableOopClosure: public OopClosure { private: G1CollectedHeap* _g1h; CMBitMapRO* _bitmap; outputStream* _out; bool _use_prev_marking; + bool _all; public: - ReachablePrinterOopClosure(CMBitMapRO* bitmap, - outputStream* out, - bool use_prev_marking) : + PrintReachableOopClosure(CMBitMapRO* bitmap, + outputStream* out, + bool use_prev_marking, + bool all) : _g1h(G1CollectedHeap::heap()), - _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { } + _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking), _all(all) { } void do_oop(narrowOop* p) { do_oop_work(p); } void do_oop( oop* p) { do_oop_work(p); } @@ -2001,9 +2004,11 @@ const char* str = NULL; const char* str2 = ""; - if (!_g1h->is_in_g1_reserved(obj)) - str = "outside G1 reserved"; - else { + if (obj == NULL) { + str = ""; + } else if (!_g1h->is_in_g1_reserved(obj)) { + str = " O"; + } else { HeapRegion* hr = _g1h->heap_region_containing(obj); guarantee(hr != NULL, "invariant"); bool over_tams = false; @@ -2012,74 +2017,67 @@ } else { over_tams = hr->obj_allocated_since_next_marking(obj); } + bool marked = _bitmap->isMarked((HeapWord*) obj); if (over_tams) { - str = "over TAMS"; - if (_bitmap->isMarked((HeapWord*) obj)) { + str = " >"; + if (marked) { str2 = " AND MARKED"; } - } else if (_bitmap->isMarked((HeapWord*) obj)) { - str = "marked"; + } else if (marked) { + str = " M"; } else { - str = "#### NOT MARKED ####"; + str = " NOT"; } } - _out->print_cr(" "PTR_FORMAT" contains "PTR_FORMAT" %s%s", + _out->print_cr(" "PTR_FORMAT": "PTR_FORMAT"%s%s", p, (void*) obj, str, str2); } }; -class ReachablePrinterClosure: public BitMapClosure { +class PrintReachableObjectClosure : public ObjectClosure { private: CMBitMapRO* _bitmap; outputStream* _out; bool _use_prev_marking; + bool _all; + HeapRegion* _hr; public: - ReachablePrinterClosure(CMBitMapRO* bitmap, - outputStream* out, - bool use_prev_marking) : - _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { } - - bool do_bit(size_t offset) { - HeapWord* addr = _bitmap->offsetToHeapWord(offset); - ReachablePrinterOopClosure oopCl(_bitmap, _out, _use_prev_marking); - - _out->print_cr(" obj "PTR_FORMAT", offset %10d (marked)", addr, offset); - oop(addr)->oop_iterate(&oopCl); - _out->print_cr(""); - - return true; + PrintReachableObjectClosure(CMBitMapRO* bitmap, + outputStream* out, + bool use_prev_marking, + bool all, + HeapRegion* hr) : + _bitmap(bitmap), _out(out), + _use_prev_marking(use_prev_marking), _all(all), _hr(hr) { } + + void do_object(oop o) { + bool over_tams; + if (_use_prev_marking) { + over_tams = _hr->obj_allocated_since_prev_marking(o); + } else { + over_tams = _hr->obj_allocated_since_next_marking(o); + } + bool marked = _bitmap->isMarked((HeapWord*) o); + bool print_it = _all || over_tams || marked; + + if (print_it) { + _out->print_cr(" "PTR_FORMAT"%s", + o, (over_tams) ? " >" : (marked) ? " M" : ""); + PrintReachableOopClosure oopCl(_bitmap, _out, _use_prev_marking, _all); + o->oop_iterate(&oopCl); + } } }; -class ObjInRegionReachablePrinterClosure : public ObjectClosure { +class PrintReachableRegionClosure : public HeapRegionClosure { private: CMBitMapRO* _bitmap; outputStream* _out; bool _use_prev_marking; - -public: - ObjInRegionReachablePrinterClosure(CMBitMapRO* bitmap, - outputStream* out, - bool use_prev_marking) : - _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { } - - void do_object(oop o) { - ReachablePrinterOopClosure oopCl(_bitmap, _out, _use_prev_marking); - - _out->print_cr(" obj "PTR_FORMAT" (over TAMS)", (void*) o); - o->oop_iterate(&oopCl); - _out->print_cr(""); - } -}; - -class RegionReachablePrinterClosure : public HeapRegionClosure { -private: - CMBitMapRO* _bitmap; - outputStream* _out; - bool _use_prev_marking; + bool _all; public: bool doHeapRegion(HeapRegion* hr) { @@ -2094,22 +2092,35 @@ } _out->print_cr("** ["PTR_FORMAT", "PTR_FORMAT"] top: "PTR_FORMAT" " "TAMS: "PTR_FORMAT, b, e, t, p); - _out->print_cr(""); - - ObjInRegionReachablePrinterClosure ocl(_bitmap, _out, _use_prev_marking); - hr->object_iterate_mem_careful(MemRegion(p, t), &ocl); + _out->cr(); + + HeapWord* from = b; + HeapWord* to = t; + + if (to > from) { + _out->print_cr("Objects in ["PTR_FORMAT", "PTR_FORMAT"]", from, to); + _out->cr(); + PrintReachableObjectClosure ocl(_bitmap, _out, + _use_prev_marking, _all, hr); + hr->object_iterate_mem_careful(MemRegion(from, to), &ocl); + _out->cr(); + } return false; } - RegionReachablePrinterClosure(CMBitMapRO* bitmap, - outputStream* out, - bool use_prev_marking) : - _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { } + PrintReachableRegionClosure(CMBitMapRO* bitmap, + outputStream* out, + bool use_prev_marking, + bool all) : + _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking), _all(all) { } }; -void ConcurrentMark::print_reachable(bool use_prev_marking, const char* str) { - gclog_or_tty->print_cr("== Doing reachable object dump... "); +void ConcurrentMark::print_reachable(const char* str, + bool use_prev_marking, + bool all) { + gclog_or_tty->cr(); + gclog_or_tty->print_cr("== Doing heap dump... "); if (G1PrintReachableBaseFile == NULL) { gclog_or_tty->print_cr(" #### error: no base file defined"); @@ -2144,19 +2155,14 @@ out->print_cr("-- USING %s", (use_prev_marking) ? "PTAMS" : "NTAMS"); out->cr(); - RegionReachablePrinterClosure rcl(bitmap, out, use_prev_marking); - out->print_cr("--- ITERATING OVER REGIONS WITH TAMS < TOP"); - out->cr(); - _g1h->heap_region_iterate(&rcl); + out->print_cr("--- ITERATING OVER REGIONS"); out->cr(); - - ReachablePrinterClosure cl(bitmap, out, use_prev_marking); - out->print_cr("--- ITERATING OVER MARKED OBJECTS ON THE BITMAP"); - out->cr(); - bitmap->iterate(&cl); + PrintReachableRegionClosure rcl(bitmap, out, use_prev_marking, all); + _g1h->heap_region_iterate(&rcl); out->cr(); gclog_or_tty->print_cr(" done"); + gclog_or_tty->flush(); } #endif // PRODUCT diff -r 0bfd3fb24150 -r 7666957bc44d src/share/vm/gc_implementation/g1/concurrentMark.hpp --- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp Tue Apr 13 13:52:10 2010 -0700 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp Tue Mar 30 15:43:03 2010 -0400 @@ -652,11 +652,24 @@ // we do nothing. void markAndGrayObjectIfNecessary(oop p); - // This iterates over the marking bitmap (either prev or next) and - // prints out all objects that are marked on the bitmap and indicates - // whether what they point to is also marked or not. It also iterates - // the objects over TAMS (either prev or next). - void print_reachable(bool use_prev_marking, const char* str); + // It iterates over the heap and for each object it comes across it + // will dump the contents of its reference fields, as well as + // liveness information for the object and its referents. The dump + // will be written to a file with the following name: + // G1PrintReachableBaseFile + "." + str. use_prev_marking decides + // whether the prev (use_prev_marking == true) or next + // (use_prev_marking == false) marking information will be used to + // determine the liveness of each object / referent. If all is true, + // all objects in the heap will be dumped, otherwise only the live + // ones. In the dump the following symbols / abbreviations are used: + // M : an explicitly live object (its bitmap bit is set) + // > : an implicitly live object (over tams) + // O : an object outside the G1 heap (typically: in the perm gen) + // NOT : a reference field whose referent is not live + // AND MARKED : indicates that an object is both explicitly and + // implicitly live (it should be one or the other, not both) + void print_reachable(const char* str, + bool use_prev_marking, bool all) PRODUCT_RETURN; // Clear the next marking bitmap (will be called concurrently). void clearNextBitmap(); diff -r 0bfd3fb24150 -r 7666957bc44d src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Apr 13 13:52:10 2010 -0700 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Mar 30 15:43:03 2010 -0400 @@ -2397,8 +2397,8 @@ print_on(gclog_or_tty, true /* extended */); gclog_or_tty->print_cr(""); if (VerifyDuringGC && G1VerifyDuringGCPrintReachable) { - concurrent_mark()->print_reachable(use_prev_marking, - "failed-verification"); + concurrent_mark()->print_reachable("at-verification-failure", + use_prev_marking, false /* all */); } gclog_or_tty->flush(); } @@ -3118,6 +3118,11 @@ } else { // the region was retained from the last collection ++_gc_alloc_region_counts[ap]; + if (G1PrintHeapRegions) { + gclog_or_tty->print_cr("new alloc region %d:["PTR_FORMAT", "PTR_FORMAT"], " + "top "PTR_FORMAT, + alloc_region->hrs_index(), alloc_region->bottom(), alloc_region->end(), alloc_region->top()); + } } if (alloc_region != NULL) { diff -r 0bfd3fb24150 -r 7666957bc44d src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Tue Apr 13 13:52:10 2010 -0700 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Tue Mar 30 15:43:03 2010 -0400 @@ -2942,10 +2942,11 @@ void G1CollectorPolicy:: add_to_collection_set(HeapRegion* hr) { if (G1PrintHeapRegions) { - gclog_or_tty->print_cr("added region to cset %d:["PTR_FORMAT", "PTR_FORMAT"], " - "top "PTR_FORMAT", young %s", - hr->hrs_index(), hr->bottom(), hr->end(), - hr->top(), (hr->is_young()) ? "YES" : "NO"); + gclog_or_tty->print_cr("added region to cset " + "%d:["PTR_FORMAT", "PTR_FORMAT"], " + "top "PTR_FORMAT", %s", + hr->hrs_index(), hr->bottom(), hr->end(), + hr->top(), hr->is_young() ? "YOUNG" : "NOT_YOUNG"); } if (_g1->mark_in_progress()) diff -r 0bfd3fb24150 -r 7666957bc44d src/share/vm/gc_implementation/g1/heapRegion.cpp --- a/src/share/vm/gc_implementation/g1/heapRegion.cpp Tue Apr 13 13:52:10 2010 -0700 +++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp Tue Mar 30 15:43:03 2010 -0400 @@ -75,6 +75,16 @@ virtual void do_oop(narrowOop* p) { do_oop_work(p); } virtual void do_oop( oop* p) { do_oop_work(p); } + void print_object(outputStream* out, oop obj) { +#ifdef PRODUCT + klassOop k = obj->klass(); + const char* class_name = instanceKlass::cast(k)->external_name(); + out->print_cr("class name %s", class_name); +#else // PRODUCT + obj->print_on(out); +#endif // PRODUCT + } + template void do_oop_work(T* p) { assert(_containing_obj != NULL, "Precondition"); assert(!_g1h->is_obj_dead_cond(_containing_obj, _use_prev_marking), @@ -90,21 +100,29 @@ gclog_or_tty->print_cr("----------"); } if (!_g1h->is_in_closed_subset(obj)) { - gclog_or_tty->print_cr("Field "PTR_FORMAT - " of live obj "PTR_FORMAT - " points to obj "PTR_FORMAT - " not in the heap.", - p, (void*) _containing_obj, (void*) obj); - } else { + HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); gclog_or_tty->print_cr("Field "PTR_FORMAT - " of live obj "PTR_FORMAT - " points to dead obj "PTR_FORMAT".", - p, (void*) _containing_obj, (void*) obj); + " of live obj "PTR_FORMAT" in region " + "["PTR_FORMAT", "PTR_FORMAT")", + p, (void*) _containing_obj, + from->bottom(), from->end()); + print_object(gclog_or_tty, _containing_obj); + gclog_or_tty->print_cr("points to obj "PTR_FORMAT" not in the heap", + (void*) obj); + } else { + HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); + HeapRegion* to = _g1h->heap_region_containing((HeapWord*)obj); + gclog_or_tty->print_cr("Field "PTR_FORMAT + " of live obj "PTR_FORMAT" in region " + "["PTR_FORMAT", "PTR_FORMAT")", + p, (void*) _containing_obj, + from->bottom(), from->end()); + print_object(gclog_or_tty, _containing_obj); + gclog_or_tty->print_cr("points to dead obj "PTR_FORMAT" in region " + "["PTR_FORMAT", "PTR_FORMAT")", + (void*) obj, to->bottom(), to->end()); + print_object(gclog_or_tty, obj); } - gclog_or_tty->print_cr("Live obj:"); - _containing_obj->print_on(gclog_or_tty); - gclog_or_tty->print_cr("Bad referent:"); - obj->print_on(gclog_or_tty); gclog_or_tty->print_cr("----------"); _failures = true; failed = true; @@ -723,6 +741,8 @@ else st->print(" "); st->print(" %5d", _gc_time_stamp); + st->print(" PTAMS "PTR_FORMAT" NTAMS "PTR_FORMAT, + prev_top_at_mark_start(), next_top_at_mark_start()); G1OffsetTableContigSpace::print_on(st); }