8330847: G1 accesses uninitialized memory when predicting eden copy time

Reviewed-by: iwalulya, ayang
This commit is contained in:
Thomas Schatzl 2024-05-27 11:20:10 +00:00
parent 1b8dea4a92
commit f3d6fbf52e
2 changed files with 21 additions and 14 deletions

@ -23,7 +23,6 @@
*/
#include "precompiled.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1HeapRegion.hpp"
#include "gc/g1/g1Predictions.hpp"
#include "gc/g1/g1SurvRateGroup.hpp"
@ -57,10 +56,6 @@ void G1SurvRateGroup::reset() {
// Seed initial _surv_rate_pred and _accum_surv_rate_pred values
guarantee(_stats_arrays_length == 1, "invariant" );
guarantee(_surv_rate_predictors[0] != nullptr, "invariant" );
const double initial_surv_rate = 0.4;
_surv_rate_predictors[0]->add(initial_surv_rate);
_last_pred = _accum_surv_rate_pred[0] = initial_surv_rate;
_num_added_regions = 0;
}
@ -75,8 +70,12 @@ void G1SurvRateGroup::stop_adding_regions() {
_surv_rate_predictors = REALLOC_C_HEAP_ARRAY(TruncatedSeq*, _surv_rate_predictors, _num_added_regions, mtGC);
for (size_t i = _stats_arrays_length; i < _num_added_regions; ++i) {
// Initialize predictors and accumulated survivor rate predictions.
_surv_rate_predictors[i] = new TruncatedSeq(10);
_surv_rate_predictors[i]->add(InitialSurvivorRate);
_accum_surv_rate_pred[i] = ((i == 0) ? 0.0 : _accum_surv_rate_pred[i-1]) + InitialSurvivorRate;
}
_last_pred = InitialSurvivorRate;
_stats_arrays_length = _num_added_regions;
}
@ -96,6 +95,19 @@ void G1SurvRateGroup::all_surviving_words_recorded(const G1Predictions& predicto
finalize_predictions(predictor);
}
double G1SurvRateGroup::accum_surv_rate_pred(uint age) const {
assert(_stats_arrays_length > 0, "invariant" );
double result;
if (age < _stats_arrays_length) {
result = _accum_surv_rate_pred[age];
} else {
double diff = (double)(age - _stats_arrays_length + 1);
result = _accum_surv_rate_pred[_stats_arrays_length - 1] + diff * _last_pred;
}
assert(result <= (age + 1.0), "Accumulated survivor rate %.2f must be smaller than age+1 %u", result, age + 1);
return result;
}
void G1SurvRateGroup::fill_in_last_surv_rates() {
if (_num_added_regions > 0) { // conservative
double surv_rate = _surv_rate_predictors[_num_added_regions-1]->last();

@ -52,6 +52,9 @@ class G1SurvRateGroup : public CHeapObj<mtGC> {
uint _stats_arrays_length;
uint _num_added_regions; // The number of regions in this survivor rate group.
// The initial survivor rate for predictors. Somewhat random value.
const double InitialSurvivorRate = 0.4;
double* _accum_surv_rate_pred;
double _last_pred;
TruncatedSeq** _surv_rate_predictors;
@ -73,15 +76,7 @@ public:
void record_surviving_words(uint age, size_t surv_words);
void all_surviving_words_recorded(const G1Predictions& predictor, bool update_predictors);
double accum_surv_rate_pred(uint age) const {
assert(_stats_arrays_length > 0, "invariant" );
if (age < _stats_arrays_length)
return _accum_surv_rate_pred[age];
else {
double diff = (double)(age - _stats_arrays_length + 1);
return _accum_surv_rate_pred[_stats_arrays_length - 1] + diff * _last_pred;
}
}
double accum_surv_rate_pred(uint age) const;
double surv_rate_pred(G1Predictions const& predictor, uint age) const {
assert(is_valid_age(age), "must be");