src/share/vm/gc_implementation/g1/survRateGroup.cpp

Mon, 03 Aug 2009 12:59:30 -0700

author
johnc
date
Mon, 03 Aug 2009 12:59:30 -0700
changeset 1324
15c5903cf9e1
parent 1014
0fbdb4381b99
child 1829
1316cec51b4d
permissions
-rw-r--r--

6865703: G1: Parallelize hot card cache cleanup
Summary: Have the GC worker threads clear the hot card cache in parallel by having each worker thread claim a chunk of the card cache and process the cards in that chunk. The size of the chunks that each thread will claim is determined at VM initialization from the size of the card cache and the number of worker threads.
Reviewed-by: jmasa, tonyp

ysr@777 1 /*
xdono@1014 2 * Copyright 2001-2009 Sun Microsystems, Inc. All Rights Reserved.
ysr@777 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ysr@777 4 *
ysr@777 5 * This code is free software; you can redistribute it and/or modify it
ysr@777 6 * under the terms of the GNU General Public License version 2 only, as
ysr@777 7 * published by the Free Software Foundation.
ysr@777 8 *
ysr@777 9 * This code is distributed in the hope that it will be useful, but WITHOUT
ysr@777 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ysr@777 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ysr@777 12 * version 2 for more details (a copy is included in the LICENSE file that
ysr@777 13 * accompanied this code).
ysr@777 14 *
ysr@777 15 * You should have received a copy of the GNU General Public License version
ysr@777 16 * 2 along with this work; if not, write to the Free Software Foundation,
ysr@777 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ysr@777 18 *
ysr@777 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
ysr@777 20 * CA 95054 USA or visit www.sun.com if you need additional information or
ysr@777 21 * have any questions.
ysr@777 22 *
ysr@777 23 */
ysr@777 24
ysr@777 25 #include "incls/_precompiled.incl"
ysr@777 26 #include "incls/_survRateGroup.cpp.incl"
ysr@777 27
ysr@777 28 SurvRateGroup::SurvRateGroup(G1CollectorPolicy* g1p,
ysr@777 29 const char* name,
ysr@777 30 size_t summary_surv_rates_len) :
ysr@777 31 _g1p(g1p), _name(name),
ysr@777 32 _summary_surv_rates_len(summary_surv_rates_len),
ysr@777 33 _summary_surv_rates_max_len(0),
apetrusenko@980 34 _summary_surv_rates(NULL),
apetrusenko@980 35 _surv_rate(NULL),
apetrusenko@980 36 _accum_surv_rate_pred(NULL),
apetrusenko@980 37 _surv_rate_pred(NULL)
apetrusenko@980 38 {
apetrusenko@980 39 reset();
ysr@777 40 if (summary_surv_rates_len > 0) {
ysr@777 41 size_t length = summary_surv_rates_len;
ysr@777 42 _summary_surv_rates = NEW_C_HEAP_ARRAY(NumberSeq*, length);
ysr@777 43 if (_summary_surv_rates == NULL) {
ysr@777 44 vm_exit_out_of_memory(sizeof(NumberSeq*) * length,
ysr@777 45 "Not enough space for surv rate summary");
ysr@777 46 }
ysr@777 47 for (size_t i = 0; i < length; ++i)
ysr@777 48 _summary_surv_rates[i] = new NumberSeq();
ysr@777 49 }
ysr@777 50
ysr@777 51 start_adding_regions();
ysr@777 52 }
ysr@777 53
apetrusenko@980 54
apetrusenko@980 55 void SurvRateGroup::reset()
apetrusenko@980 56 {
apetrusenko@980 57 _all_regions_allocated = 0;
apetrusenko@980 58 _scan_only_prefix = 0;
apetrusenko@980 59 _setup_seq_num = 0;
apetrusenko@980 60 _stats_arrays_length = 0;
apetrusenko@980 61 _accum_surv_rate = 0.0;
apetrusenko@980 62 _last_pred = 0.0;
apetrusenko@980 63 // the following will set up the arrays with length 1
apetrusenko@980 64 _region_num = 1;
apetrusenko@980 65 stop_adding_regions();
apetrusenko@980 66 guarantee( _stats_arrays_length == 1, "invariant" );
apetrusenko@980 67 guarantee( _surv_rate_pred[0] != NULL, "invariant" );
apetrusenko@980 68 _surv_rate_pred[0]->add(0.4);
apetrusenko@980 69 all_surviving_words_recorded(false);
apetrusenko@980 70 _region_num = 0;
apetrusenko@980 71 }
apetrusenko@980 72
apetrusenko@980 73
ysr@777 74 void
ysr@777 75 SurvRateGroup::start_adding_regions() {
apetrusenko@980 76 _setup_seq_num = _stats_arrays_length;
apetrusenko@980 77 _region_num = _scan_only_prefix;
ysr@777 78 _accum_surv_rate = 0.0;
ysr@777 79
ysr@777 80 #if 0
apetrusenko@980 81 gclog_or_tty->print_cr("[%s] start adding regions, seq num %d, length %d",
apetrusenko@980 82 _name, _setup_seq_num, _region_num);
ysr@777 83 #endif // 0
ysr@777 84 }
ysr@777 85
ysr@777 86 void
ysr@777 87 SurvRateGroup::stop_adding_regions() {
ysr@777 88
ysr@777 89 #if 0
apetrusenko@980 90 gclog_or_tty->print_cr("[%s] stop adding regions, length %d", _name, _region_num);
ysr@777 91 #endif // 0
ysr@777 92
apetrusenko@980 93 if (_region_num > _stats_arrays_length) {
ysr@777 94 double* old_surv_rate = _surv_rate;
ysr@777 95 double* old_accum_surv_rate_pred = _accum_surv_rate_pred;
ysr@777 96 TruncatedSeq** old_surv_rate_pred = _surv_rate_pred;
ysr@777 97
apetrusenko@980 98 _surv_rate = NEW_C_HEAP_ARRAY(double, _region_num);
ysr@777 99 if (_surv_rate == NULL) {
apetrusenko@980 100 vm_exit_out_of_memory(sizeof(double) * _region_num,
ysr@777 101 "Not enough space for surv rate array.");
ysr@777 102 }
apetrusenko@980 103 _accum_surv_rate_pred = NEW_C_HEAP_ARRAY(double, _region_num);
ysr@777 104 if (_accum_surv_rate_pred == NULL) {
apetrusenko@980 105 vm_exit_out_of_memory(sizeof(double) * _region_num,
ysr@777 106 "Not enough space for accum surv rate pred array.");
ysr@777 107 }
apetrusenko@980 108 _surv_rate_pred = NEW_C_HEAP_ARRAY(TruncatedSeq*, _region_num);
ysr@777 109 if (_surv_rate == NULL) {
apetrusenko@980 110 vm_exit_out_of_memory(sizeof(TruncatedSeq*) * _region_num,
ysr@777 111 "Not enough space for surv rate pred array.");
ysr@777 112 }
ysr@777 113
apetrusenko@980 114 for (size_t i = 0; i < _stats_arrays_length; ++i)
ysr@777 115 _surv_rate_pred[i] = old_surv_rate_pred[i];
ysr@777 116
ysr@777 117 #if 0
apetrusenko@980 118 gclog_or_tty->print_cr("[%s] stop adding regions, new seqs %d to %d",
apetrusenko@980 119 _name, _array_length, _region_num - 1);
ysr@777 120 #endif // 0
ysr@777 121
apetrusenko@980 122 for (size_t i = _stats_arrays_length; i < _region_num; ++i) {
ysr@777 123 _surv_rate_pred[i] = new TruncatedSeq(10);
ysr@777 124 // _surv_rate_pred[i]->add(last_pred);
ysr@777 125 }
ysr@777 126
apetrusenko@980 127 _stats_arrays_length = _region_num;
ysr@777 128
ysr@777 129 if (old_surv_rate != NULL)
ysr@777 130 FREE_C_HEAP_ARRAY(double, old_surv_rate);
ysr@777 131 if (old_accum_surv_rate_pred != NULL)
ysr@777 132 FREE_C_HEAP_ARRAY(double, old_accum_surv_rate_pred);
ysr@777 133 if (old_surv_rate_pred != NULL)
ysr@777 134 FREE_C_HEAP_ARRAY(NumberSeq*, old_surv_rate_pred);
ysr@777 135 }
ysr@777 136
apetrusenko@980 137 for (size_t i = 0; i < _stats_arrays_length; ++i)
ysr@777 138 _surv_rate[i] = 0.0;
ysr@777 139 }
ysr@777 140
ysr@777 141 double
ysr@777 142 SurvRateGroup::accum_surv_rate(size_t adjustment) {
ysr@777 143 // we might relax this one in the future...
ysr@777 144 guarantee( adjustment == 0 || adjustment == 1, "pre-condition" );
ysr@777 145
ysr@777 146 double ret = _accum_surv_rate;
ysr@777 147 if (adjustment > 0) {
apetrusenko@980 148 TruncatedSeq* seq = get_seq(_region_num+1);
ysr@777 149 double surv_rate = _g1p->get_new_prediction(seq);
ysr@777 150 ret += surv_rate;
ysr@777 151 }
ysr@777 152
ysr@777 153 return ret;
ysr@777 154 }
ysr@777 155
ysr@777 156 int
ysr@777 157 SurvRateGroup::next_age_index() {
apetrusenko@980 158 TruncatedSeq* seq = get_seq(_region_num);
ysr@777 159 double surv_rate = _g1p->get_new_prediction(seq);
ysr@777 160 _accum_surv_rate += surv_rate;
ysr@777 161
apetrusenko@980 162 ++_region_num;
ysr@777 163 return (int) ++_all_regions_allocated;
ysr@777 164 }
ysr@777 165
ysr@777 166 void
ysr@777 167 SurvRateGroup::record_scan_only_prefix(size_t scan_only_prefix) {
apetrusenko@980 168 guarantee( scan_only_prefix <= _region_num, "pre-condition" );
ysr@777 169 _scan_only_prefix = scan_only_prefix;
ysr@777 170 }
ysr@777 171
ysr@777 172 void
ysr@777 173 SurvRateGroup::record_surviving_words(int age_in_group, size_t surv_words) {
apetrusenko@980 174 guarantee( 0 <= age_in_group && (size_t) age_in_group < _region_num,
ysr@777 175 "pre-condition" );
ysr@777 176 guarantee( _surv_rate[age_in_group] <= 0.00001,
ysr@777 177 "should only update each slot once" );
ysr@777 178
ysr@777 179 double surv_rate = (double) surv_words / (double) HeapRegion::GrainWords;
ysr@777 180 _surv_rate[age_in_group] = surv_rate;
ysr@777 181 _surv_rate_pred[age_in_group]->add(surv_rate);
ysr@777 182 if ((size_t)age_in_group < _summary_surv_rates_len) {
ysr@777 183 _summary_surv_rates[age_in_group]->add(surv_rate);
ysr@777 184 if ((size_t)(age_in_group+1) > _summary_surv_rates_max_len)
ysr@777 185 _summary_surv_rates_max_len = age_in_group+1;
ysr@777 186 }
ysr@777 187 }
ysr@777 188
ysr@777 189 void
ysr@777 190 SurvRateGroup::all_surviving_words_recorded(bool propagate) {
apetrusenko@980 191 if (propagate && _region_num > 0) { // conservative
apetrusenko@980 192 double surv_rate = _surv_rate_pred[_region_num-1]->last();
ysr@777 193
ysr@777 194 #if 0
ysr@777 195 gclog_or_tty->print_cr("propagating %1.2lf from %d to %d",
ysr@777 196 surv_rate, _curr_length, _array_length - 1);
ysr@777 197 #endif // 0
ysr@777 198
apetrusenko@980 199 for (size_t i = _region_num; i < _stats_arrays_length; ++i) {
ysr@777 200 guarantee( _surv_rate[i] <= 0.00001,
ysr@777 201 "the slot should not have been updated" );
ysr@777 202 _surv_rate_pred[i]->add(surv_rate);
ysr@777 203 }
ysr@777 204 }
ysr@777 205
ysr@777 206 double accum = 0.0;
ysr@777 207 double pred = 0.0;
apetrusenko@980 208 for (size_t i = 0; i < _stats_arrays_length; ++i) {
ysr@777 209 pred = _g1p->get_new_prediction(_surv_rate_pred[i]);
ysr@777 210 if (pred > 1.0) pred = 1.0;
ysr@777 211 accum += pred;
ysr@777 212 _accum_surv_rate_pred[i] = accum;
ysr@777 213 // gclog_or_tty->print_cr("age %3d, accum %10.2lf", i, accum);
ysr@777 214 }
ysr@777 215 _last_pred = pred;
ysr@777 216 }
ysr@777 217
ysr@777 218 #ifndef PRODUCT
ysr@777 219 void
ysr@777 220 SurvRateGroup::print() {
ysr@777 221 gclog_or_tty->print_cr("Surv Rate Group: %s (%d entries, %d scan-only)",
apetrusenko@980 222 _name, _region_num, _scan_only_prefix);
apetrusenko@980 223 for (size_t i = 0; i < _region_num; ++i) {
ysr@777 224 gclog_or_tty->print_cr(" age %4d surv rate %6.2lf %% pred %6.2lf %%%s",
ysr@777 225 i, _surv_rate[i] * 100.0,
ysr@777 226 _g1p->get_new_prediction(_surv_rate_pred[i]) * 100.0,
ysr@777 227 (i < _scan_only_prefix) ? " S-O" : " ");
ysr@777 228 }
ysr@777 229 }
ysr@777 230
ysr@777 231 void
ysr@777 232 SurvRateGroup::print_surv_rate_summary() {
ysr@777 233 size_t length = _summary_surv_rates_max_len;
ysr@777 234 if (length == 0)
ysr@777 235 return;
ysr@777 236
ysr@777 237 gclog_or_tty->print_cr("");
ysr@777 238 gclog_or_tty->print_cr("%s Rate Summary (for up to age %d)", _name, length-1);
ysr@777 239 gclog_or_tty->print_cr(" age range survival rate (avg) samples (avg)");
ysr@777 240 gclog_or_tty->print_cr(" ---------------------------------------------------------");
ysr@777 241
ysr@777 242 size_t index = 0;
ysr@777 243 size_t limit = MIN2((int) length, 10);
ysr@777 244 while (index < limit) {
ysr@777 245 gclog_or_tty->print_cr(" %4d %6.2lf%% %6.2lf",
ysr@777 246 index, _summary_surv_rates[index]->avg() * 100.0,
ysr@777 247 (double) _summary_surv_rates[index]->num());
ysr@777 248 ++index;
ysr@777 249 }
ysr@777 250
ysr@777 251 gclog_or_tty->print_cr(" ---------------------------------------------------------");
ysr@777 252
ysr@777 253 int num = 0;
ysr@777 254 double sum = 0.0;
ysr@777 255 int samples = 0;
ysr@777 256 while (index < length) {
ysr@777 257 ++num;
ysr@777 258 sum += _summary_surv_rates[index]->avg() * 100.0;
ysr@777 259 samples += _summary_surv_rates[index]->num();
ysr@777 260 ++index;
ysr@777 261
ysr@777 262 if (index == length || num % 10 == 0) {
ysr@777 263 gclog_or_tty->print_cr(" %4d .. %4d %6.2lf%% %6.2lf",
ysr@777 264 (index-1) / 10 * 10, index-1, sum / (double) num,
ysr@777 265 (double) samples / (double) num);
ysr@777 266 sum = 0.0;
ysr@777 267 num = 0;
ysr@777 268 samples = 0;
ysr@777 269 }
ysr@777 270 }
ysr@777 271
ysr@777 272 gclog_or_tty->print_cr(" ---------------------------------------------------------");
ysr@777 273 }
ysr@777 274 #endif // PRODUCT

mercurial