1 /*
   2  * Copyright (c) 2001, 2015, 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/heapRegion.hpp"
  29 #include "gc/g1/survRateGroup.hpp"
  30 #include "logging/log.hpp"
  31 #include "memory/allocation.hpp"
  32 
  33 SurvRateGroup::SurvRateGroup() :
  34   _stats_arrays_length(0),
  35   _accum_surv_rate_pred(NULL),
  36   _last_pred(0.0),
  37   _surv_rate_predictors(NULL),
  38   _num_added_regions(0) {
  39   reset();
  40   start_adding_regions();
  41 }
  42 
  43 void SurvRateGroup::reset() {
  44   _last_pred = 0.0;
  45   // the following will set up the arrays with length 1
  46   _num_added_regions = 1;
  47 
  48   // The call to stop_adding_regions() will use "new" to refill
  49   // the _surv_rate_pred array, so we need to make sure to call
  50   // "delete".
  51   for (size_t i = 0; i < _stats_arrays_length; ++i) {
  52     delete _surv_rate_predictors[i];
  53   }
  54   _stats_arrays_length = 0;
  55 
  56   stop_adding_regions();
  57 
  58   // Seed initial _surv_rate_pred and _accum_surv_rate_pred values
  59   guarantee(_stats_arrays_length == 1, "invariant" );
  60   guarantee(_surv_rate_predictors[0] != NULL, "invariant" );
  61   const double initial_surv_rate = 0.4;
  62   _surv_rate_predictors[0]->add(initial_surv_rate);
  63   _last_pred = _accum_surv_rate_pred[0] = initial_surv_rate;
  64 
  65   _num_added_regions = 0;
  66 }
  67 
  68 void SurvRateGroup::start_adding_regions() {
  69   _num_added_regions = 0;
  70 }
  71 
  72 void SurvRateGroup::stop_adding_regions() {
  73   if (_num_added_regions > _stats_arrays_length) {
  74     _accum_surv_rate_pred = REALLOC_C_HEAP_ARRAY(double, _accum_surv_rate_pred, _num_added_regions, mtGC);
  75     _surv_rate_predictors = REALLOC_C_HEAP_ARRAY(TruncatedSeq*, _surv_rate_predictors, _num_added_regions, mtGC);
  76 
  77     for (size_t i = _stats_arrays_length; i < _num_added_regions; ++i) {
  78       _surv_rate_predictors[i] = new TruncatedSeq(10);
  79     }
  80 
  81     _stats_arrays_length = _num_added_regions;
  82   }
  83 }
  84 
  85 void SurvRateGroup::record_surviving_words(int age_in_group, size_t surv_words) {
  86   guarantee(0 <= age_in_group && (size_t)age_in_group < _num_added_regions,
  87             "age_in_group is %d not between 0 and " SIZE_FORMAT, age_in_group, _num_added_regions);
  88 
  89   double surv_rate = (double)surv_words / HeapRegion::GrainWords;
  90   _surv_rate_predictors[age_in_group]->add(surv_rate);
  91 }
  92 
  93 void SurvRateGroup::all_surviving_words_recorded(const G1Predictions& predictor, bool update_predictors) {
  94   if (update_predictors) {
  95     fill_in_last_surv_rates();
  96   }
  97   finalize_predictions(predictor);
  98 }
  99 
 100 void SurvRateGroup::fill_in_last_surv_rates() {
 101   if (_num_added_regions > 0) { // conservative
 102     double surv_rate = _surv_rate_predictors[_num_added_regions-1]->last();
 103     for (size_t i = _num_added_regions; i < _stats_arrays_length; ++i) {
 104       _surv_rate_predictors[i]->add(surv_rate);
 105     }
 106   }
 107 }
 108 
 109 void SurvRateGroup::finalize_predictions(const G1Predictions& predictor) {
 110   double accum = 0.0;
 111   double pred = 0.0;
 112   for (size_t i = 0; i < _stats_arrays_length; ++i) {
 113     pred = predictor.get_new_unit_prediction(_surv_rate_predictors[i]);
 114     accum += pred;
 115     _accum_surv_rate_pred[i] = accum;
 116   }
 117   _last_pred = pred;
 118 }