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 "memory/allocation.hpp" 31 32 SurvRateGroup::SurvRateGroup(G1Predictions* predictor, 33 const char* name, 34 size_t summary_surv_rates_len) : 35 _predictor(predictor), _name(name), 36 _summary_surv_rates_len(summary_surv_rates_len), 37 _summary_surv_rates_max_len(0), 38 _summary_surv_rates(NULL), 39 _surv_rate(NULL), 40 _accum_surv_rate_pred(NULL), 41 _surv_rate_pred(NULL), 42 _stats_arrays_length(0) { 43 reset(); 44 if (summary_surv_rates_len > 0) { 45 size_t length = summary_surv_rates_len; 46 _summary_surv_rates = NEW_C_HEAP_ARRAY(NumberSeq*, length, mtGC); 47 for (size_t i = 0; i < length; ++i) { 48 _summary_surv_rates[i] = new NumberSeq(); 49 } 50 } 51 52 start_adding_regions(); 53 } 54 55 double SurvRateGroup::get_new_prediction(TruncatedSeq const* seq) const { 56 return _predictor->get_new_prediction(seq); 57 } 58 59 void SurvRateGroup::reset() { 60 _all_regions_allocated = 0; 61 _setup_seq_num = 0; 62 _last_pred = 0.0; 63 // the following will set up the arrays with length 1 64 _region_num = 1; 65 66 // The call to stop_adding_regions() will use "new" to refill 67 // the _surv_rate_pred array, so we need to make sure to call 68 // "delete". 69 for (size_t i = 0; i < _stats_arrays_length; ++i) { 70 delete _surv_rate_pred[i]; 71 } 72 _stats_arrays_length = 0; 73 74 stop_adding_regions(); 75 guarantee( _stats_arrays_length == 1, "invariant" ); 76 guarantee( _surv_rate_pred[0] != NULL, "invariant" ); 77 _surv_rate_pred[0]->add(0.4); 78 all_surviving_words_recorded(false); 79 _region_num = 0; 80 } 81 82 void SurvRateGroup::start_adding_regions() { 83 _setup_seq_num = _stats_arrays_length; 84 _region_num = 0; 85 } 86 87 void SurvRateGroup::stop_adding_regions() { 88 if (_region_num > _stats_arrays_length) { 89 double* old_surv_rate = _surv_rate; 90 double* old_accum_surv_rate_pred = _accum_surv_rate_pred; 91 TruncatedSeq** old_surv_rate_pred = _surv_rate_pred; 92 93 _surv_rate = NEW_C_HEAP_ARRAY(double, _region_num, mtGC); 94 _accum_surv_rate_pred = NEW_C_HEAP_ARRAY(double, _region_num, mtGC); 95 _surv_rate_pred = NEW_C_HEAP_ARRAY(TruncatedSeq*, _region_num, mtGC); 96 97 for (size_t i = 0; i < _stats_arrays_length; ++i) { 98 _surv_rate_pred[i] = old_surv_rate_pred[i]; 99 } 100 for (size_t i = _stats_arrays_length; i < _region_num; ++i) { 101 _surv_rate_pred[i] = new TruncatedSeq(10); 102 } 103 104 _stats_arrays_length = _region_num; 105 106 if (old_surv_rate != NULL) { 107 FREE_C_HEAP_ARRAY(double, old_surv_rate); 108 } 109 if (old_accum_surv_rate_pred != NULL) { 110 FREE_C_HEAP_ARRAY(double, old_accum_surv_rate_pred); 111 } 112 if (old_surv_rate_pred != NULL) { 113 FREE_C_HEAP_ARRAY(TruncatedSeq*, old_surv_rate_pred); 114 } 115 } 116 117 for (size_t i = 0; i < _stats_arrays_length; ++i) { 118 _surv_rate[i] = 0.0; 119 } 120 } 121 122 int SurvRateGroup::next_age_index() { 123 ++_region_num; 124 return (int) ++_all_regions_allocated; 125 } 126 127 void SurvRateGroup::record_surviving_words(int age_in_group, size_t surv_words) { 128 guarantee( 0 <= age_in_group && (size_t) age_in_group < _region_num, 129 "pre-condition" ); 130 guarantee( _surv_rate[age_in_group] <= 0.00001, 131 "should only update each slot once" ); 132 133 double surv_rate = (double) surv_words / (double) HeapRegion::GrainWords; 134 _surv_rate[age_in_group] = surv_rate; 135 _surv_rate_pred[age_in_group]->add(surv_rate); 136 if ((size_t)age_in_group < _summary_surv_rates_len) { 137 _summary_surv_rates[age_in_group]->add(surv_rate); 138 if ((size_t)(age_in_group+1) > _summary_surv_rates_max_len) 139 _summary_surv_rates_max_len = age_in_group+1; 140 } 141 } 142 143 void SurvRateGroup::all_surviving_words_recorded(bool update_predictors) { 144 if (update_predictors && _region_num > 0) { // conservative 145 double surv_rate = _surv_rate_pred[_region_num-1]->last(); 146 for (size_t i = _region_num; i < _stats_arrays_length; ++i) { 147 guarantee( _surv_rate[i] <= 0.00001, 148 "the slot should not have been updated" ); 149 _surv_rate_pred[i]->add(surv_rate); 150 } 151 } 152 153 double accum = 0.0; 154 double pred = 0.0; 155 for (size_t i = 0; i < _stats_arrays_length; ++i) { 156 pred = get_new_prediction(_surv_rate_pred[i]); 157 if (pred > 1.0) pred = 1.0; 158 accum += pred; 159 _accum_surv_rate_pred[i] = accum; 160 } 161 _last_pred = pred; 162 } 163 164 #ifndef PRODUCT 165 void SurvRateGroup::print() { 166 gclog_or_tty->print_cr("Surv Rate Group: %s (" SIZE_FORMAT " entries)", 167 _name, _region_num); 168 for (size_t i = 0; i < _region_num; ++i) { 169 gclog_or_tty->print_cr(" age " SIZE_FORMAT_W(4) " surv rate %6.2lf %% pred %6.2lf %%", 170 i, _surv_rate[i] * 100.0, 171 _predictor->get_new_prediction(_surv_rate_pred[i]) * 100.0); 172 } 173 } 174 175 void 176 SurvRateGroup::print_surv_rate_summary() { 177 size_t length = _summary_surv_rates_max_len; 178 if (length == 0) 179 return; 180 181 gclog_or_tty->cr(); 182 gclog_or_tty->print_cr("%s Rate Summary (for up to age " SIZE_FORMAT ")", _name, length-1); 183 gclog_or_tty->print_cr(" age range survival rate (avg) samples (avg)"); 184 gclog_or_tty->print_cr(" ---------------------------------------------------------"); 185 186 size_t index = 0; 187 size_t limit = MIN2((int) length, 10); 188 while (index < limit) { 189 gclog_or_tty->print_cr(" " SIZE_FORMAT_W(4) 190 " %6.2lf%% %6.2lf", 191 index, _summary_surv_rates[index]->avg() * 100.0, 192 (double) _summary_surv_rates[index]->num()); 193 ++index; 194 } 195 196 gclog_or_tty->print_cr(" ---------------------------------------------------------"); 197 198 int num = 0; 199 double sum = 0.0; 200 int samples = 0; 201 while (index < length) { 202 ++num; 203 sum += _summary_surv_rates[index]->avg() * 100.0; 204 samples += _summary_surv_rates[index]->num(); 205 ++index; 206 207 if (index == length || num % 10 == 0) { 208 gclog_or_tty->print_cr(" " SIZE_FORMAT_W(4) " .. " SIZE_FORMAT_W(4) 209 " %6.2lf%% %6.2lf", 210 (index-1) / 10 * 10, index-1, sum / (double) num, 211 (double) samples / (double) num); 212 sum = 0.0; 213 num = 0; 214 samples = 0; 215 } 216 } 217 218 gclog_or_tty->print_cr(" ---------------------------------------------------------"); 219 } 220 #endif // PRODUCT