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

     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

mercurial