< prev index next >
src/hotspot/share/gc/g1/g1CollectedHeap.cpp
Print this page
rev 53920 : [mq]: 8218880-g1-crashes-periodic-gc-gclocker
@@ -2111,19 +2111,25 @@
// waiting in VM_G1CollectForAllocation::doit_epilogue().
FullGCCount_lock->notify_all();
}
void G1CollectedHeap::collect(GCCause::Cause cause) {
+ attempt_collect(cause, true);
+}
+
+bool G1CollectedHeap::attempt_collect(GCCause::Cause cause, bool retry_on_vmop_failure) {
assert_heap_not_locked();
+ bool vmop_succeeded;
+ bool should_retry_vmop;
+
+ do {
+ should_retry_vmop = false;
+
uint gc_count_before;
uint old_marking_count_before;
uint full_gc_count_before;
- bool retry_gc;
-
- do {
- retry_gc = false;
{
MutexLocker ml(Heap_lock);
// Read the GC count while holding the Heap_lock
@@ -2140,25 +2146,24 @@
gc_count_before,
cause,
true, /* should_initiate_conc_mark */
g1_policy()->max_pause_time_ms());
VMThread::execute(&op);
- if (!op.pause_succeeded()) {
+ vmop_succeeded = op.pause_succeeded();
+ if (!vmop_succeeded && retry_on_vmop_failure) {
if (old_marking_count_before == _old_marking_cycles_started) {
- retry_gc = op.should_retry_gc();
+ should_retry_vmop = op.should_retry_gc();
} else {
// A Full GC happened while we were trying to schedule the
- // initial-mark GC. No point in starting a new cycle given
+ // concurrent cycle. No point in starting a new cycle given
// that the whole heap was collected anyway.
}
- if (retry_gc) {
- if (GCLocker::is_active_and_needs_gc()) {
+ if (should_retry_vmop && GCLocker::is_active_and_needs_gc()) {
GCLocker::stall_until_clear();
}
}
- }
} else {
if (cause == GCCause::_gc_locker || cause == GCCause::_wb_young_gc
DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) {
// Schedule a standard evacuation pause. We're setting word_size
@@ -2167,17 +2172,20 @@
gc_count_before,
cause,
false, /* should_initiate_conc_mark */
g1_policy()->max_pause_time_ms());
VMThread::execute(&op);
+ vmop_succeeded = op.pause_succeeded();
} else {
// Schedule a Full GC.
VM_G1CollectFull op(gc_count_before, full_gc_count_before, cause);
VMThread::execute(&op);
+ vmop_succeeded = op.pause_succeeded();
}
}
- } while (retry_gc);
+ } while (should_retry_vmop);
+ return vmop_succeeded;
}
bool G1CollectedHeap::is_in(const void* p) const {
if (_hrm->reserved().contains(p)) {
// Given that we know that p is in the reserved space,
< prev index next >