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