Mon, 02 Aug 2010 12:51:43 -0700
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
1 /*
2 * Copyright (c) 2001, 2010, 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 */
25 #include "incls/_precompiled.incl"
26 #include "incls/_survRateGroup.cpp.incl"
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),
34 _summary_surv_rates(NULL),
35 _surv_rate(NULL),
36 _accum_surv_rate_pred(NULL),
37 _surv_rate_pred(NULL)
38 {
39 reset();
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 }
51 start_adding_regions();
52 }
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 }
73 void
74 SurvRateGroup::start_adding_regions() {
75 _setup_seq_num = _stats_arrays_length;
76 _region_num = 0;
77 _accum_surv_rate = 0.0;
79 #if 0
80 gclog_or_tty->print_cr("[%s] start adding regions, seq num %d, length %d",
81 _name, _setup_seq_num, _region_num);
82 #endif // 0
83 }
85 void
86 SurvRateGroup::stop_adding_regions() {
88 #if 0
89 gclog_or_tty->print_cr("[%s] stop adding regions, length %d", _name, _region_num);
90 #endif // 0
92 if (_region_num > _stats_arrays_length) {
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;
97 _surv_rate = NEW_C_HEAP_ARRAY(double, _region_num);
98 if (_surv_rate == NULL) {
99 vm_exit_out_of_memory(sizeof(double) * _region_num,
100 "Not enough space for surv rate array.");
101 }
102 _accum_surv_rate_pred = NEW_C_HEAP_ARRAY(double, _region_num);
103 if (_accum_surv_rate_pred == NULL) {
104 vm_exit_out_of_memory(sizeof(double) * _region_num,
105 "Not enough space for accum surv rate pred array.");
106 }
107 _surv_rate_pred = NEW_C_HEAP_ARRAY(TruncatedSeq*, _region_num);
108 if (_surv_rate == NULL) {
109 vm_exit_out_of_memory(sizeof(TruncatedSeq*) * _region_num,
110 "Not enough space for surv rate pred array.");
111 }
113 for (size_t i = 0; i < _stats_arrays_length; ++i)
114 _surv_rate_pred[i] = old_surv_rate_pred[i];
116 #if 0
117 gclog_or_tty->print_cr("[%s] stop adding regions, new seqs %d to %d",
118 _name, _array_length, _region_num - 1);
119 #endif // 0
121 for (size_t i = _stats_arrays_length; i < _region_num; ++i) {
122 _surv_rate_pred[i] = new TruncatedSeq(10);
123 // _surv_rate_pred[i]->add(last_pred);
124 }
126 _stats_arrays_length = _region_num;
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 }
136 for (size_t i = 0; i < _stats_arrays_length; ++i)
137 _surv_rate[i] = 0.0;
138 }
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" );
145 double ret = _accum_surv_rate;
146 if (adjustment > 0) {
147 TruncatedSeq* seq = get_seq(_region_num+1);
148 double surv_rate = _g1p->get_new_prediction(seq);
149 ret += surv_rate;
150 }
152 return ret;
153 }
155 int
156 SurvRateGroup::next_age_index() {
157 TruncatedSeq* seq = get_seq(_region_num);
158 double surv_rate = _g1p->get_new_prediction(seq);
159 _accum_surv_rate += surv_rate;
161 ++_region_num;
162 return (int) ++_all_regions_allocated;
163 }
165 void
166 SurvRateGroup::record_surviving_words(int age_in_group, size_t surv_words) {
167 guarantee( 0 <= age_in_group && (size_t) age_in_group < _region_num,
168 "pre-condition" );
169 guarantee( _surv_rate[age_in_group] <= 0.00001,
170 "should only update each slot once" );
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 }
182 void
183 SurvRateGroup::all_surviving_words_recorded(bool propagate) {
184 if (propagate && _region_num > 0) { // conservative
185 double surv_rate = _surv_rate_pred[_region_num-1]->last();
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
192 for (size_t i = _region_num; i < _stats_arrays_length; ++i) {
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 }
199 double accum = 0.0;
200 double pred = 0.0;
201 for (size_t i = 0; i < _stats_arrays_length; ++i) {
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 }
211 #ifndef PRODUCT
212 void
213 SurvRateGroup::print() {
214 gclog_or_tty->print_cr("Surv Rate Group: %s (%d entries)",
215 _name, _region_num);
216 for (size_t i = 0; i < _region_num; ++i) {
217 gclog_or_tty->print_cr(" age %4d surv rate %6.2lf %% pred %6.2lf %%",
218 i, _surv_rate[i] * 100.0,
219 _g1p->get_new_prediction(_surv_rate_pred[i]) * 100.0);
220 }
221 }
223 void
224 SurvRateGroup::print_surv_rate_summary() {
225 size_t length = _summary_surv_rates_max_len;
226 if (length == 0)
227 return;
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(" ---------------------------------------------------------");
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 }
243 gclog_or_tty->print_cr(" ---------------------------------------------------------");
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;
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 }
264 gclog_or_tty->print_cr(" ---------------------------------------------------------");
265 }
266 #endif // PRODUCT