8008301: G1: guarantee(satb_mq_set.completed_buffers_num() == 0) failure
Summary: If the marking stack overflows while the marking tasks are draining the SATB buffers, remark will exit with some SATB buffers left unprocessed. Relax the guarantee to allow for overflow.
Reviewed-by: jmasa, brutisso
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Tue Mar 19 00:57:39 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Tue Mar 19 09:38:37 2013 -0700
@@ -1289,12 +1289,22 @@
if (has_overflown()) {
// Oops. We overflowed. Restart concurrent marking.
_restart_for_overflow = true;
+ if (G1TraceMarkStackOverflow) {
+ gclog_or_tty->print_cr("\nRemark led to restart for overflow.");
+ }
+
+ // Verify the heap w.r.t. the previous marking bitmap.
+ if (VerifyDuringGC) {
+ HandleMark hm; // handle scope
+ gclog_or_tty->print(" VerifyDuringGC:(overflow)");
+ Universe::heap()->prepare_for_verify();
+ Universe::verify(/* silent */ false,
+ /* option */ VerifyOption_G1UsePrevMarking);
+ }
+
// Clear the marking state because we will be restarting
// marking due to overflowing the global mark stack.
reset_marking_state();
- if (G1TraceMarkStackOverflow) {
- gclog_or_tty->print_cr("\nRemark led to restart for overflow.");
- }
} else {
// Aggregate the per-task counting data that we have accumulated
// while marking.
@@ -2593,7 +2603,11 @@
remarkTask.work(0);
}
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
- guarantee(satb_mq_set.completed_buffers_num() == 0, "invariant");
+ guarantee(has_overflown() ||
+ satb_mq_set.completed_buffers_num() == 0,
+ err_msg("Invariant: has_overflown = %s, num buffers = %d",
+ BOOL_TO_STR(has_overflown()),
+ satb_mq_set.completed_buffers_num()));
print_stats();
}