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

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

mercurial