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

Fri, 10 Oct 2014 15:51:58 +0200

author
tschatzl
date
Fri, 10 Oct 2014 15:51:58 +0200
changeset 7257
e7d0505c8a30
parent 6680
78bbf4d43a14
child 6876
710a3c8b516e
permissions
-rw-r--r--

8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso

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

mercurial