--- old/src/hotspot/share/gc/g1/g1Policy.cpp 2020-07-03 17:41:19.203375914 +0200 +++ new/src/hotspot/share/gc/g1/g1Policy.cpp 2020-07-03 17:41:19.095374349 +0200 @@ -74,7 +74,7 @@ _rs_length_prediction(0), _pending_cards_at_gc_start(0), _old_gen_alloc_tracker(), - _initial_mark_to_mixed(), + _concurrent_start_to_mixed(), _collection_set(NULL), _g1h(NULL), _phase_times(new G1GCPhaseTimes(gc_timer, ParallelGCThreads)), @@ -448,7 +448,7 @@ collector_state()->set_in_young_only_phase(true); collector_state()->set_in_young_gc_before_mixed(false); collector_state()->set_initiate_conc_mark_if_possible(need_to_start_conc_mark("end of Full GC", 0)); - collector_state()->set_in_initial_mark_gc(false); + collector_state()->set_in_concurrent_start_gc(false); collector_state()->set_mark_or_rebuild_in_progress(false); collector_state()->set_clearing_next_bitmap(false); @@ -544,7 +544,7 @@ void G1Policy::record_concurrent_mark_init_end(double mark_init_elapsed_time_ms) { assert(!collector_state()->initiate_conc_mark_if_possible(), "we should have cleared it by now"); - collector_state()->set_in_initial_mark_gc(false); + collector_state()->set_in_concurrent_start_gc(false); } void G1Policy::record_concurrent_mark_remark_start() { @@ -632,17 +632,15 @@ double end_time_sec = os::elapsedTime(); - bool this_pause_included_initial_mark = false; - bool this_pause_was_young_only = collector_state()->in_young_only_phase(); + PauseKind this_pause = young_gc_pause_kind(); bool update_stats = !_g1h->evacuation_failed(); - record_pause(young_gc_pause_kind(), end_time_sec - pause_time_ms / 1000.0, end_time_sec); + record_pause(this_pause, end_time_sec - pause_time_ms / 1000.0, end_time_sec); _collection_pause_end_millis = os::javaTimeNanos() / NANOSECS_PER_MILLISEC; - this_pause_included_initial_mark = collector_state()->in_initial_mark_gc(); - if (this_pause_included_initial_mark) { + if (is_concurrent_start_pause(this_pause)) { record_concurrent_mark_init_end(0.0); } else { maybe_start_marking(); @@ -673,14 +671,15 @@ _analytics->update_recent_gc_times(end_time_sec, pause_time_ms); } - if (collector_state()->in_young_gc_before_mixed()) { - assert(!this_pause_included_initial_mark, "The young GC before mixed is not allowed to be an initial mark GC"); + if (is_last_young_pause(this_pause)) { + assert(!is_concurrent_start_pause(this_pause), + "The young GC before mixed is not allowed to be concurrent start GC"); // This has been the young GC before we start doing mixed GCs. We already // decided to start mixed GCs much earlier, so there is nothing to do except // advancing the state. collector_state()->set_in_young_only_phase(false); collector_state()->set_in_young_gc_before_mixed(false); - } else if (!this_pause_was_young_only) { + } else if (!is_young_only_pause(this_pause)) { // This is a mixed GC. Here we decide whether to continue doing more // mixed GCs or not. if (!next_gc_should_be_mixed("continue mixed GCs", @@ -713,7 +712,8 @@ average_time_ms(G1GCPhaseTimes::MergeHCC) + average_time_ms(G1GCPhaseTimes::MergeLB) + average_time_ms(G1GCPhaseTimes::OptMergeRS); - _analytics->report_cost_per_card_merge_ms(avg_time_merge_cards / total_cards_merged, this_pause_was_young_only); + _analytics->report_cost_per_card_merge_ms(avg_time_merge_cards / total_cards_merged, + is_young_only_pause(this_pause)); } // Update prediction for card scan @@ -724,7 +724,8 @@ double avg_time_dirty_card_scan = average_time_ms(G1GCPhaseTimes::ScanHR) + average_time_ms(G1GCPhaseTimes::OptScanHR); - _analytics->report_cost_per_card_scan_ms(avg_time_dirty_card_scan / total_cards_scanned, this_pause_was_young_only); + _analytics->report_cost_per_card_scan_ms(avg_time_dirty_card_scan / total_cards_scanned, + is_young_only_pause(this_pause)); } // Update prediction for the ratio between cards from the remembered @@ -738,7 +739,8 @@ if (total_cards_scanned > 0) { merge_to_scan_ratio = (double) from_rs_length_cards / total_cards_scanned; } - _analytics->report_card_merge_to_scan_ratio(merge_to_scan_ratio, this_pause_was_young_only); + _analytics->report_card_merge_to_scan_ratio(merge_to_scan_ratio, + is_young_only_pause(this_pause)); const size_t recorded_rs_length = _collection_set->recorded_rs_length(); const size_t rs_length_diff = _rs_length > recorded_rs_length ? _rs_length - recorded_rs_length : 0; @@ -768,15 +770,15 @@ // these are is wildly different to during young only gc and mess up young gen sizing right // after the mixed gc phase. // During mixed gc we do not use them for young gen sizing. - if (this_pause_was_young_only) { + if (is_young_only_pause(this_pause)) { _analytics->report_pending_cards((double) _pending_cards_at_gc_start); _analytics->report_rs_length((double) _rs_length); } } - assert(!(this_pause_included_initial_mark && collector_state()->mark_or_rebuild_in_progress()), - "If the last pause has been an initial mark, we should not have been in the marking window"); - if (this_pause_included_initial_mark) { + assert(!(is_concurrent_start_pause(this_pause) && collector_state()->mark_or_rebuild_in_progress()), + "If the last pause has been concurrent start, we should not have been in the marking window"); + if (is_concurrent_start_pause(this_pause)) { collector_state()->set_mark_or_rebuild_in_progress(true); } @@ -797,7 +799,7 @@ update_ihop_prediction(_old_gen_alloc_tracker.last_cycle_duration(), _old_gen_alloc_tracker.last_cycle_old_bytes(), last_unrestrained_young_length * HeapRegion::GrainBytes, - this_pause_was_young_only); + is_young_only_pause(this_pause)); _ihop_control->send_trace_event(_g1h->gc_tracer_stw()); } else { @@ -807,7 +809,7 @@ // for completing the marking, i.e. are faster than expected. // This skews the predicted marking length towards smaller values which might cause // the mark start being too late. - _initial_mark_to_mixed.reset(); + _concurrent_start_to_mixed.reset(); } // Note that _mmu_tracker->max_gc_time() returns the time in seconds. @@ -858,10 +860,10 @@ bool report = false; double marking_to_mixed_time = -1.0; - if (!this_gc_was_young_only && _initial_mark_to_mixed.has_result()) { - marking_to_mixed_time = _initial_mark_to_mixed.last_marking_time(); + if (!this_gc_was_young_only && _concurrent_start_to_mixed.has_result()) { + marking_to_mixed_time = _concurrent_start_to_mixed.last_marking_time(); assert(marking_to_mixed_time > 0.0, - "Initial mark to mixed time must be larger than zero but is %.3f", + "Concurrent start to mixed time must be larger than zero but is %.3f", marking_to_mixed_time); if (marking_to_mixed_time > min_valid_time) { _ihop_control->update_marking_length(marking_to_mixed_time); @@ -1017,35 +1019,39 @@ _g1h->num_free_or_available_regions()); } -bool G1Policy::force_initial_mark_if_outside_cycle(GCCause::Cause gc_cause) { +bool G1Policy::force_concurrent_start_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 = _g1h->concurrent_mark()->cm_thread()->during_cycle(); if (!during_cycle) { - log_debug(gc, ergo)("Request concurrent cycle initiation (requested by GC cause). GC cause: %s", GCCause::to_string(gc_cause)); + log_debug(gc, ergo)("Request concurrent cycle initiation (requested by GC cause). " + "GC cause: %s", + GCCause::to_string(gc_cause)); collector_state()->set_initiate_conc_mark_if_possible(true); return true; } else { - log_debug(gc, ergo)("Do not request concurrent cycle initiation (concurrent cycle already in progress). GC cause: %s", GCCause::to_string(gc_cause)); + log_debug(gc, ergo)("Do not request concurrent cycle initiation " + "(concurrent cycle already in progress). GC cause: %s", + GCCause::to_string(gc_cause)); return false; } } void G1Policy::initiate_conc_mark() { - collector_state()->set_in_initial_mark_gc(true); + collector_state()->set_in_concurrent_start_gc(true); collector_state()->set_initiate_conc_mark_if_possible(false); } void G1Policy::decide_on_conc_mark_initiation() { - // We are about to decide on whether this pause will be an - // initial-mark pause. + // We are about to decide on whether this pause will be a + // concurrent start pause. - // First, collector_state()->in_initial_mark_gc() should not be already set. We + // First, collector_state()->in_concurrent_start_gc() should not be already set. We // will set it here if we have to. However, it should be cleared by - // the end of the pause (it's only set for the duration of an - // initial-mark pause). - assert(!collector_state()->in_initial_mark_gc(), "pre-condition"); + // the end of the pause (it's only set for the duration of a + // concurrent start pause). + assert(!collector_state()->in_concurrent_start_gc(), "pre-condition"); if (collector_state()->initiate_conc_mark_if_possible()) { // We had noticed on a previous pause that the heap occupancy has @@ -1059,13 +1065,13 @@ ConcurrentGCBreakpoints::is_controlled()) { log_debug(gc, ergo)("Do not initiate concurrent cycle (whitebox controlled)"); } else if (!about_to_start_mixed_phase() && collector_state()->in_young_only_phase()) { - // Initiate a new initial mark if there is no marking or reclamation going on. + // Initiate a new concurrent start if there is no marking or reclamation going on. initiate_conc_mark(); log_debug(gc, ergo)("Initiate concurrent cycle (concurrent cycle initiation requested)"); } else if (_g1h->is_user_requested_concurrent_full_gc(cause) || (cause == GCCause::_wb_breakpoint)) { - // Initiate a user requested initial mark or run_to a breakpoint. - // An initial mark must be young only GC, so the collector state + // Initiate a user requested concurrent start or run to a breakpoint. + // A concurrent start must be young only GC, so the collector state // must be updated to reflect this. collector_state()->set_in_young_only_phase(true); collector_state()->set_in_young_gc_before_mixed(false); @@ -1145,20 +1151,35 @@ } } +bool G1Policy::is_young_only_pause(PauseKind kind) { + assert(kind != FullGC, "must be"); + assert(kind != Remark, "must be"); + assert(kind != Cleanup, "must be"); + return kind == ConcurrentStartGC || kind == LastYoungGC || kind == YoungOnlyGC; +} + +bool G1Policy::is_last_young_pause(PauseKind kind) { + return kind == LastYoungGC; +} + +bool G1Policy::is_concurrent_start_pause(PauseKind kind) { + return kind == ConcurrentStartGC; +} + G1Policy::PauseKind G1Policy::young_gc_pause_kind() const { assert(!collector_state()->in_full_gc(), "must be"); - if (collector_state()->in_initial_mark_gc()) { + if (collector_state()->in_concurrent_start_gc()) { assert(!collector_state()->in_young_gc_before_mixed(), "must be"); - return InitialMarkGC; + return ConcurrentStartGC; } else if (collector_state()->in_young_gc_before_mixed()) { - assert(!collector_state()->in_initial_mark_gc(), "must be"); + assert(!collector_state()->in_concurrent_start_gc(), "must be"); return LastYoungGC; } else if (collector_state()->in_mixed_phase()) { - assert(!collector_state()->in_initial_mark_gc(), "must be"); + assert(!collector_state()->in_concurrent_start_gc(), "must be"); assert(!collector_state()->in_young_gc_before_mixed(), "must be"); return MixedGC; } else { - assert(!collector_state()->in_initial_mark_gc(), "must be"); + assert(!collector_state()->in_concurrent_start_gc(), "must be"); assert(!collector_state()->in_young_gc_before_mixed(), "must be"); return YoungOnlyGC; } @@ -1169,7 +1190,7 @@ if (kind != FullGC) { _mmu_tracker->add_pause(start, end); } - // Manage the mutator time tracking from initial mark to first mixed gc. + // Manage the mutator time tracking from concurrent start to first mixed gc. switch (kind) { case FullGC: abort_time_to_mixed_tracking(); @@ -1178,15 +1199,15 @@ case Remark: case YoungOnlyGC: case LastYoungGC: - _initial_mark_to_mixed.add_pause(end - start); + _concurrent_start_to_mixed.add_pause(end - start); break; - case InitialMarkGC: + case ConcurrentStartGC: if (_g1h->gc_cause() != GCCause::_g1_periodic_collection) { - _initial_mark_to_mixed.record_initial_mark_end(end); + _concurrent_start_to_mixed.record_concurrent_start_end(end); } break; case MixedGC: - _initial_mark_to_mixed.record_mixed_gc_start(start); + _concurrent_start_to_mixed.record_mixed_gc_start(start); break; default: ShouldNotReachHere(); @@ -1194,7 +1215,7 @@ } void G1Policy::abort_time_to_mixed_tracking() { - _initial_mark_to_mixed.reset(); + _concurrent_start_to_mixed.reset(); } bool G1Policy::next_gc_should_be_mixed(const char* true_action_str,