Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/g1/survRateGroup.cpp @ 1886:72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
Summary: There is a race between the concurrent refinement threads and the humongous object allocation that can cause the concurrent refinement threads to corrupt the part of the BOT that it is being initialized by the humongous object allocation operation. The solution is to do the humongous object allocation in careful steps to ensure that the concurrent refinement threads always have a consistent view over the BOT, region contents, and top. The fix includes some very minor tidying up in sparsePRT.
Reviewed-by: jcoomes, johnc, ysr
author | tonyp |
---|---|
date | Sat, 16 Oct 2010 17:12:19 -0400 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
342 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1394
diff
changeset
|
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. |
342 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1394
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1394
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1394
diff
changeset
|
21 * questions. |
342 | 22 * |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_survRateGroup.cpp.incl" | |
27 | |
28 SurvRateGroup::SurvRateGroup(G1CollectorPolicy* g1p, | |
29 const char* name, | |
30 size_t summary_surv_rates_len) : | |
31 _g1p(g1p), _name(name), | |
32 _summary_surv_rates_len(summary_surv_rates_len), | |
33 _summary_surv_rates_max_len(0), | |
545 | 34 _summary_surv_rates(NULL), |
35 _surv_rate(NULL), | |
36 _accum_surv_rate_pred(NULL), | |
37 _surv_rate_pred(NULL) | |
38 { | |
39 reset(); | |
342 | 40 if (summary_surv_rates_len > 0) { |
41 size_t length = summary_surv_rates_len; | |
42 _summary_surv_rates = NEW_C_HEAP_ARRAY(NumberSeq*, length); | |
43 if (_summary_surv_rates == NULL) { | |
44 vm_exit_out_of_memory(sizeof(NumberSeq*) * length, | |
45 "Not enough space for surv rate summary"); | |
46 } | |
47 for (size_t i = 0; i < length; ++i) | |
48 _summary_surv_rates[i] = new NumberSeq(); | |
49 } | |
50 | |
51 start_adding_regions(); | |
52 } | |
53 | |
545 | 54 |
55 void SurvRateGroup::reset() | |
56 { | |
57 _all_regions_allocated = 0; | |
58 _setup_seq_num = 0; | |
59 _stats_arrays_length = 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 stop_adding_regions(); | |
65 guarantee( _stats_arrays_length == 1, "invariant" ); | |
66 guarantee( _surv_rate_pred[0] != NULL, "invariant" ); | |
67 _surv_rate_pred[0]->add(0.4); | |
68 all_surviving_words_recorded(false); | |
69 _region_num = 0; | |
70 } | |
71 | |
72 | |
342 | 73 void |
74 SurvRateGroup::start_adding_regions() { | |
545 | 75 _setup_seq_num = _stats_arrays_length; |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
579
diff
changeset
|
76 _region_num = 0; |
342 | 77 _accum_surv_rate = 0.0; |
78 | |
79 #if 0 | |
545 | 80 gclog_or_tty->print_cr("[%s] start adding regions, seq num %d, length %d", |
81 _name, _setup_seq_num, _region_num); | |
342 | 82 #endif // 0 |
83 } | |
84 | |
85 void | |
86 SurvRateGroup::stop_adding_regions() { | |
87 | |
88 #if 0 | |
545 | 89 gclog_or_tty->print_cr("[%s] stop adding regions, length %d", _name, _region_num); |
342 | 90 #endif // 0 |
91 | |
545 | 92 if (_region_num > _stats_arrays_length) { |
342 | 93 double* old_surv_rate = _surv_rate; |
94 double* old_accum_surv_rate_pred = _accum_surv_rate_pred; | |
95 TruncatedSeq** old_surv_rate_pred = _surv_rate_pred; | |
96 | |
545 | 97 _surv_rate = NEW_C_HEAP_ARRAY(double, _region_num); |
342 | 98 if (_surv_rate == NULL) { |
545 | 99 vm_exit_out_of_memory(sizeof(double) * _region_num, |
342 | 100 "Not enough space for surv rate array."); |
101 } | |
545 | 102 _accum_surv_rate_pred = NEW_C_HEAP_ARRAY(double, _region_num); |
342 | 103 if (_accum_surv_rate_pred == NULL) { |
545 | 104 vm_exit_out_of_memory(sizeof(double) * _region_num, |
342 | 105 "Not enough space for accum surv rate pred array."); |
106 } | |
545 | 107 _surv_rate_pred = NEW_C_HEAP_ARRAY(TruncatedSeq*, _region_num); |
342 | 108 if (_surv_rate == NULL) { |
545 | 109 vm_exit_out_of_memory(sizeof(TruncatedSeq*) * _region_num, |
342 | 110 "Not enough space for surv rate pred array."); |
111 } | |
112 | |
545 | 113 for (size_t i = 0; i < _stats_arrays_length; ++i) |
342 | 114 _surv_rate_pred[i] = old_surv_rate_pred[i]; |
115 | |
116 #if 0 | |
545 | 117 gclog_or_tty->print_cr("[%s] stop adding regions, new seqs %d to %d", |
118 _name, _array_length, _region_num - 1); | |
342 | 119 #endif // 0 |
120 | |
545 | 121 for (size_t i = _stats_arrays_length; i < _region_num; ++i) { |
342 | 122 _surv_rate_pred[i] = new TruncatedSeq(10); |
123 // _surv_rate_pred[i]->add(last_pred); | |
124 } | |
125 | |
545 | 126 _stats_arrays_length = _region_num; |
342 | 127 |
128 if (old_surv_rate != NULL) | |
129 FREE_C_HEAP_ARRAY(double, old_surv_rate); | |
130 if (old_accum_surv_rate_pred != NULL) | |
131 FREE_C_HEAP_ARRAY(double, old_accum_surv_rate_pred); | |
132 if (old_surv_rate_pred != NULL) | |
133 FREE_C_HEAP_ARRAY(NumberSeq*, old_surv_rate_pred); | |
134 } | |
135 | |
545 | 136 for (size_t i = 0; i < _stats_arrays_length; ++i) |
342 | 137 _surv_rate[i] = 0.0; |
138 } | |
139 | |
140 double | |
141 SurvRateGroup::accum_surv_rate(size_t adjustment) { | |
142 // we might relax this one in the future... | |
143 guarantee( adjustment == 0 || adjustment == 1, "pre-condition" ); | |
144 | |
145 double ret = _accum_surv_rate; | |
146 if (adjustment > 0) { | |
545 | 147 TruncatedSeq* seq = get_seq(_region_num+1); |
342 | 148 double surv_rate = _g1p->get_new_prediction(seq); |
149 ret += surv_rate; | |
150 } | |
151 | |
152 return ret; | |
153 } | |
154 | |
155 int | |
156 SurvRateGroup::next_age_index() { | |
545 | 157 TruncatedSeq* seq = get_seq(_region_num); |
342 | 158 double surv_rate = _g1p->get_new_prediction(seq); |
159 _accum_surv_rate += surv_rate; | |
160 | |
545 | 161 ++_region_num; |
342 | 162 return (int) ++_all_regions_allocated; |
163 } | |
164 | |
165 void | |
166 SurvRateGroup::record_surviving_words(int age_in_group, size_t surv_words) { | |
545 | 167 guarantee( 0 <= age_in_group && (size_t) age_in_group < _region_num, |
342 | 168 "pre-condition" ); |
169 guarantee( _surv_rate[age_in_group] <= 0.00001, | |
170 "should only update each slot once" ); | |
171 | |
172 double surv_rate = (double) surv_words / (double) HeapRegion::GrainWords; | |
173 _surv_rate[age_in_group] = surv_rate; | |
174 _surv_rate_pred[age_in_group]->add(surv_rate); | |
175 if ((size_t)age_in_group < _summary_surv_rates_len) { | |
176 _summary_surv_rates[age_in_group]->add(surv_rate); | |
177 if ((size_t)(age_in_group+1) > _summary_surv_rates_max_len) | |
178 _summary_surv_rates_max_len = age_in_group+1; | |
179 } | |
180 } | |
181 | |
182 void | |
183 SurvRateGroup::all_surviving_words_recorded(bool propagate) { | |
545 | 184 if (propagate && _region_num > 0) { // conservative |
185 double surv_rate = _surv_rate_pred[_region_num-1]->last(); | |
342 | 186 |
187 #if 0 | |
188 gclog_or_tty->print_cr("propagating %1.2lf from %d to %d", | |
189 surv_rate, _curr_length, _array_length - 1); | |
190 #endif // 0 | |
191 | |
545 | 192 for (size_t i = _region_num; i < _stats_arrays_length; ++i) { |
342 | 193 guarantee( _surv_rate[i] <= 0.00001, |
194 "the slot should not have been updated" ); | |
195 _surv_rate_pred[i]->add(surv_rate); | |
196 } | |
197 } | |
198 | |
199 double accum = 0.0; | |
200 double pred = 0.0; | |
545 | 201 for (size_t i = 0; i < _stats_arrays_length; ++i) { |
342 | 202 pred = _g1p->get_new_prediction(_surv_rate_pred[i]); |
203 if (pred > 1.0) pred = 1.0; | |
204 accum += pred; | |
205 _accum_surv_rate_pred[i] = accum; | |
206 // gclog_or_tty->print_cr("age %3d, accum %10.2lf", i, accum); | |
207 } | |
208 _last_pred = pred; | |
209 } | |
210 | |
211 #ifndef PRODUCT | |
212 void | |
213 SurvRateGroup::print() { | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
579
diff
changeset
|
214 gclog_or_tty->print_cr("Surv Rate Group: %s (%d entries)", |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
579
diff
changeset
|
215 _name, _region_num); |
545 | 216 for (size_t i = 0; i < _region_num; ++i) { |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
579
diff
changeset
|
217 gclog_or_tty->print_cr(" age %4d surv rate %6.2lf %% pred %6.2lf %%", |
342 | 218 i, _surv_rate[i] * 100.0, |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
579
diff
changeset
|
219 _g1p->get_new_prediction(_surv_rate_pred[i]) * 100.0); |
342 | 220 } |
221 } | |
222 | |
223 void | |
224 SurvRateGroup::print_surv_rate_summary() { | |
225 size_t length = _summary_surv_rates_max_len; | |
226 if (length == 0) | |
227 return; | |
228 | |
229 gclog_or_tty->print_cr(""); | |
230 gclog_or_tty->print_cr("%s Rate Summary (for up to age %d)", _name, length-1); | |
231 gclog_or_tty->print_cr(" age range survival rate (avg) samples (avg)"); | |
232 gclog_or_tty->print_cr(" ---------------------------------------------------------"); | |
233 | |
234 size_t index = 0; | |
235 size_t limit = MIN2((int) length, 10); | |
236 while (index < limit) { | |
237 gclog_or_tty->print_cr(" %4d %6.2lf%% %6.2lf", | |
238 index, _summary_surv_rates[index]->avg() * 100.0, | |
239 (double) _summary_surv_rates[index]->num()); | |
240 ++index; | |
241 } | |
242 | |
243 gclog_or_tty->print_cr(" ---------------------------------------------------------"); | |
244 | |
245 int num = 0; | |
246 double sum = 0.0; | |
247 int samples = 0; | |
248 while (index < length) { | |
249 ++num; | |
250 sum += _summary_surv_rates[index]->avg() * 100.0; | |
251 samples += _summary_surv_rates[index]->num(); | |
252 ++index; | |
253 | |
254 if (index == length || num % 10 == 0) { | |
255 gclog_or_tty->print_cr(" %4d .. %4d %6.2lf%% %6.2lf", | |
256 (index-1) / 10 * 10, index-1, sum / (double) num, | |
257 (double) samples / (double) num); | |
258 sum = 0.0; | |
259 num = 0; | |
260 samples = 0; | |
261 } | |
262 } | |
263 | |
264 gclog_or_tty->print_cr(" ---------------------------------------------------------"); | |
265 } | |
266 #endif // PRODUCT |