mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
6937142: G1: improvements to debugging output (S-M)
Various fixes to the G1 debugging output. Reviewed-by: johnc, iveresov
This commit is contained in:
parent
f5197d0d36
commit
9b4fc8fc23
5 changed files with 133 additions and 88 deletions
|
@ -767,7 +767,8 @@ void ConcurrentMark::checkpointRootsInitialPre() {
|
||||||
_has_aborted = false;
|
_has_aborted = false;
|
||||||
|
|
||||||
if (G1PrintReachableAtInitialMark) {
|
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.
|
// Initialise marking structures. This has to be done in a STW phase.
|
||||||
|
@ -1979,19 +1980,21 @@ void ConcurrentMark::checkpointRootsFinalWork() {
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
|
|
||||||
class ReachablePrinterOopClosure: public OopClosure {
|
class PrintReachableOopClosure: public OopClosure {
|
||||||
private:
|
private:
|
||||||
G1CollectedHeap* _g1h;
|
G1CollectedHeap* _g1h;
|
||||||
CMBitMapRO* _bitmap;
|
CMBitMapRO* _bitmap;
|
||||||
outputStream* _out;
|
outputStream* _out;
|
||||||
bool _use_prev_marking;
|
bool _use_prev_marking;
|
||||||
|
bool _all;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ReachablePrinterOopClosure(CMBitMapRO* bitmap,
|
PrintReachableOopClosure(CMBitMapRO* bitmap,
|
||||||
outputStream* out,
|
outputStream* out,
|
||||||
bool use_prev_marking) :
|
bool use_prev_marking,
|
||||||
|
bool all) :
|
||||||
_g1h(G1CollectedHeap::heap()),
|
_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(narrowOop* p) { do_oop_work(p); }
|
||||||
void do_oop( oop* p) { do_oop_work(p); }
|
void do_oop( oop* p) { do_oop_work(p); }
|
||||||
|
@ -2001,9 +2004,11 @@ public:
|
||||||
const char* str = NULL;
|
const char* str = NULL;
|
||||||
const char* str2 = "";
|
const char* str2 = "";
|
||||||
|
|
||||||
if (!_g1h->is_in_g1_reserved(obj))
|
if (obj == NULL) {
|
||||||
str = "outside G1 reserved";
|
str = "";
|
||||||
else {
|
} else if (!_g1h->is_in_g1_reserved(obj)) {
|
||||||
|
str = " O";
|
||||||
|
} else {
|
||||||
HeapRegion* hr = _g1h->heap_region_containing(obj);
|
HeapRegion* hr = _g1h->heap_region_containing(obj);
|
||||||
guarantee(hr != NULL, "invariant");
|
guarantee(hr != NULL, "invariant");
|
||||||
bool over_tams = false;
|
bool over_tams = false;
|
||||||
|
@ -2012,74 +2017,67 @@ public:
|
||||||
} else {
|
} else {
|
||||||
over_tams = hr->obj_allocated_since_next_marking(obj);
|
over_tams = hr->obj_allocated_since_next_marking(obj);
|
||||||
}
|
}
|
||||||
|
bool marked = _bitmap->isMarked((HeapWord*) obj);
|
||||||
|
|
||||||
if (over_tams) {
|
if (over_tams) {
|
||||||
str = "over TAMS";
|
str = " >";
|
||||||
if (_bitmap->isMarked((HeapWord*) obj)) {
|
if (marked) {
|
||||||
str2 = " AND MARKED";
|
str2 = " AND MARKED";
|
||||||
}
|
}
|
||||||
} else if (_bitmap->isMarked((HeapWord*) obj)) {
|
} else if (marked) {
|
||||||
str = "marked";
|
str = " M";
|
||||||
} else {
|
} 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);
|
p, (void*) obj, str, str2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ReachablePrinterClosure: public BitMapClosure {
|
class PrintReachableObjectClosure : public ObjectClosure {
|
||||||
private:
|
private:
|
||||||
CMBitMapRO* _bitmap;
|
CMBitMapRO* _bitmap;
|
||||||
outputStream* _out;
|
outputStream* _out;
|
||||||
bool _use_prev_marking;
|
bool _use_prev_marking;
|
||||||
|
bool _all;
|
||||||
|
HeapRegion* _hr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ReachablePrinterClosure(CMBitMapRO* bitmap,
|
PrintReachableObjectClosure(CMBitMapRO* bitmap,
|
||||||
outputStream* out,
|
outputStream* out,
|
||||||
bool use_prev_marking) :
|
bool use_prev_marking,
|
||||||
_bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { }
|
bool all,
|
||||||
|
HeapRegion* hr) :
|
||||||
bool do_bit(size_t offset) {
|
_bitmap(bitmap), _out(out),
|
||||||
HeapWord* addr = _bitmap->offsetToHeapWord(offset);
|
_use_prev_marking(use_prev_marking), _all(all), _hr(hr) { }
|
||||||
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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ObjInRegionReachablePrinterClosure : public ObjectClosure {
|
|
||||||
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) {
|
void do_object(oop o) {
|
||||||
ReachablePrinterOopClosure oopCl(_bitmap, _out, _use_prev_marking);
|
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;
|
||||||
|
|
||||||
_out->print_cr(" obj "PTR_FORMAT" (over TAMS)", (void*) o);
|
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);
|
o->oop_iterate(&oopCl);
|
||||||
_out->print_cr("");
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class RegionReachablePrinterClosure : public HeapRegionClosure {
|
class PrintReachableRegionClosure : public HeapRegionClosure {
|
||||||
private:
|
private:
|
||||||
CMBitMapRO* _bitmap;
|
CMBitMapRO* _bitmap;
|
||||||
outputStream* _out;
|
outputStream* _out;
|
||||||
bool _use_prev_marking;
|
bool _use_prev_marking;
|
||||||
|
bool _all;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool doHeapRegion(HeapRegion* hr) {
|
bool doHeapRegion(HeapRegion* hr) {
|
||||||
|
@ -2094,22 +2092,35 @@ public:
|
||||||
}
|
}
|
||||||
_out->print_cr("** ["PTR_FORMAT", "PTR_FORMAT"] top: "PTR_FORMAT" "
|
_out->print_cr("** ["PTR_FORMAT", "PTR_FORMAT"] top: "PTR_FORMAT" "
|
||||||
"TAMS: "PTR_FORMAT, b, e, t, p);
|
"TAMS: "PTR_FORMAT, b, e, t, p);
|
||||||
_out->print_cr("");
|
_out->cr();
|
||||||
|
|
||||||
ObjInRegionReachablePrinterClosure ocl(_bitmap, _out, _use_prev_marking);
|
HeapWord* from = b;
|
||||||
hr->object_iterate_mem_careful(MemRegion(p, t), &ocl);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionReachablePrinterClosure(CMBitMapRO* bitmap,
|
PrintReachableRegionClosure(CMBitMapRO* bitmap,
|
||||||
outputStream* out,
|
outputStream* out,
|
||||||
bool use_prev_marking) :
|
bool use_prev_marking,
|
||||||
_bitmap(bitmap), _out(out), _use_prev_marking(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) {
|
void ConcurrentMark::print_reachable(const char* str,
|
||||||
gclog_or_tty->print_cr("== Doing reachable object dump... ");
|
bool use_prev_marking,
|
||||||
|
bool all) {
|
||||||
|
gclog_or_tty->cr();
|
||||||
|
gclog_or_tty->print_cr("== Doing heap dump... ");
|
||||||
|
|
||||||
if (G1PrintReachableBaseFile == NULL) {
|
if (G1PrintReachableBaseFile == NULL) {
|
||||||
gclog_or_tty->print_cr(" #### error: no base file defined");
|
gclog_or_tty->print_cr(" #### error: no base file defined");
|
||||||
|
@ -2144,19 +2155,14 @@ void ConcurrentMark::print_reachable(bool use_prev_marking, const char* str) {
|
||||||
out->print_cr("-- USING %s", (use_prev_marking) ? "PTAMS" : "NTAMS");
|
out->print_cr("-- USING %s", (use_prev_marking) ? "PTAMS" : "NTAMS");
|
||||||
out->cr();
|
out->cr();
|
||||||
|
|
||||||
RegionReachablePrinterClosure rcl(bitmap, out, use_prev_marking);
|
out->print_cr("--- ITERATING OVER REGIONS");
|
||||||
out->print_cr("--- ITERATING OVER REGIONS WITH TAMS < TOP");
|
|
||||||
out->cr();
|
out->cr();
|
||||||
|
PrintReachableRegionClosure rcl(bitmap, out, use_prev_marking, all);
|
||||||
_g1h->heap_region_iterate(&rcl);
|
_g1h->heap_region_iterate(&rcl);
|
||||||
out->cr();
|
out->cr();
|
||||||
|
|
||||||
ReachablePrinterClosure cl(bitmap, out, use_prev_marking);
|
|
||||||
out->print_cr("--- ITERATING OVER MARKED OBJECTS ON THE BITMAP");
|
|
||||||
out->cr();
|
|
||||||
bitmap->iterate(&cl);
|
|
||||||
out->cr();
|
|
||||||
|
|
||||||
gclog_or_tty->print_cr(" done");
|
gclog_or_tty->print_cr(" done");
|
||||||
|
gclog_or_tty->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // PRODUCT
|
#endif // PRODUCT
|
||||||
|
|
|
@ -652,11 +652,24 @@ public:
|
||||||
// we do nothing.
|
// we do nothing.
|
||||||
void markAndGrayObjectIfNecessary(oop p);
|
void markAndGrayObjectIfNecessary(oop p);
|
||||||
|
|
||||||
// This iterates over the marking bitmap (either prev or next) and
|
// It iterates over the heap and for each object it comes across it
|
||||||
// prints out all objects that are marked on the bitmap and indicates
|
// will dump the contents of its reference fields, as well as
|
||||||
// whether what they point to is also marked or not. It also iterates
|
// liveness information for the object and its referents. The dump
|
||||||
// the objects over TAMS (either prev or next).
|
// will be written to a file with the following name:
|
||||||
void print_reachable(bool use_prev_marking, const char* str);
|
// 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).
|
// Clear the next marking bitmap (will be called concurrently).
|
||||||
void clearNextBitmap();
|
void clearNextBitmap();
|
||||||
|
|
|
@ -2397,8 +2397,8 @@ void G1CollectedHeap::verify(bool allow_dirty,
|
||||||
print_on(gclog_or_tty, true /* extended */);
|
print_on(gclog_or_tty, true /* extended */);
|
||||||
gclog_or_tty->print_cr("");
|
gclog_or_tty->print_cr("");
|
||||||
if (VerifyDuringGC && G1VerifyDuringGCPrintReachable) {
|
if (VerifyDuringGC && G1VerifyDuringGCPrintReachable) {
|
||||||
concurrent_mark()->print_reachable(use_prev_marking,
|
concurrent_mark()->print_reachable("at-verification-failure",
|
||||||
"failed-verification");
|
use_prev_marking, false /* all */);
|
||||||
}
|
}
|
||||||
gclog_or_tty->flush();
|
gclog_or_tty->flush();
|
||||||
}
|
}
|
||||||
|
@ -3118,6 +3118,11 @@ void G1CollectedHeap::get_gc_alloc_regions() {
|
||||||
} else {
|
} else {
|
||||||
// the region was retained from the last collection
|
// the region was retained from the last collection
|
||||||
++_gc_alloc_region_counts[ap];
|
++_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) {
|
if (alloc_region != NULL) {
|
||||||
|
|
|
@ -2942,10 +2942,11 @@ record_concurrent_mark_cleanup_end(size_t freed_bytes,
|
||||||
void G1CollectorPolicy::
|
void G1CollectorPolicy::
|
||||||
add_to_collection_set(HeapRegion* hr) {
|
add_to_collection_set(HeapRegion* hr) {
|
||||||
if (G1PrintHeapRegions) {
|
if (G1PrintHeapRegions) {
|
||||||
gclog_or_tty->print_cr("added region to cset %d:["PTR_FORMAT", "PTR_FORMAT"], "
|
gclog_or_tty->print_cr("added region to cset "
|
||||||
"top "PTR_FORMAT", young %s",
|
"%d:["PTR_FORMAT", "PTR_FORMAT"], "
|
||||||
|
"top "PTR_FORMAT", %s",
|
||||||
hr->hrs_index(), hr->bottom(), hr->end(),
|
hr->hrs_index(), hr->bottom(), hr->end(),
|
||||||
hr->top(), (hr->is_young()) ? "YES" : "NO");
|
hr->top(), hr->is_young() ? "YOUNG" : "NOT_YOUNG");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_g1->mark_in_progress())
|
if (_g1->mark_in_progress())
|
||||||
|
|
|
@ -75,6 +75,16 @@ public:
|
||||||
virtual void do_oop(narrowOop* p) { do_oop_work(p); }
|
virtual void do_oop(narrowOop* p) { do_oop_work(p); }
|
||||||
virtual void do_oop( oop* 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 <class T> void do_oop_work(T* p) {
|
template <class T> void do_oop_work(T* p) {
|
||||||
assert(_containing_obj != NULL, "Precondition");
|
assert(_containing_obj != NULL, "Precondition");
|
||||||
assert(!_g1h->is_obj_dead_cond(_containing_obj, _use_prev_marking),
|
assert(!_g1h->is_obj_dead_cond(_containing_obj, _use_prev_marking),
|
||||||
|
@ -90,21 +100,29 @@ public:
|
||||||
gclog_or_tty->print_cr("----------");
|
gclog_or_tty->print_cr("----------");
|
||||||
}
|
}
|
||||||
if (!_g1h->is_in_closed_subset(obj)) {
|
if (!_g1h->is_in_closed_subset(obj)) {
|
||||||
|
HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
|
||||||
gclog_or_tty->print_cr("Field "PTR_FORMAT
|
gclog_or_tty->print_cr("Field "PTR_FORMAT
|
||||||
" of live obj "PTR_FORMAT
|
" of live obj "PTR_FORMAT" in region "
|
||||||
" points to obj "PTR_FORMAT
|
"["PTR_FORMAT", "PTR_FORMAT")",
|
||||||
" not in the heap.",
|
p, (void*) _containing_obj,
|
||||||
p, (void*) _containing_obj, (void*) 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 {
|
} 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
|
gclog_or_tty->print_cr("Field "PTR_FORMAT
|
||||||
" of live obj "PTR_FORMAT
|
" of live obj "PTR_FORMAT" in region "
|
||||||
" points to dead obj "PTR_FORMAT".",
|
"["PTR_FORMAT", "PTR_FORMAT")",
|
||||||
p, (void*) _containing_obj, (void*) obj);
|
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("----------");
|
gclog_or_tty->print_cr("----------");
|
||||||
_failures = true;
|
_failures = true;
|
||||||
failed = true;
|
failed = true;
|
||||||
|
@ -723,6 +741,8 @@ void HeapRegion::print_on(outputStream* st) const {
|
||||||
else
|
else
|
||||||
st->print(" ");
|
st->print(" ");
|
||||||
st->print(" %5d", _gc_time_stamp);
|
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);
|
G1OffsetTableContigSpace::print_on(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue