# HG changeset patch # User sjohanss # Date 1447946458 -3600 # Thu Nov 19 16:20:58 2015 +0100 # Node ID 7b5a0a1dcaee09c24bd4e10988e018c044ad91bf # Parent 104643b8cfcb1d0fd7735ced00635c8a085d8e25 8143251: HeapRetentionTest.java Test is failing on jdk9/dev Reviewed-by: diff --git a/src/share/vm/gc/g1/g1CollectedHeap.cpp b/src/share/vm/gc/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc/g1/g1CollectedHeap.cpp +++ b/src/share/vm/gc/g1/g1CollectedHeap.cpp @@ -2259,15 +2259,21 @@ return blk.result(); } +bool G1CollectedHeap::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 user_requested_concurrent_full_gc(cause); } } diff --git a/src/share/vm/gc/g1/g1CollectedHeap.hpp b/src/share/vm/gc/g1/g1CollectedHeap.hpp --- a/src/share/vm/gc/g1/g1CollectedHeap.hpp +++ b/src/share/vm/gc/g1/g1CollectedHeap.hpp @@ -244,9 +244,13 @@ // 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 + // These are defined in user_requested_concurrent_full_gc() because + // these sometimes need to be treated differently: + // (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 @@ -582,6 +586,11 @@ _in_cset_fast_test.clear(); } + // A complement to should_do_concurrent_full_gc. GCs caused + // by a user sometimes needs to be treated differently + // from those caused by the VM. + bool 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(); diff --git a/src/share/vm/gc/g1/g1CollectorPolicy.cpp b/src/share/vm/gc/g1/g1CollectorPolicy.cpp --- a/src/share/vm/gc/g1/g1CollectorPolicy.cpp +++ b/src/share/vm/gc/g1/g1CollectorPolicy.cpp @@ -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. + // 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->user_requested_concurrent_full_gc(_g1->gc_cause())) { + // Initiate a user requested initial mark and update the collector state to + // reflect this. + collector_state()->set_gcs_are_young(true); + collector_state()->set_last_young_gc(false); - 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_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 diff --git a/src/share/vm/gc/g1/g1CollectorPolicy.hpp b/src/share/vm/gc/g1/g1CollectorPolicy.hpp --- a/src/share/vm/gc/g1/g1CollectorPolicy.hpp +++ b/src/share/vm/gc/g1/g1CollectorPolicy.hpp @@ -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);