6966222: G1: simplify TaskQueue overflow handling

Reviewed-by: tonyp, ysr
This commit is contained in:
John Coomes 2010-08-09 05:41:05 -07:00
parent f8eed77f36
commit 7fe1c05c7c
5 changed files with 127 additions and 90 deletions

View file

@ -2710,6 +2710,35 @@ struct PrepareForRSScanningClosure : public HeapRegionClosure {
}
};
#if TASKQUEUE_STATS
void G1CollectedHeap::print_taskqueue_stats_hdr(outputStream* const st) {
st->print_raw_cr("GC Task Stats");
st->print_raw("thr "); TaskQueueStats::print_header(1, st); st->cr();
st->print_raw("--- "); TaskQueueStats::print_header(2, st); st->cr();
}
void G1CollectedHeap::print_taskqueue_stats(outputStream* const st) const {
print_taskqueue_stats_hdr(st);
TaskQueueStats totals;
const int n = MAX2(workers()->total_workers(), 1);
for (int i = 0; i < n; ++i) {
st->print("%3d ", i); task_queue(i)->stats.print(st); st->cr();
totals += task_queue(i)->stats;
}
st->print_raw("tot "); totals.print(st); st->cr();
DEBUG_ONLY(totals.verify());
}
void G1CollectedHeap::reset_taskqueue_stats() {
const int n = MAX2(workers()->total_workers(), 1);
for (int i = 0; i < n; ++i) {
task_queue(i)->stats.reset();
}
}
#endif // TASKQUEUE_STATS
void
G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
if (GC_locker::check_active_before_gc()) {
@ -2970,6 +2999,9 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
}
}
TASKQUEUE_STATS_ONLY(if (ParallelGCVerbose) print_taskqueue_stats());
TASKQUEUE_STATS_ONLY(reset_taskqueue_stats());
if (PrintHeapAtGC) {
Universe::print_heap_after_gc();
}
@ -3715,10 +3747,6 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, int queue_num)
_surviving_alloc_buffer(g1h->desired_plab_sz(GCAllocForSurvived)),
_tenured_alloc_buffer(g1h->desired_plab_sz(GCAllocForTenured)),
_age_table(false),
#if G1_DETAILED_STATS
_pushes(0), _pops(0), _steals(0),
_steal_attempts(0), _overflow_pushes(0),
#endif
_strong_roots_time(0), _term_time(0),
_alloc_buffer_waste(0), _undo_waste(0)
{
@ -3738,14 +3766,41 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, int queue_num)
_surviving_young_words = _surviving_young_words_base + PADDING_ELEM_NUM;
memset(_surviving_young_words, 0, real_length * sizeof(size_t));
_overflowed_refs = new OverflowQueue(10);
_alloc_buffers[GCAllocForSurvived] = &_surviving_alloc_buffer;
_alloc_buffers[GCAllocForTenured] = &_tenured_alloc_buffer;
_start = os::elapsedTime();
}
void
G1ParScanThreadState::print_termination_stats_hdr(outputStream* const st)
{
st->print_raw_cr("GC Termination Stats");
st->print_raw_cr(" elapsed --strong roots-- -------termination-------"
" ------waste (KiB)------");
st->print_raw_cr("thr ms ms % ms % attempts"
" total alloc undo");
st->print_raw_cr("--- --------- --------- ------ --------- ------ --------"
" ------- ------- -------");
}
void
G1ParScanThreadState::print_termination_stats(int i,
outputStream* const st) const
{
const double elapsed_ms = elapsed_time() * 1000.0;
const double s_roots_ms = strong_roots_time() * 1000.0;
const double term_ms = term_time() * 1000.0;
st->print_cr("%3d %9.2f %9.2f %6.2f "
"%9.2f %6.2f " SIZE_FORMAT_W(8) " "
SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7),
i, elapsed_ms, s_roots_ms, s_roots_ms * 100 / elapsed_ms,
term_ms, term_ms * 100 / elapsed_ms, term_attempts(),
(alloc_buffer_waste() + undo_waste()) * HeapWordSize / K,
alloc_buffer_waste() * HeapWordSize / K,
undo_waste() * HeapWordSize / K);
}
G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) :
_g1(g1), _g1_rem(_g1->g1_rem_set()), _cm(_g1->concurrent_mark()),
_par_scan_state(par_scan_state) { }
@ -3952,12 +4007,9 @@ public:
G1ParScanThreadState* pss = par_scan_state();
while (true) {
pss->trim_queue();
IF_G1_DETAILED_STATS(pss->note_steal_attempt());
StarTask stolen_task;
if (queues()->steal(pss->queue_num(), pss->hash_seed(), stolen_task)) {
IF_G1_DETAILED_STATS(pss->note_steal());
// slightly paranoid tests; I'm trying to catch potential
// problems before we go into push_on_queue to know where the
// problem is coming from
@ -4076,35 +4128,9 @@ public:
// Clean up any par-expanded rem sets.
HeapRegionRemSet::par_cleanup();
MutexLocker x(stats_lock());
if (ParallelGCVerbose) {
gclog_or_tty->print("Thread %d complete:\n", i);
#if G1_DETAILED_STATS
gclog_or_tty->print(" Pushes: %7d Pops: %7d Overflows: %7d Steals %7d (in %d attempts)\n",
pss.pushes(),
pss.pops(),
pss.overflow_pushes(),
pss.steals(),
pss.steal_attempts());
#endif
double elapsed = pss.elapsed();
double strong_roots = pss.strong_roots_time();
double term = pss.term_time();
gclog_or_tty->print(" Elapsed: %7.2f ms.\n"
" Strong roots: %7.2f ms (%6.2f%%)\n"
" Termination: %7.2f ms (%6.2f%%) "
"(in "SIZE_FORMAT" entries)\n",
elapsed * 1000.0,
strong_roots * 1000.0, (strong_roots*100.0/elapsed),
term * 1000.0, (term*100.0/elapsed),
pss.term_attempts());
size_t total_waste = pss.alloc_buffer_waste() + pss.undo_waste();
gclog_or_tty->print(" Waste: %8dK\n"
" Alloc Buffer: %8dK\n"
" Undo: %8dK\n",
(total_waste * HeapWordSize) / K,
(pss.alloc_buffer_waste() * HeapWordSize) / K,
(pss.undo_waste() * HeapWordSize) / K);
MutexLocker x(stats_lock());
pss.print_termination_stats(i);
}
assert(pss.refs_to_scan() == 0, "Task queue should be empty");
@ -4221,6 +4247,7 @@ void G1CollectedHeap::evacuate_collection_set() {
if (ParallelGCThreads > 0) {
// The individual threads will set their evac-failure closures.
StrongRootsScope srs(this);
if (ParallelGCVerbose) G1ParScanThreadState::print_termination_stats_hdr();
workers()->run_task(&g1_par_task);
} else {
StrongRootsScope srs(this);