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