--- old/src/hotspot/share/gc/g1/g1Policy.cpp 2019-11-21 15:05:53.794706151 +0100 +++ new/src/hotspot/share/gc/g1/g1Policy.cpp 2019-11-21 15:05:53.433694978 +0100 @@ -62,8 +62,8 @@ _young_list_target_length(0), _young_list_fixed_length(0), _young_list_max_length(0), - _eden_surv_rate_group(new SurvRateGroup()), - _survivor_surv_rate_group(new SurvRateGroup()), + _eden_surv_rate_group(new G1SurvRateGroup()), + _survivor_surv_rate_group(new G1SurvRateGroup()), _reserve_factor((double) G1ReservePercent / 100.0), _reserve_regions(0), _young_gen_sizer(G1YoungGenSizer::create_gen_sizer()), @@ -460,7 +460,6 @@ // also call this on any additional surv rate groups _free_regions_at_end_of_collection = _g1h->num_free_regions(); - // Reset survivors SurvRateGroup. _survivor_surv_rate_group->reset(); update_young_list_max_and_target_length(); update_rs_length_prediction(); @@ -1391,8 +1390,6 @@ } void G1Policy::transfer_survivors_to_cset(const G1SurvivorRegions* survivors) { - - // Add survivor regions to SurvRateGroup. note_start_adding_survivor_regions(); HeapRegion* last = NULL; --- old/src/hotspot/share/gc/g1/g1Policy.hpp 2019-11-21 15:05:55.106746760 +0100 +++ new/src/hotspot/share/gc/g1/g1Policy.hpp 2019-11-21 15:05:54.760736050 +0100 @@ -82,10 +82,10 @@ // locker is active. This should be >= _young_list_target_length; uint _young_list_max_length; - // SurvRateGroups below must be initialized after the predictor because they - // indirectly use it through this object passed to their constructor. - SurvRateGroup* _eden_surv_rate_group; - SurvRateGroup* _survivor_surv_rate_group; + // The survivor rate groups below must be initialized after the predictor because they + // indirectly use it through the "this" object passed to their constructor. + G1SurvRateGroup* _eden_surv_rate_group; + G1SurvRateGroup* _survivor_surv_rate_group; double _reserve_factor; // This will be set when the heap is expanded --- old/src/hotspot/share/gc/g1/g1SurvRateGroup.cpp 2019-11-21 15:05:56.392786563 +0100 +++ new/src/hotspot/share/gc/g1/g1SurvRateGroup.cpp 2019-11-21 15:05:56.050775978 +0100 @@ -30,7 +30,7 @@ #include "logging/log.hpp" #include "memory/allocation.hpp" -SurvRateGroup::SurvRateGroup() : +G1SurvRateGroup::G1SurvRateGroup() : _stats_arrays_length(0), _accum_surv_rate_pred(NULL), _last_pred(0.0), @@ -40,7 +40,7 @@ start_adding_regions(); } -void SurvRateGroup::reset() { +void G1SurvRateGroup::reset() { _last_pred = 0.0; // the following will set up the arrays with length 1 _num_added_regions = 1; @@ -65,11 +65,11 @@ _num_added_regions = 0; } -void SurvRateGroup::start_adding_regions() { +void G1SurvRateGroup::start_adding_regions() { _num_added_regions = 0; } -void SurvRateGroup::stop_adding_regions() { +void G1SurvRateGroup::stop_adding_regions() { if (_num_added_regions > _stats_arrays_length) { _accum_surv_rate_pred = REALLOC_C_HEAP_ARRAY(double, _accum_surv_rate_pred, _num_added_regions, mtGC); _surv_rate_predictors = REALLOC_C_HEAP_ARRAY(TruncatedSeq*, _surv_rate_predictors, _num_added_regions, mtGC); @@ -82,7 +82,7 @@ } } -void SurvRateGroup::record_surviving_words(int age_in_group, size_t surv_words) { +void G1SurvRateGroup::record_surviving_words(int age_in_group, size_t surv_words) { guarantee(0 <= age_in_group && (size_t)age_in_group < _num_added_regions, "age_in_group is %d not between 0 and " SIZE_FORMAT, age_in_group, _num_added_regions); @@ -90,14 +90,14 @@ _surv_rate_predictors[age_in_group]->add(surv_rate); } -void SurvRateGroup::all_surviving_words_recorded(const G1Predictions& predictor, bool update_predictors) { +void G1SurvRateGroup::all_surviving_words_recorded(const G1Predictions& predictor, bool update_predictors) { if (update_predictors) { fill_in_last_surv_rates(); } finalize_predictions(predictor); } -void SurvRateGroup::fill_in_last_surv_rates() { +void G1SurvRateGroup::fill_in_last_surv_rates() { if (_num_added_regions > 0) { // conservative double surv_rate = _surv_rate_predictors[_num_added_regions-1]->last(); for (size_t i = _num_added_regions; i < _stats_arrays_length; ++i) { @@ -106,7 +106,7 @@ } } -void SurvRateGroup::finalize_predictions(const G1Predictions& predictor) { +void G1SurvRateGroup::finalize_predictions(const G1Predictions& predictor) { double accum = 0.0; double pred = 0.0; for (size_t i = 0; i < _stats_arrays_length; ++i) { --- old/src/hotspot/share/gc/g1/g1SurvRateGroup.hpp 2019-11-21 15:05:57.686826615 +0100 +++ new/src/hotspot/share/gc/g1/g1SurvRateGroup.hpp 2019-11-21 15:05:57.343815998 +0100 @@ -28,13 +28,33 @@ #include "gc/g1/g1Predictions.hpp" #include "utilities/numberSeq.hpp" -class SurvRateGroup : public CHeapObj { +// A survivor rate group tracks survival ratios of objects allocated in the +// heap regions associated to a set of regions (a "space", i.e. eden or survivor) +// on a time basis to predict future survival rates of regions of the same "age". +// +// Every time a new heap region associated with a survivor rate group is retired +// (i.e. the time basis), it gets associated the next "age" entry in that group. +// +// During garbage collection G1 keeps track how much of total data is copied out +// of a heap region (i.e. survives), to update the survivor rate predictor of that age. +// +// This information is used to predict, given a particular age of a heap region, +// how much of its contents will likely survive to determine young generation sizes. +// +// The age index associated with a heap region is incremented from 0 (retired first) +// to N (retired just before the GC). +// +// To avoid copying around data all the time when the total amount of regions in +// a survivor rate group changes, this class organizes the arrays containing the +// predictors in reverse chronological order as returned by age_in_group(). I.e. +// index 0 contains the rate information for the region retired most recently. +class G1SurvRateGroup : public CHeapObj { size_t _stats_arrays_length; double* _accum_surv_rate_pred; double _last_pred; TruncatedSeq** _surv_rate_predictors; - size_t _num_added_regions; // The number of regions in this SurvRateGroup + size_t _num_added_regions; // The number of regions in this survivor rate group. void fill_in_last_surv_rates(); void finalize_predictions(const G1Predictions& predictor); @@ -43,7 +63,7 @@ static const int InvalidAgeIndex = -1; static bool is_valid_age_index(int age) { return age >= 0; } - SurvRateGroup(); + G1SurvRateGroup(); void reset(); void start_adding_regions(); void stop_adding_regions(); --- old/src/hotspot/share/gc/g1/heapRegion.cpp 2019-11-21 15:05:58.981866697 +0100 +++ new/src/hotspot/share/gc/g1/heapRegion.cpp 2019-11-21 15:05:58.638856081 +0100 @@ -254,7 +254,7 @@ _prev_top_at_mark_start(NULL), _next_top_at_mark_start(NULL), _prev_marked_bytes(0), _next_marked_bytes(0), _young_index_in_cset(-1), - _surv_rate_group(NULL), _age_index(SurvRateGroup::InvalidAgeIndex), _gc_efficiency(0.0), + _surv_rate_group(NULL), _age_index(G1SurvRateGroup::InvalidAgeIndex), _gc_efficiency(0.0), _node_index(G1NUMA::UnknownNodeIndex) { assert(Universe::on_page_boundary(mr.start()) && Universe::on_page_boundary(mr.end()), --- old/src/hotspot/share/gc/g1/heapRegion.hpp 2019-11-21 15:06:00.289907182 +0100 +++ new/src/hotspot/share/gc/g1/heapRegion.hpp 2019-11-21 15:05:59.936896256 +0100 @@ -246,7 +246,7 @@ // Data for young region survivor prediction. uint _young_index_in_cset; - SurvRateGroup* _surv_rate_group; + G1SurvRateGroup* _surv_rate_group; int _age_index; // Cached attributes used in the collection set policy information @@ -544,7 +544,7 @@ double surv_rate_prediction(G1Predictions const& predictor) const; - void install_surv_rate_group(SurvRateGroup* surv_rate_group); + void install_surv_rate_group(G1SurvRateGroup* surv_rate_group); void uninstall_surv_rate_group(); void record_surv_words_in_group(size_t words_survived); --- old/src/hotspot/share/gc/g1/heapRegion.inline.hpp 2019-11-21 15:06:01.619948347 +0100 +++ new/src/hotspot/share/gc/g1/heapRegion.inline.hpp 2019-11-21 15:06:01.255937081 +0100 @@ -378,7 +378,7 @@ } inline bool HeapRegion::has_valid_age_in_surv_rate() const { - return SurvRateGroup::is_valid_age_index(_age_index); + return G1SurvRateGroup::is_valid_age_index(_age_index); } inline bool HeapRegion::has_surv_rate_group() const { @@ -390,7 +390,7 @@ return _surv_rate_group->surv_rate_pred(predictor, age_in_surv_rate_group()); } -inline void HeapRegion::install_surv_rate_group(SurvRateGroup* surv_rate_group) { +inline void HeapRegion::install_surv_rate_group(G1SurvRateGroup* surv_rate_group) { assert(surv_rate_group != NULL, "pre-condition"); assert(!has_surv_rate_group(), "pre-condition"); assert(is_young(), "pre-condition"); @@ -405,7 +405,7 @@ assert(is_young(), "pre-condition"); _surv_rate_group = NULL; - _age_index = SurvRateGroup::InvalidAgeIndex; + _age_index = G1SurvRateGroup::InvalidAgeIndex; } else { assert(!has_valid_age_in_surv_rate(), "pre-condition"); }