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/g1CollectorPolicy.hpp" 28 #include "gc/g1/heapRegion.hpp" 29 #include "gc/g1/survRateGroup.hpp" 30 #include "memory/allocation.hpp" 31 32 SurvRateGroup::SurvRateGroup(G1CollectorPolicy* g1p, 33 const char* name, 34 size_t summary_surv_rates_len) : 35 _g1p(g1p), _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 void SurvRateGroup::reset() { 56 _all_regions_allocated = 0; 57 _setup_seq_num = 0; 58 _accum_surv_rate = 0.0; 59 _last_pred = 0.0; 60 // the following will set up the arrays with length 1 61 _region_num = 1; 62 63 // The call to stop_adding_regions() will use "new" to refill 64 // the _surv_rate_pred array, so we need to make sure to call 65 // "delete". 66 for (size_t i = 0; i < _stats_arrays_length; ++i) { 67 delete _surv_rate_pred[i]; 68 } 69 _stats_arrays_length = 0; 70 71 stop_adding_regions(); 72 guarantee( _stats_arrays_length == 1, "invariant" ); 73 guarantee( _surv_rate_pred[0] != NULL, "invariant" ); 74 _surv_rate_pred[0]->add(0.4); 75 all_surviving_words_recorded(false); 76 _region_num = 0; 77 } 78 79 void 80 SurvRateGroup::start_adding_regions() { 81 _setup_seq_num = _stats_arrays_length; 82 _region_num = 0; 83 _accum_surv_rate = 0.0; 84 } 85 86 void 87 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 double 123 SurvRateGroup::accum_surv_rate(size_t adjustment) { 124 // we might relax this one in the future... 125 guarantee( adjustment == 0 || adjustment == 1, "pre-condition" ); 126 127 double ret = _accum_surv_rate; 128 if (adjustment > 0) { 129 TruncatedSeq* seq = get_seq(_region_num+1); 130 double surv_rate = _g1p->get_new_prediction(seq); 131 ret += surv_rate; 132 } 133 134 return ret; 135 } 136 137 int 138 SurvRateGroup::next_age_index() { 139 TruncatedSeq* seq = get_seq(_region_num); 140 double surv_rate = _g1p->get_new_prediction(seq); 141 _accum_surv_rate += surv_rate; 142 143 ++_region_num; 144 return (int) ++_all_regions_allocated; 145 } 146 147 void 148 SurvRateGroup::record_surviving_words(int age_in_group, size_t surv_words) { 149 guarantee( 0 <= age_in_group && (size_t) age_in_group < _region_num, 150 "pre-condition" ); 151 guarantee( _surv_rate[age_in_group] <= 0.00001, 152 "should only update each slot once" ); 153 154 double surv_rate = (double) surv_words / (double) HeapRegion::GrainWords; 155 _surv_rate[age_in_group] = surv_rate; 156 _surv_rate_pred[age_in_group]->add(surv_rate); 157 if ((size_t)age_in_group < _summary_surv_rates_len) { 158 _summary_surv_rates[age_in_group]->add(surv_rate); 159 if ((size_t)(age_in_group+1) > _summary_surv_rates_max_len) 160 _summary_surv_rates_max_len = age_in_group+1; 161 } 162 } 163 164 void 165 SurvRateGroup::all_surviving_words_recorded(bool propagate) { 166 if (propagate && _region_num > 0) { // conservative 167 double surv_rate = _surv_rate_pred[_region_num-1]->last(); 168 for (size_t i = _region_num; i < _stats_arrays_length; ++i) { 169 guarantee( _surv_rate[i] <= 0.00001, 170 "the slot should not have been updated" ); 171 _surv_rate_pred[i]->add(surv_rate); 172 } 173 } 174 175 double accum = 0.0; 176 double pred = 0.0; 177 for (size_t i = 0; i < _stats_arrays_length; ++i) { 178 pred = _g1p->get_new_prediction(_surv_rate_pred[i]); 179 if (pred > 1.0) pred = 1.0; 180 accum += pred; 181 _accum_surv_rate_pred[i] = accum; 182 // gclog_or_tty->print_cr("age %3d, accum %10.2lf", i, accum); 183 } 184 _last_pred = pred; 185 } 186 187 #ifndef PRODUCT 188 void 189 SurvRateGroup::print() { 190 gclog_or_tty->print_cr("Surv Rate Group: %s (" SIZE_FORMAT " entries)", 191 _name, _region_num); 192 for (size_t i = 0; i < _region_num; ++i) { 193 gclog_or_tty->print_cr(" age " SIZE_FORMAT_W(4) " surv rate %6.2lf %% pred %6.2lf %%", 194 i, _surv_rate[i] * 100.0, 195 _g1p->get_new_prediction(_surv_rate_pred[i]) * 100.0); 196 } 197 } 198 199 void 200 SurvRateGroup::print_surv_rate_summary() { 201 size_t length = _summary_surv_rates_max_len; 202 if (length == 0) 203 return; 204 205 gclog_or_tty->cr(); 206 gclog_or_tty->print_cr("%s Rate Summary (for up to age " SIZE_FORMAT ")", _name, length-1); 207 gclog_or_tty->print_cr(" age range survival rate (avg) samples (avg)"); 208 gclog_or_tty->print_cr(" ---------------------------------------------------------"); 209 210 size_t index = 0; 211 size_t limit = MIN2((int) length, 10); 212 while (index < limit) { 213 gclog_or_tty->print_cr(" " SIZE_FORMAT_W(4) 214 " %6.2lf%% %6.2lf", 215 index, _summary_surv_rates[index]->avg() * 100.0, 216 (double) _summary_surv_rates[index]->num()); 217 ++index; 218 } 219 220 gclog_or_tty->print_cr(" ---------------------------------------------------------"); 221 222 int num = 0; 223 double sum = 0.0; 224 int samples = 0; 225 while (index < length) { 226 ++num; 227 sum += _summary_surv_rates[index]->avg() * 100.0; 228 samples += _summary_surv_rates[index]->num(); 229 ++index; 230 231 if (index == length || num % 10 == 0) { 232 gclog_or_tty->print_cr(" " SIZE_FORMAT_W(4) " .. " SIZE_FORMAT_W(4) 233 " %6.2lf%% %6.2lf", 234 (index-1) / 10 * 10, index-1, sum / (double) num, 235 (double) samples / (double) num); 236 sum = 0.0; 237 num = 0; 238 samples = 0; 239 } 240 } 241 242 gclog_or_tty->print_cr(" ---------------------------------------------------------"); 243 } 244 #endif // PRODUCT