1 /*
   2  * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "gc/g1/g1CollectedHeap.inline.hpp"
  27 #include "gc/g1/g1Predictions.hpp"
  28 #include "gc/g1/g1SurvRateGroup.hpp"
  29 #include "logging/log.hpp"
  30 #include "memory/allocation.hpp"
  31 
  32 G1SurvRateGroup::G1SurvRateGroup() :
  33   _stats_arrays_length(0),
  34   _accum_surv_rate_pred(NULL),
  35   _last_pred(0.0),
  36   _surv_rate_predictors(NULL),
  37   _num_added_regions(0) {
  38   reset();
  39   start_adding_regions();
  40 }
  41 
  42 void G1SurvRateGroup::reset() {
  43   _last_pred = 0.0;
  44   // the following will set up the arrays with length 1
  45   _num_added_regions = 1;
  46 
  47   // The call to stop_adding_regions() will use "new" to refill
  48   // the _surv_rate_pred array, so we need to make sure to call
  49   // "delete".
  50   for (size_t i = 0; i < _stats_arrays_length; ++i) {
  51     delete _surv_rate_predictors[i];
  52   }
  53   _stats_arrays_length = 0;
  54 
  55   stop_adding_regions();
  56 
  57   // Seed initial _surv_rate_pred and _accum_surv_rate_pred values
  58   guarantee(_stats_arrays_length == 1, "invariant" );
  59   guarantee(_surv_rate_predictors[0] != NULL, "invariant" );
  60   const double initial_surv_rate = 0.4;
  61   _surv_rate_predictors[0]->add(initial_surv_rate);
  62   _last_pred = _accum_surv_rate_pred[0] = initial_surv_rate;
  63 
  64   _num_added_regions = 0;
  65 }
  66 
  67 void G1SurvRateGroup::start_adding_regions() {
  68   _num_added_regions = 0;
  69 }
  70 
  71 void G1SurvRateGroup::stop_adding_regions() {
  72   if (_num_added_regions > _stats_arrays_length) {
  73     _accum_surv_rate_pred = REALLOC_C_HEAP_ARRAY(double, _accum_surv_rate_pred, _num_added_regions, mtGC);
  74     _surv_rate_predictors = REALLOC_C_HEAP_ARRAY(TruncatedSeq*, _surv_rate_predictors, _num_added_regions, mtGC);
  75 
  76     for (size_t i = _stats_arrays_length; i < _num_added_regions; ++i) {
  77       _surv_rate_predictors[i] = new TruncatedSeq(10);
  78     }
  79 
  80     _stats_arrays_length = _num_added_regions;
  81   }
  82 }
  83 
  84 void G1SurvRateGroup::record_surviving_words(int age_in_group, double surv_rate) {
  85   guarantee(0 <= age_in_group && (size_t)age_in_group < _num_added_regions,
  86             "age_in_group is %d not between 0 and " SIZE_FORMAT, age_in_group, _num_added_regions);
  87   _surv_rate_predictors[age_in_group]->add(surv_rate);
  88 }
  89 
  90 void G1SurvRateGroup::all_surviving_words_recorded(const G1Predictions& predictor, bool update_predictors) {
  91   if (update_predictors) {
  92     fill_in_last_surv_rates();
  93   }
  94   finalize_predictions(predictor);
  95 }
  96 
  97 void G1SurvRateGroup::fill_in_last_surv_rates() {
  98   if (_num_added_regions > 0) { // conservative
  99     double surv_rate = _surv_rate_predictors[_num_added_regions-1]->last();
 100     for (size_t i = _num_added_regions; i < _stats_arrays_length; ++i) {
 101       _surv_rate_predictors[i]->add(surv_rate);
 102     }
 103   }
 104 }
 105 
 106 void G1SurvRateGroup::finalize_predictions(const G1Predictions& predictor) {
 107   double accum = 0.0;
 108   double pred = 0.0;
 109   for (size_t i = 0; i < _stats_arrays_length; ++i) {
 110     pred = predictor.predict_in_unit_interval(_surv_rate_predictors[i]);
 111     accum += pred;
 112     _accum_surv_rate_pred[i] = accum;
 113   }
 114   _last_pred = pred;
 115 }