--- old/src/share/vm/gc/g1/g1CollectedHeap.cpp 2015-11-24 10:09:18.609590666 +0100 +++ new/src/share/vm/gc/g1/g1CollectedHeap.cpp 2015-11-24 10:09:18.497586332 +0100 @@ -2250,15 +2250,21 @@ return blk.result(); } +bool G1CollectedHeap::is_user_requested_concurrent_full_gc(GCCause::Cause cause) { + switch (cause) { + case GCCause::_java_lang_system_gc: return ExplicitGCInvokesConcurrent; + case GCCause::_dcmd_gc_run: return ExplicitGCInvokesConcurrent; + case GCCause::_update_allocation_context_stats_inc: return true; + case GCCause::_wb_conc_mark: return true; + default : return false; + } +} + bool G1CollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) { switch (cause) { case GCCause::_gc_locker: return GCLockerInvokesConcurrent; - case GCCause::_java_lang_system_gc: return ExplicitGCInvokesConcurrent; - case GCCause::_dcmd_gc_run: return ExplicitGCInvokesConcurrent; case GCCause::_g1_humongous_allocation: return true; - case GCCause::_update_allocation_context_stats_inc: return true; - case GCCause::_wb_conc_mark: return true; - default: return false; + default: return is_user_requested_concurrent_full_gc(cause); } } --- old/src/share/vm/gc/g1/g1CollectedHeap.hpp 2015-11-24 10:09:19.317618064 +0100 +++ new/src/share/vm/gc/g1/g1CollectedHeap.hpp 2015-11-24 10:09:19.213614039 +0100 @@ -244,9 +244,11 @@ // instead of doing a STW GC. Currently, a concurrent cycle is // explicitly started if: // (a) cause == _gc_locker and +GCLockerInvokesConcurrent, or - // (b) cause == _java_lang_system_gc and +ExplicitGCInvokesConcurrent. - // (c) cause == _dcmd_gc_run and +ExplicitGCInvokesConcurrent. - // (d) cause == _g1_humongous_allocation + // (b) cause == _g1_humongous_allocation + // (c) cause == _java_lang_system_gc and +ExplicitGCInvokesConcurrent. + // (d) cause == _dcmd_gc_run and +ExplicitGCInvokesConcurrent. + // (e) cause == _update_allocation_context_stats_inc + // (f) cause == _wb_conc_mark bool should_do_concurrent_full_gc(GCCause::Cause cause); // indicates whether we are in young or mixed GC mode @@ -576,6 +578,8 @@ _in_cset_fast_test.clear(); } + bool is_user_requested_concurrent_full_gc(GCCause::Cause cause); + // This is called at the start of either a concurrent cycle or a Full // GC to update the number of old marking cycles started. void increment_old_marking_cycles_started(); --- old/src/share/vm/gc/g1/g1CollectorPolicy.cpp 2015-11-24 10:09:19.925641592 +0100 +++ new/src/share/vm/gc/g1/g1CollectorPolicy.cpp 2015-11-24 10:09:19.809637103 +0100 @@ -1621,6 +1621,11 @@ } } +void G1CollectorPolicy::initiate_conc_mark() { + collector_state()->set_during_initial_mark_pause(true); + collector_state()->set_initiate_conc_mark_if_possible(false); +} + void G1CollectorPolicy::decide_on_conc_mark_initiation() { // We are about to decide on whether this pause will be an // initial-mark pause. @@ -1637,17 +1642,21 @@ // concurrent marking cycle. So we might initiate one. 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); - // 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); + // Initiate a new initial mark if there is no marking or reclamation going on. + initiate_conc_mark(); + ergo_verbose0(ErgoConcCycles, + "initiate concurrent cycle", + ergo_format_reason("concurrent cycle initiation requested")); + } else if (_g1->is_user_requested_concurrent_full_gc(_g1->gc_cause())) { + // Initiate a user requested initial mark. An initial mark must be young only + // GC, so the collector state must be updated to reflect this. + collector_state()->set_gcs_are_young(true); + collector_state()->set_last_young_gc(false); + initiate_conc_mark(); ergo_verbose0(ErgoConcCycles, - "initiate concurrent cycle", - ergo_format_reason("concurrent cycle initiation requested")); + "initiate concurrent cycle", + ergo_format_reason("user requested concurrent cycle")); } else { // The concurrent marking thread is still finishing up the // previous cycle. If we start one right now the two cycles --- old/src/share/vm/gc/g1/g1CollectorPolicy.hpp 2015-11-24 10:09:20.657669919 +0100 +++ new/src/share/vm/gc/g1/g1CollectorPolicy.hpp 2015-11-24 10:09:20.557666049 +0100 @@ -681,6 +681,11 @@ // (should not be called directly). void add_region_to_incremental_cset_common(HeapRegion* hr); + // Set the state to start a concurrent marking cycle and clear + // _initiate_conc_mark_if_possible because it has now been + // acted on. + void initiate_conc_mark(); + public: // Add hr to the LHS of the incremental collection set. void add_region_to_incremental_cset_lhs(HeapRegion* hr);