--- old/src/share/vm/gc/g1/g1CollectorPolicy.cpp 2015-11-05 09:34:51.934102869 +0100 +++ new/src/share/vm/gc/g1/g1CollectorPolicy.cpp 2015-11-05 09:34:51.851100418 +0100 @@ -930,8 +930,12 @@ return other_time_ms(pause_time_ms) - young_other_time_ms() - non_young_other_time_ms(); } +bool G1CollectorPolicy::about_to_start_mixed_phase() const { + return _g1->concurrent_mark()->cmThread()->during_cycle() || collector_state()->last_young_gc(); +} + bool G1CollectorPolicy::need_to_start_conc_mark(const char* source, size_t alloc_word_size) { - if (_g1->concurrent_mark()->cmThread()->during_cycle()) { + if (about_to_start_mixed_phase()) { return false; } @@ -1071,17 +1075,13 @@ if (collector_state()->last_young_gc()) { // This is supposed to to be the "last young GC" before we start // doing mixed GCs. Here we decide whether to start mixed GCs or not. + assert(!last_pause_included_initial_mark, "The last young GC is not allowed to be an initial mark GC"); - if (!last_pause_included_initial_mark) { - if (next_gc_should_be_mixed("start mixed GCs", - "do not start mixed GCs")) { - collector_state()->set_gcs_are_young(false); - } - } else { - ergo_verbose0(ErgoMixedGCs, - "do not start mixed GCs", - ergo_format_reason("concurrent cycle is about to start")); + if (next_gc_should_be_mixed("start mixed GCs", + "do not start mixed GCs")) { + collector_state()->set_gcs_are_young(false); } + collector_state()->set_last_young_gc(false); } @@ -1599,8 +1599,10 @@ HeapRegion::GrainWords * _max_survivor_regions, counters()); } -bool G1CollectorPolicy::force_initial_mark_if_outside_cycle( - GCCause::Cause gc_cause) { +bool G1CollectorPolicy::force_initial_mark_if_outside_cycle(GCCause::Cause gc_cause) { + // We actually check whether we are marking here and not if we are in a + // reclamation phase. This means that we will schedule a concurrent mark + // even while we are still in the process of reclaiming memory. bool during_cycle = _g1->concurrent_mark()->cmThread()->during_cycle(); if (!during_cycle) { ergo_verbose1(ErgoConcCycles, @@ -1620,8 +1622,7 @@ } } -void -G1CollectorPolicy::decide_on_conc_mark_initiation() { +void G1CollectorPolicy::decide_on_conc_mark_initiation() { // We are about to decide on whether this pause will be an // initial-mark pause. @@ -1636,21 +1637,11 @@ // gone over the initiating threshold and we should start a // concurrent marking cycle. So we might initiate one. - bool during_cycle = _g1->concurrent_mark()->cmThread()->during_cycle(); - if (!during_cycle) { - // The concurrent marking thread is not "during a cycle", i.e., - // it has completed the last one. So we can go ahead and - // initiate a new cycle. + if (!about_to_start_mixed_phase() && collector_state()->gcs_are_young()) { + // Initiate a new initial mark only if there is no marking or reclamation going + // on. collector_state()->set_during_initial_mark_pause(true); - // We do not allow mixed GCs during marking. - if (!collector_state()->gcs_are_young()) { - collector_state()->set_gcs_are_young(true); - ergo_verbose0(ErgoMixedGCs, - "end mixed GCs", - ergo_format_reason("concurrent cycle is about to start")); - } - // And we can now clear initiate_conc_mark_if_possible() as // we've already acted on it. collector_state()->set_initiate_conc_mark_if_possible(false); --- old/src/share/vm/gc/g1/g1CollectorPolicy.hpp 2015-11-05 09:34:52.437117719 +0100 +++ new/src/share/vm/gc/g1/g1CollectorPolicy.hpp 2015-11-05 09:34:52.356115327 +0100 @@ -570,6 +570,8 @@ bool need_to_start_conc_mark(const char* source, size_t alloc_word_size = 0); + bool about_to_start_mixed_phase() const; + // Record the start and end of an evacuation pause. void record_collection_pause_start(double start_time_sec); void record_collection_pause_end(double pause_time_ms, size_t cards_scanned); --- old/src/share/vm/prims/whitebox.cpp 2015-11-05 09:34:52.919131949 +0100 +++ new/src/share/vm/prims/whitebox.cpp 2015-11-05 09:34:52.837129528 +0100 @@ -322,8 +322,8 @@ WB_END WB_ENTRY(jboolean, WB_G1InConcurrentMark(JNIEnv* env, jobject o)) - G1CollectedHeap* g1 = G1CollectedHeap::heap(); - return g1->concurrent_mark()->cmThread()->during_cycle(); + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + return g1h->concurrent_mark()->cmThread()->during_cycle(); WB_END WB_ENTRY(jboolean, WB_G1StartMarkCycle(JNIEnv* env, jobject o))