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

Mon, 02 Aug 2010 12:51:43 -0700

author
johnc
date
Mon, 02 Aug 2010 12:51:43 -0700
changeset 2060
2d160770d2e5
parent 1907
c18cbe5936b8
child 2314
f95d63e2154a
permissions
-rw-r--r--

6814437: G1: remove the _new_refs array
Summary: The per-worker _new_refs array is used to hold references that point into the collection set. It is populated during RSet updating and subsequently processed. In the event of an evacuation failure it processed again to recreate the RSets of regions in the collection set. Remove the per-worker _new_refs array by processing the references directly. Use a DirtyCardQueue to hold the cards containing the references so that the RSets of regions in the collection set can be recreated when handling an evacuation failure.
Reviewed-by: iveresov, jmasa, tonyp

ysr@777 1 /*
trims@1907 2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. 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 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * 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 _setup_seq_num = 0;
apetrusenko@980 59 _stats_arrays_length = 0;
apetrusenko@980 60 _accum_surv_rate = 0.0;
apetrusenko@980 61 _last_pred = 0.0;
apetrusenko@980 62 // the following will set up the arrays with length 1
apetrusenko@980 63 _region_num = 1;
apetrusenko@980 64 stop_adding_regions();
apetrusenko@980 65 guarantee( _stats_arrays_length == 1, "invariant" );
apetrusenko@980 66 guarantee( _surv_rate_pred[0] != NULL, "invariant" );
apetrusenko@980 67 _surv_rate_pred[0]->add(0.4);
apetrusenko@980 68 all_surviving_words_recorded(false);
apetrusenko@980 69 _region_num = 0;
apetrusenko@980 70 }
apetrusenko@980 71
apetrusenko@980 72
ysr@777 73 void
ysr@777 74 SurvRateGroup::start_adding_regions() {
apetrusenko@980 75 _setup_seq_num = _stats_arrays_length;
johnc@1829 76 _region_num = 0;
ysr@777 77 _accum_surv_rate = 0.0;
ysr@777 78
ysr@777 79 #if 0
apetrusenko@980 80 gclog_or_tty->print_cr("[%s] start adding regions, seq num %d, length %d",
apetrusenko@980 81 _name, _setup_seq_num, _region_num);
ysr@777 82 #endif // 0
ysr@777 83 }
ysr@777 84
ysr@777 85 void
ysr@777 86 SurvRateGroup::stop_adding_regions() {
ysr@777 87
ysr@777 88 #if 0
apetrusenko@980 89 gclog_or_tty->print_cr("[%s] stop adding regions, length %d", _name, _region_num);
ysr@777 90 #endif // 0
ysr@777 91
apetrusenko@980 92 if (_region_num > _stats_arrays_length) {
ysr@777 93 double* old_surv_rate = _surv_rate;
ysr@777 94 double* old_accum_surv_rate_pred = _accum_surv_rate_pred;
ysr@777 95 TruncatedSeq** old_surv_rate_pred = _surv_rate_pred;
ysr@777 96
apetrusenko@980 97 _surv_rate = NEW_C_HEAP_ARRAY(double, _region_num);
ysr@777 98 if (_surv_rate == NULL) {
apetrusenko@980 99 vm_exit_out_of_memory(sizeof(double) * _region_num,
ysr@777 100 "Not enough space for surv rate array.");
ysr@777 101 }
apetrusenko@980 102 _accum_surv_rate_pred = NEW_C_HEAP_ARRAY(double, _region_num);
ysr@777 103 if (_accum_surv_rate_pred == NULL) {
apetrusenko@980 104 vm_exit_out_of_memory(sizeof(double) * _region_num,
ysr@777 105 "Not enough space for accum surv rate pred array.");
ysr@777 106 }
apetrusenko@980 107 _surv_rate_pred = NEW_C_HEAP_ARRAY(TruncatedSeq*, _region_num);
ysr@777 108 if (_surv_rate == NULL) {
apetrusenko@980 109 vm_exit_out_of_memory(sizeof(TruncatedSeq*) * _region_num,
ysr@777 110 "Not enough space for surv rate pred array.");
ysr@777 111 }
ysr@777 112
apetrusenko@980 113 for (size_t i = 0; i < _stats_arrays_length; ++i)
ysr@777 114 _surv_rate_pred[i] = old_surv_rate_pred[i];
ysr@777 115
ysr@777 116 #if 0
apetrusenko@980 117 gclog_or_tty->print_cr("[%s] stop adding regions, new seqs %d to %d",
apetrusenko@980 118 _name, _array_length, _region_num - 1);
ysr@777 119 #endif // 0
ysr@777 120
apetrusenko@980 121 for (size_t i = _stats_arrays_length; i < _region_num; ++i) {
ysr@777 122 _surv_rate_pred[i] = new TruncatedSeq(10);
ysr@777 123 // _surv_rate_pred[i]->add(last_pred);
ysr@777 124 }
ysr@777 125
apetrusenko@980 126 _stats_arrays_length = _region_num;
ysr@777 127
ysr@777 128 if (old_surv_rate != NULL)
ysr@777 129 FREE_C_HEAP_ARRAY(double, old_surv_rate);
ysr@777 130 if (old_accum_surv_rate_pred != NULL)
ysr@777 131 FREE_C_HEAP_ARRAY(double, old_accum_surv_rate_pred);
ysr@777 132 if (old_surv_rate_pred != NULL)
ysr@777 133 FREE_C_HEAP_ARRAY(NumberSeq*, old_surv_rate_pred);
ysr@777 134 }
ysr@777 135
apetrusenko@980 136 for (size_t i = 0; i < _stats_arrays_length; ++i)
ysr@777 137 _surv_rate[i] = 0.0;
ysr@777 138 }
ysr@777 139
ysr@777 140 double
ysr@777 141 SurvRateGroup::accum_surv_rate(size_t adjustment) {
ysr@777 142 // we might relax this one in the future...
ysr@777 143 guarantee( adjustment == 0 || adjustment == 1, "pre-condition" );
ysr@777 144
ysr@777 145 double ret = _accum_surv_rate;
ysr@777 146 if (adjustment > 0) {
apetrusenko@980 147 TruncatedSeq* seq = get_seq(_region_num+1);
ysr@777 148 double surv_rate = _g1p->get_new_prediction(seq);
ysr@777 149 ret += surv_rate;
ysr@777 150 }
ysr@777 151
ysr@777 152 return ret;
ysr@777 153 }
ysr@777 154
ysr@777 155 int
ysr@777 156 SurvRateGroup::next_age_index() {
apetrusenko@980 157 TruncatedSeq* seq = get_seq(_region_num);
ysr@777 158 double surv_rate = _g1p->get_new_prediction(seq);
ysr@777 159 _accum_surv_rate += surv_rate;
ysr@777 160
apetrusenko@980 161 ++_region_num;
ysr@777 162 return (int) ++_all_regions_allocated;
ysr@777 163 }
ysr@777 164
ysr@777 165 void
ysr@777 166 SurvRateGroup::record_surviving_words(int age_in_group, size_t surv_words) {
apetrusenko@980 167 guarantee( 0 <= age_in_group && (size_t) age_in_group < _region_num,
ysr@777 168 "pre-condition" );
ysr@777 169 guarantee( _surv_rate[age_in_group] <= 0.00001,
ysr@777 170 "should only update each slot once" );
ysr@777 171
ysr@777 172 double surv_rate = (double) surv_words / (double) HeapRegion::GrainWords;
ysr@777 173 _surv_rate[age_in_group] = surv_rate;
ysr@777 174 _surv_rate_pred[age_in_group]->add(surv_rate);
ysr@777 175 if ((size_t)age_in_group < _summary_surv_rates_len) {
ysr@777 176 _summary_surv_rates[age_in_group]->add(surv_rate);
ysr@777 177 if ((size_t)(age_in_group+1) > _summary_surv_rates_max_len)
ysr@777 178 _summary_surv_rates_max_len = age_in_group+1;
ysr@777 179 }
ysr@777 180 }
ysr@777 181
ysr@777 182 void
ysr@777 183 SurvRateGroup::all_surviving_words_recorded(bool propagate) {
apetrusenko@980 184 if (propagate && _region_num > 0) { // conservative
apetrusenko@980 185 double surv_rate = _surv_rate_pred[_region_num-1]->last();
ysr@777 186
ysr@777 187 #if 0
ysr@777 188 gclog_or_tty->print_cr("propagating %1.2lf from %d to %d",
ysr@777 189 surv_rate, _curr_length, _array_length - 1);
ysr@777 190 #endif // 0
ysr@777 191
apetrusenko@980 192 for (size_t i = _region_num; i < _stats_arrays_length; ++i) {
ysr@777 193 guarantee( _surv_rate[i] <= 0.00001,
ysr@777 194 "the slot should not have been updated" );
ysr@777 195 _surv_rate_pred[i]->add(surv_rate);
ysr@777 196 }
ysr@777 197 }
ysr@777 198
ysr@777 199 double accum = 0.0;
ysr@777 200 double pred = 0.0;
apetrusenko@980 201 for (size_t i = 0; i < _stats_arrays_length; ++i) {
ysr@777 202 pred = _g1p->get_new_prediction(_surv_rate_pred[i]);
ysr@777 203 if (pred > 1.0) pred = 1.0;
ysr@777 204 accum += pred;
ysr@777 205 _accum_surv_rate_pred[i] = accum;
ysr@777 206 // gclog_or_tty->print_cr("age %3d, accum %10.2lf", i, accum);
ysr@777 207 }
ysr@777 208 _last_pred = pred;
ysr@777 209 }
ysr@777 210
ysr@777 211 #ifndef PRODUCT
ysr@777 212 void
ysr@777 213 SurvRateGroup::print() {
johnc@1829 214 gclog_or_tty->print_cr("Surv Rate Group: %s (%d entries)",
johnc@1829 215 _name, _region_num);
apetrusenko@980 216 for (size_t i = 0; i < _region_num; ++i) {
johnc@1829 217 gclog_or_tty->print_cr(" age %4d surv rate %6.2lf %% pred %6.2lf %%",
ysr@777 218 i, _surv_rate[i] * 100.0,
johnc@1829 219 _g1p->get_new_prediction(_surv_rate_pred[i]) * 100.0);
ysr@777 220 }
ysr@777 221 }
ysr@777 222
ysr@777 223 void
ysr@777 224 SurvRateGroup::print_surv_rate_summary() {
ysr@777 225 size_t length = _summary_surv_rates_max_len;
ysr@777 226 if (length == 0)
ysr@777 227 return;
ysr@777 228
ysr@777 229 gclog_or_tty->print_cr("");
ysr@777 230 gclog_or_tty->print_cr("%s Rate Summary (for up to age %d)", _name, length-1);
ysr@777 231 gclog_or_tty->print_cr(" age range survival rate (avg) samples (avg)");
ysr@777 232 gclog_or_tty->print_cr(" ---------------------------------------------------------");
ysr@777 233
ysr@777 234 size_t index = 0;
ysr@777 235 size_t limit = MIN2((int) length, 10);
ysr@777 236 while (index < limit) {
ysr@777 237 gclog_or_tty->print_cr(" %4d %6.2lf%% %6.2lf",
ysr@777 238 index, _summary_surv_rates[index]->avg() * 100.0,
ysr@777 239 (double) _summary_surv_rates[index]->num());
ysr@777 240 ++index;
ysr@777 241 }
ysr@777 242
ysr@777 243 gclog_or_tty->print_cr(" ---------------------------------------------------------");
ysr@777 244
ysr@777 245 int num = 0;
ysr@777 246 double sum = 0.0;
ysr@777 247 int samples = 0;
ysr@777 248 while (index < length) {
ysr@777 249 ++num;
ysr@777 250 sum += _summary_surv_rates[index]->avg() * 100.0;
ysr@777 251 samples += _summary_surv_rates[index]->num();
ysr@777 252 ++index;
ysr@777 253
ysr@777 254 if (index == length || num % 10 == 0) {
ysr@777 255 gclog_or_tty->print_cr(" %4d .. %4d %6.2lf%% %6.2lf",
ysr@777 256 (index-1) / 10 * 10, index-1, sum / (double) num,
ysr@777 257 (double) samples / (double) num);
ysr@777 258 sum = 0.0;
ysr@777 259 num = 0;
ysr@777 260 samples = 0;
ysr@777 261 }
ysr@777 262 }
ysr@777 263
ysr@777 264 gclog_or_tty->print_cr(" ---------------------------------------------------------");
ysr@777 265 }
ysr@777 266 #endif // PRODUCT

mercurial