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

changeset 3119
4f41766176cf
parent 3114
20213c8a3c40
child 3120
af2ab04e0038
     1.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Wed Sep 07 18:58:33 2011 -0700
     1.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Thu Sep 08 05:16:49 2011 -0400
     1.3 @@ -414,7 +414,7 @@
     1.4    _concurrent_mark_cleanup_times_ms->add(0.20);
     1.5    _tenuring_threshold = MaxTenuringThreshold;
     1.6    // _max_survivor_regions will be calculated by
     1.7 -  // calculate_young_list_target_length() during initialization.
     1.8 +  // update_young_list_target_length() during initialization.
     1.9    _max_survivor_regions = 0;
    1.10  
    1.11    assert(GCTimeRatio > 0,
    1.12 @@ -422,6 +422,18 @@
    1.13           "if a user set it to 0");
    1.14    _gc_overhead_perc = 100.0 * (1.0 / (1.0 + GCTimeRatio));
    1.15  
    1.16 +  uintx reserve_perc = G1ReservePercent;
    1.17 +  // Put an artificial ceiling on this so that it's not set to a silly value.
    1.18 +  if (reserve_perc > 50) {
    1.19 +    reserve_perc = 50;
    1.20 +    warning("G1ReservePercent is set to a value that is too large, "
    1.21 +            "it's been updated to %u", reserve_perc);
    1.22 +  }
    1.23 +  _reserve_factor = (double) reserve_perc / 100.0;
    1.24 +  // This will be set in calculate_reserve() when the heap is expanded
    1.25 +  // for the first time during initialization.
    1.26 +  _reserve_regions = 0;
    1.27 +
    1.28    initialize_all();
    1.29  }
    1.30  
    1.31 @@ -486,9 +498,7 @@
    1.32      _young_list_fixed_length = initial_region_num;
    1.33    }
    1.34    _free_regions_at_end_of_collection = _g1->free_regions();
    1.35 -  calculate_young_list_min_length();
    1.36 -  guarantee( _young_list_min_length == 0, "invariant, not enough info" );
    1.37 -  calculate_young_list_target_length();
    1.38 +  update_young_list_target_length();
    1.39  
    1.40    // We may immediately start allocating regions and placing them on the
    1.41    // collection set list. Initialize the per-collection set info
    1.42 @@ -496,236 +506,252 @@
    1.43  }
    1.44  
    1.45  // Create the jstat counters for the policy.
    1.46 -void G1CollectorPolicy::initialize_gc_policy_counters()
    1.47 -{
    1.48 +void G1CollectorPolicy::initialize_gc_policy_counters() {
    1.49    _gc_policy_counters = new GCPolicyCounters("GarbageFirst", 1, 3);
    1.50  }
    1.51  
    1.52 -void G1CollectorPolicy::calculate_young_list_min_length() {
    1.53 -  _young_list_min_length = 0;
    1.54 -
    1.55 -  if (!adaptive_young_list_length())
    1.56 -    return;
    1.57 -
    1.58 -  if (_alloc_rate_ms_seq->num() > 3) {
    1.59 -    double now_sec = os::elapsedTime();
    1.60 -    double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0;
    1.61 -    double alloc_rate_ms = predict_alloc_rate_ms();
    1.62 -    size_t min_regions = (size_t) ceil(alloc_rate_ms * when_ms);
    1.63 -    size_t current_region_num = _g1->young_list()->length();
    1.64 -    _young_list_min_length = min_regions + current_region_num;
    1.65 +bool G1CollectorPolicy::predict_will_fit(size_t young_length,
    1.66 +                                         double base_time_ms,
    1.67 +                                         size_t base_free_regions,
    1.68 +                                         double target_pause_time_ms) {
    1.69 +  if (young_length >= base_free_regions) {
    1.70 +    // end condition 1: not enough space for the young regions
    1.71 +    return false;
    1.72    }
    1.73 +
    1.74 +  double accum_surv_rate = accum_yg_surv_rate_pred((int)(young_length - 1));
    1.75 +  size_t bytes_to_copy =
    1.76 +               (size_t) (accum_surv_rate * (double) HeapRegion::GrainBytes);
    1.77 +  double copy_time_ms = predict_object_copy_time_ms(bytes_to_copy);
    1.78 +  double young_other_time_ms = predict_young_other_time_ms(young_length);
    1.79 +  double pause_time_ms = base_time_ms + copy_time_ms + young_other_time_ms;
    1.80 +  if (pause_time_ms > target_pause_time_ms) {
    1.81 +    // end condition 2: prediction is over the target pause time
    1.82 +    return false;
    1.83 +  }
    1.84 +
    1.85 +  size_t free_bytes =
    1.86 +                  (base_free_regions - young_length) * HeapRegion::GrainBytes;
    1.87 +  if ((2.0 * sigma()) * (double) bytes_to_copy > (double) free_bytes) {
    1.88 +    // end condition 3: out-of-space (conservatively!)
    1.89 +    return false;
    1.90 +  }
    1.91 +
    1.92 +  // success!
    1.93 +  return true;
    1.94  }
    1.95  
    1.96 -void G1CollectorPolicy::calculate_young_list_target_length() {
    1.97 +void G1CollectorPolicy::calculate_reserve(size_t all_regions) {
    1.98 +  double reserve_regions_d = (double) all_regions * _reserve_factor;
    1.99 +  // We use ceiling so that if reserve_regions_d is > 0.0 (but
   1.100 +  // smaller than 1.0) we'll get 1.
   1.101 +  _reserve_regions = (size_t) ceil(reserve_regions_d);
   1.102 +}
   1.103 +
   1.104 +size_t G1CollectorPolicy::calculate_young_list_desired_min_length(
   1.105 +                                                     size_t base_min_length) {
   1.106 +  size_t desired_min_length = 0;
   1.107    if (adaptive_young_list_length()) {
   1.108 -    size_t rs_lengths = (size_t) get_new_prediction(_rs_lengths_seq);
   1.109 -    calculate_young_list_target_length(rs_lengths);
   1.110 -  } else {
   1.111 -    if (full_young_gcs())
   1.112 -      _young_list_target_length = _young_list_fixed_length;
   1.113 -    else
   1.114 -      _young_list_target_length = _young_list_fixed_length / 2;
   1.115 +    if (_alloc_rate_ms_seq->num() > 3) {
   1.116 +      double now_sec = os::elapsedTime();
   1.117 +      double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0;
   1.118 +      double alloc_rate_ms = predict_alloc_rate_ms();
   1.119 +      desired_min_length = (size_t) ceil(alloc_rate_ms * when_ms);
   1.120 +    } else {
   1.121 +      // otherwise we don't have enough info to make the prediction
   1.122 +    }
   1.123    }
   1.124 -
   1.125 -  // Make sure we allow the application to allocate at least one
   1.126 -  // region before we need to do a collection again.
   1.127 -  size_t min_length = _g1->young_list()->length() + 1;
   1.128 -  _young_list_target_length = MAX2(_young_list_target_length, min_length);
   1.129 -  calculate_max_gc_locker_expansion();
   1.130 -  calculate_survivors_policy();
   1.131 +  // Here, we might want to also take into account any additional
   1.132 +  // constraints (i.e., user-defined minimum bound). Currently, we don't.
   1.133 +  return base_min_length + desired_min_length;
   1.134  }
   1.135  
   1.136 -void G1CollectorPolicy::calculate_young_list_target_length(size_t rs_lengths) {
   1.137 -  guarantee( adaptive_young_list_length(), "pre-condition" );
   1.138 -  guarantee( !_in_marking_window || !_last_full_young_gc, "invariant" );
   1.139 -
   1.140 -  double start_time_sec = os::elapsedTime();
   1.141 -  size_t min_reserve_perc = MAX2((size_t)2, (size_t)G1ReservePercent);
   1.142 -  min_reserve_perc = MIN2((size_t) 50, min_reserve_perc);
   1.143 -  size_t reserve_regions =
   1.144 -    (size_t) ((double) min_reserve_perc * (double) _g1->n_regions() / 100.0);
   1.145 -
   1.146 -  if (full_young_gcs() && _free_regions_at_end_of_collection > 0) {
   1.147 -    // we are in fully-young mode and there are free regions in the heap
   1.148 -
   1.149 -    double survivor_regions_evac_time =
   1.150 -        predict_survivor_regions_evac_time();
   1.151 -
   1.152 -    double target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0;
   1.153 -    size_t pending_cards = (size_t) get_new_prediction(_pending_cards_seq);
   1.154 -    size_t adj_rs_lengths = rs_lengths + predict_rs_length_diff();
   1.155 -    size_t scanned_cards = predict_young_card_num(adj_rs_lengths);
   1.156 -    double base_time_ms = predict_base_elapsed_time_ms(pending_cards, scanned_cards)
   1.157 -                          + survivor_regions_evac_time;
   1.158 -
   1.159 -    // the result
   1.160 -    size_t final_young_length = 0;
   1.161 -
   1.162 -    size_t init_free_regions =
   1.163 -      MAX2((size_t)0, _free_regions_at_end_of_collection - reserve_regions);
   1.164 -
   1.165 -    // if we're still under the pause target...
   1.166 -    if (base_time_ms <= target_pause_time_ms) {
   1.167 -      // We make sure that the shortest young length that makes sense
   1.168 -      // fits within the target pause time.
   1.169 -      size_t min_young_length = 1;
   1.170 -
   1.171 -      if (predict_will_fit(min_young_length, base_time_ms,
   1.172 -                                     init_free_regions, target_pause_time_ms)) {
   1.173 -        // The shortest young length will fit within the target pause time;
   1.174 -        // we'll now check whether the absolute maximum number of young
   1.175 -        // regions will fit in the target pause time. If not, we'll do
   1.176 -        // a binary search between min_young_length and max_young_length
   1.177 -        size_t abs_max_young_length = _free_regions_at_end_of_collection - 1;
   1.178 -        size_t max_young_length = abs_max_young_length;
   1.179 -
   1.180 -        if (max_young_length > min_young_length) {
   1.181 -          // Let's check if the initial max young length will fit within the
   1.182 -          // target pause. If so then there is no need to search for a maximal
   1.183 -          // young length - we'll return the initial maximum
   1.184 -
   1.185 -          if (predict_will_fit(max_young_length, base_time_ms,
   1.186 -                                init_free_regions, target_pause_time_ms)) {
   1.187 -            // The maximum young length will satisfy the target pause time.
   1.188 -            // We are done so set min young length to this maximum length.
   1.189 -            // The code after the loop will then set final_young_length using
   1.190 -            // the value cached in the minimum length.
   1.191 -            min_young_length = max_young_length;
   1.192 -          } else {
   1.193 -            // The maximum possible number of young regions will not fit within
   1.194 -            // the target pause time so let's search....
   1.195 -
   1.196 -            size_t diff = (max_young_length - min_young_length) / 2;
   1.197 -            max_young_length = min_young_length + diff;
   1.198 -
   1.199 -            while (max_young_length > min_young_length) {
   1.200 -              if (predict_will_fit(max_young_length, base_time_ms,
   1.201 -                                        init_free_regions, target_pause_time_ms)) {
   1.202 -
   1.203 -                // The current max young length will fit within the target
   1.204 -                // pause time. Note we do not exit the loop here. By setting
   1.205 -                // min = max, and then increasing the max below means that
   1.206 -                // we will continue searching for an upper bound in the
   1.207 -                // range [max..max+diff]
   1.208 -                min_young_length = max_young_length;
   1.209 -              }
   1.210 -              diff = (max_young_length - min_young_length) / 2;
   1.211 -              max_young_length = min_young_length + diff;
   1.212 -            }
   1.213 -            // the above loop found a maximal young length that will fit
   1.214 -            // within the target pause time.
   1.215 -          }
   1.216 -          assert(min_young_length <= abs_max_young_length, "just checking");
   1.217 -        }
   1.218 -        final_young_length = min_young_length;
   1.219 -      }
   1.220 -    }
   1.221 -    // and we're done!
   1.222 -
   1.223 -    // we should have at least one region in the target young length
   1.224 -    _young_list_target_length =
   1.225 -                              final_young_length + _recorded_survivor_regions;
   1.226 -
   1.227 -    // let's keep an eye of how long we spend on this calculation
   1.228 -    // right now, I assume that we'll print it when we need it; we
   1.229 -    // should really adde it to the breakdown of a pause
   1.230 -    double end_time_sec = os::elapsedTime();
   1.231 -    double elapsed_time_ms = (end_time_sec - start_time_sec) * 1000.0;
   1.232 -
   1.233 -#ifdef TRACE_CALC_YOUNG_LENGTH
   1.234 -    // leave this in for debugging, just in case
   1.235 -    gclog_or_tty->print_cr("target = %1.1lf ms, young = " SIZE_FORMAT ", "
   1.236 -                           "elapsed %1.2lf ms, (%s%s) " SIZE_FORMAT SIZE_FORMAT,
   1.237 -                           target_pause_time_ms,
   1.238 -                           _young_list_target_length
   1.239 -                           elapsed_time_ms,
   1.240 -                           full_young_gcs() ? "full" : "partial",
   1.241 -                           during_initial_mark_pause() ? " i-m" : "",
   1.242 -                           _in_marking_window,
   1.243 -                           _in_marking_window_im);
   1.244 -#endif // TRACE_CALC_YOUNG_LENGTH
   1.245 -
   1.246 -    if (_young_list_target_length < _young_list_min_length) {
   1.247 -      // bummer; this means that, if we do a pause when the maximal
   1.248 -      // length dictates, we'll violate the pause spacing target (the
   1.249 -      // min length was calculate based on the application's current
   1.250 -      // alloc rate);
   1.251 -
   1.252 -      // so, we have to bite the bullet, and allocate the minimum
   1.253 -      // number. We'll violate our target, but we just can't meet it.
   1.254 -
   1.255 -#ifdef TRACE_CALC_YOUNG_LENGTH
   1.256 -      // leave this in for debugging, just in case
   1.257 -      gclog_or_tty->print_cr("adjusted target length from "
   1.258 -                             SIZE_FORMAT " to " SIZE_FORMAT,
   1.259 -                             _young_list_target_length, _young_list_min_length);
   1.260 -#endif // TRACE_CALC_YOUNG_LENGTH
   1.261 -
   1.262 -      _young_list_target_length = _young_list_min_length;
   1.263 +size_t G1CollectorPolicy::calculate_young_list_desired_max_length() {
   1.264 +  // Here, we might want to also take into account any additional
   1.265 +  // constraints (i.e., user-defined minimum bound). Currently, we
   1.266 +  // effectively don't set this bound.
   1.267 +  return _g1->n_regions();
   1.268 +}
   1.269 +
   1.270 +void G1CollectorPolicy::update_young_list_target_length(size_t rs_lengths) {
   1.271 +  if (rs_lengths == (size_t) -1) {
   1.272 +    // if it's set to the default value (-1), we should predict it;
   1.273 +    // otherwise, use the given value.
   1.274 +    rs_lengths = (size_t) get_new_prediction(_rs_lengths_seq);
   1.275 +  }
   1.276 +
   1.277 +  // Calculate the absolute and desired min bounds.
   1.278 +
   1.279 +  // This is how many young regions we already have (currently: the survivors).
   1.280 +  size_t base_min_length = recorded_survivor_regions();
   1.281 +  // This is the absolute minimum young length, which ensures that we
   1.282 +  // can allocate one eden region in the worst-case.
   1.283 +  size_t absolute_min_length = base_min_length + 1;
   1.284 +  size_t desired_min_length =
   1.285 +                     calculate_young_list_desired_min_length(base_min_length);
   1.286 +  if (desired_min_length < absolute_min_length) {
   1.287 +    desired_min_length = absolute_min_length;
   1.288 +  }
   1.289 +
   1.290 +  // Calculate the absolute and desired max bounds.
   1.291 +
   1.292 +  // We will try our best not to "eat" into the reserve.
   1.293 +  size_t absolute_max_length = 0;
   1.294 +  if (_free_regions_at_end_of_collection > _reserve_regions) {
   1.295 +    absolute_max_length = _free_regions_at_end_of_collection - _reserve_regions;
   1.296 +  }
   1.297 +  size_t desired_max_length = calculate_young_list_desired_max_length();
   1.298 +  if (desired_max_length > absolute_max_length) {
   1.299 +    desired_max_length = absolute_max_length;
   1.300 +  }
   1.301 +
   1.302 +  size_t young_list_target_length = 0;
   1.303 +  if (adaptive_young_list_length()) {
   1.304 +    if (full_young_gcs()) {
   1.305 +      young_list_target_length =
   1.306 +                        calculate_young_list_target_length(rs_lengths,
   1.307 +                                                           base_min_length,
   1.308 +                                                           desired_min_length,
   1.309 +                                                           desired_max_length);
   1.310 +      _rs_lengths_prediction = rs_lengths;
   1.311 +    } else {
   1.312 +      // Don't calculate anything and let the code below bound it to
   1.313 +      // the desired_min_length, i.e., do the next GC as soon as
   1.314 +      // possible to maximize how many old regions we can add to it.
   1.315      }
   1.316    } else {
   1.317 -    // we are in a partially-young mode or we've run out of regions (due
   1.318 -    // to evacuation failure)
   1.319 -
   1.320 -#ifdef TRACE_CALC_YOUNG_LENGTH
   1.321 -    // leave this in for debugging, just in case
   1.322 -    gclog_or_tty->print_cr("(partial) setting target to " SIZE_FORMAT
   1.323 -                           _young_list_min_length);
   1.324 -#endif // TRACE_CALC_YOUNG_LENGTH
   1.325 -    // we'll do the pause as soon as possible by choosing the minimum
   1.326 -    _young_list_target_length = _young_list_min_length;
   1.327 +    if (full_young_gcs()) {
   1.328 +      young_list_target_length = _young_list_fixed_length;
   1.329 +    } else {
   1.330 +      // A bit arbitrary: during partially-young GCs we allocate half
   1.331 +      // the young regions to try to add old regions to the CSet.
   1.332 +      young_list_target_length = _young_list_fixed_length / 2;
   1.333 +      // We choose to accept that we might go under the desired min
   1.334 +      // length given that we intentionally ask for a smaller young gen.
   1.335 +      desired_min_length = absolute_min_length;
   1.336 +    }
   1.337    }
   1.338  
   1.339 -  _rs_lengths_prediction = rs_lengths;
   1.340 +  // Make sure we don't go over the desired max length, nor under the
   1.341 +  // desired min length. In case they clash, desired_min_length wins
   1.342 +  // which is why that test is second.
   1.343 +  if (young_list_target_length > desired_max_length) {
   1.344 +    young_list_target_length = desired_max_length;
   1.345 +  }
   1.346 +  if (young_list_target_length < desired_min_length) {
   1.347 +    young_list_target_length = desired_min_length;
   1.348 +  }
   1.349 +
   1.350 +  assert(young_list_target_length > recorded_survivor_regions(),
   1.351 +         "we should be able to allocate at least one eden region");
   1.352 +  assert(young_list_target_length >= absolute_min_length, "post-condition");
   1.353 +  _young_list_target_length = young_list_target_length;
   1.354 +
   1.355 +  update_max_gc_locker_expansion();
   1.356  }
   1.357  
   1.358 -// This is used by: calculate_young_list_target_length(rs_length). It
   1.359 -// returns true iff:
   1.360 -//   the predicted pause time for the given young list will not overflow
   1.361 -//   the target pause time
   1.362 -// and:
   1.363 -//   the predicted amount of surviving data will not overflow the
   1.364 -//   the amount of free space available for survivor regions.
   1.365 -//
   1.366 -bool
   1.367 -G1CollectorPolicy::predict_will_fit(size_t young_length,
   1.368 -                                    double base_time_ms,
   1.369 -                                    size_t init_free_regions,
   1.370 -                                    double target_pause_time_ms) {
   1.371 -
   1.372 -  if (young_length >= init_free_regions)
   1.373 -    // end condition 1: not enough space for the young regions
   1.374 -    return false;
   1.375 -
   1.376 -  double accum_surv_rate_adj = 0.0;
   1.377 -  double accum_surv_rate =
   1.378 -    accum_yg_surv_rate_pred((int)(young_length - 1)) - accum_surv_rate_adj;
   1.379 -
   1.380 -  size_t bytes_to_copy =
   1.381 -    (size_t) (accum_surv_rate * (double) HeapRegion::GrainBytes);
   1.382 -
   1.383 -  double copy_time_ms = predict_object_copy_time_ms(bytes_to_copy);
   1.384 -
   1.385 -  double young_other_time_ms =
   1.386 -                       predict_young_other_time_ms(young_length);
   1.387 -
   1.388 -  double pause_time_ms =
   1.389 -                   base_time_ms + copy_time_ms + young_other_time_ms;
   1.390 -
   1.391 -  if (pause_time_ms > target_pause_time_ms)
   1.392 -    // end condition 2: over the target pause time
   1.393 -    return false;
   1.394 -
   1.395 -  size_t free_bytes =
   1.396 -                 (init_free_regions - young_length) * HeapRegion::GrainBytes;
   1.397 -
   1.398 -  if ((2.0 + sigma()) * (double) bytes_to_copy > (double) free_bytes)
   1.399 -    // end condition 3: out of to-space (conservatively)
   1.400 -    return false;
   1.401 -
   1.402 -  // success!
   1.403 -  return true;
   1.404 +size_t
   1.405 +G1CollectorPolicy::calculate_young_list_target_length(size_t rs_lengths,
   1.406 +                                                   size_t base_min_length,
   1.407 +                                                   size_t desired_min_length,
   1.408 +                                                   size_t desired_max_length) {
   1.409 +  assert(adaptive_young_list_length(), "pre-condition");
   1.410 +  assert(full_young_gcs(), "only call this for fully-young GCs");
   1.411 +
   1.412 +  // In case some edge-condition makes the desired max length too small...
   1.413 +  if (desired_max_length <= desired_min_length) {
   1.414 +    return desired_min_length;
   1.415 +  }
   1.416 +
   1.417 +  // We'll adjust min_young_length and max_young_length not to include
   1.418 +  // the already allocated young regions (i.e., so they reflect the
   1.419 +  // min and max eden regions we'll allocate). The base_min_length
   1.420 +  // will be reflected in the predictions by the
   1.421 +  // survivor_regions_evac_time prediction.
   1.422 +  assert(desired_min_length > base_min_length, "invariant");
   1.423 +  size_t min_young_length = desired_min_length - base_min_length;
   1.424 +  assert(desired_max_length > base_min_length, "invariant");
   1.425 +  size_t max_young_length = desired_max_length - base_min_length;
   1.426 +
   1.427 +  double target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0;
   1.428 +  double survivor_regions_evac_time = predict_survivor_regions_evac_time();
   1.429 +  size_t pending_cards = (size_t) get_new_prediction(_pending_cards_seq);
   1.430 +  size_t adj_rs_lengths = rs_lengths + predict_rs_length_diff();
   1.431 +  size_t scanned_cards = predict_young_card_num(adj_rs_lengths);
   1.432 +  double base_time_ms =
   1.433 +    predict_base_elapsed_time_ms(pending_cards, scanned_cards) +
   1.434 +    survivor_regions_evac_time;
   1.435 +  size_t available_free_regions = _free_regions_at_end_of_collection;
   1.436 +  size_t base_free_regions = 0;
   1.437 +  if (available_free_regions > _reserve_regions) {
   1.438 +    base_free_regions = available_free_regions - _reserve_regions;
   1.439 +  }
   1.440 +
   1.441 +  // Here, we will make sure that the shortest young length that
   1.442 +  // makes sense fits within the target pause time.
   1.443 +
   1.444 +  if (predict_will_fit(min_young_length, base_time_ms,
   1.445 +                       base_free_regions, target_pause_time_ms)) {
   1.446 +    // The shortest young length will fit into the target pause time;
   1.447 +    // we'll now check whether the absolute maximum number of young
   1.448 +    // regions will fit in the target pause time. If not, we'll do
   1.449 +    // a binary search between min_young_length and max_young_length.
   1.450 +    if (predict_will_fit(max_young_length, base_time_ms,
   1.451 +                         base_free_regions, target_pause_time_ms)) {
   1.452 +      // The maximum young length will fit into the target pause time.
   1.453 +      // We are done so set min young length to the maximum length (as
   1.454 +      // the result is assumed to be returned in min_young_length).
   1.455 +      min_young_length = max_young_length;
   1.456 +    } else {
   1.457 +      // The maximum possible number of young regions will not fit within
   1.458 +      // the target pause time so we'll search for the optimal
   1.459 +      // length. The loop invariants are:
   1.460 +      //
   1.461 +      // min_young_length < max_young_length
   1.462 +      // min_young_length is known to fit into the target pause time
   1.463 +      // max_young_length is known not to fit into the target pause time
   1.464 +      //
   1.465 +      // Going into the loop we know the above hold as we've just
   1.466 +      // checked them. Every time around the loop we check whether
   1.467 +      // the middle value between min_young_length and
   1.468 +      // max_young_length fits into the target pause time. If it
   1.469 +      // does, it becomes the new min. If it doesn't, it becomes
   1.470 +      // the new max. This way we maintain the loop invariants.
   1.471 +
   1.472 +      assert(min_young_length < max_young_length, "invariant");
   1.473 +      size_t diff = (max_young_length - min_young_length) / 2;
   1.474 +      while (diff > 0) {
   1.475 +        size_t young_length = min_young_length + diff;
   1.476 +        if (predict_will_fit(young_length, base_time_ms,
   1.477 +                             base_free_regions, target_pause_time_ms)) {
   1.478 +          min_young_length = young_length;
   1.479 +        } else {
   1.480 +          max_young_length = young_length;
   1.481 +        }
   1.482 +        assert(min_young_length <  max_young_length, "invariant");
   1.483 +        diff = (max_young_length - min_young_length) / 2;
   1.484 +      }
   1.485 +      // The results is min_young_length which, according to the
   1.486 +      // loop invariants, should fit within the target pause time.
   1.487 +
   1.488 +      // These are the post-conditions of the binary search above:
   1.489 +      assert(min_young_length < max_young_length,
   1.490 +             "otherwise we should have discovered that max_young_length "
   1.491 +             "fits into the pause target and not done the binary search");
   1.492 +      assert(predict_will_fit(min_young_length, base_time_ms,
   1.493 +                              base_free_regions, target_pause_time_ms),
   1.494 +             "min_young_length, the result of the binary search, should "
   1.495 +             "fit into the pause target");
   1.496 +      assert(!predict_will_fit(min_young_length + 1, base_time_ms,
   1.497 +                               base_free_regions, target_pause_time_ms),
   1.498 +             "min_young_length, the result of the binary search, should be "
   1.499 +             "optimal, so no larger length should fit into the pause target");
   1.500 +    }
   1.501 +  } else {
   1.502 +    // Even the minimum length doesn't fit into the pause time
   1.503 +    // target, return it as the result nevertheless.
   1.504 +  }
   1.505 +  return base_min_length + min_young_length;
   1.506  }
   1.507  
   1.508  double G1CollectorPolicy::predict_survivor_regions_evac_time() {
   1.509 @@ -738,17 +764,19 @@
   1.510    return survivor_regions_evac_time;
   1.511  }
   1.512  
   1.513 -void G1CollectorPolicy::check_prediction_validity() {
   1.514 +void G1CollectorPolicy::revise_young_list_target_length_if_necessary() {
   1.515    guarantee( adaptive_young_list_length(), "should not call this otherwise" );
   1.516  
   1.517    size_t rs_lengths = _g1->young_list()->sampled_rs_lengths();
   1.518    if (rs_lengths > _rs_lengths_prediction) {
   1.519      // add 10% to avoid having to recalculate often
   1.520      size_t rs_lengths_prediction = rs_lengths * 1100 / 1000;
   1.521 -    calculate_young_list_target_length(rs_lengths_prediction);
   1.522 +    update_young_list_target_length(rs_lengths_prediction);
   1.523    }
   1.524  }
   1.525  
   1.526 +
   1.527 +
   1.528  HeapWord* G1CollectorPolicy::mem_allocate_work(size_t size,
   1.529                                                 bool is_tlab,
   1.530                                                 bool* gc_overhead_limit_was_exceeded) {
   1.531 @@ -855,8 +883,7 @@
   1.532    _free_regions_at_end_of_collection = _g1->free_regions();
   1.533    // Reset survivors SurvRateGroup.
   1.534    _survivor_surv_rate_group->reset();
   1.535 -  calculate_young_list_min_length();
   1.536 -  calculate_young_list_target_length();
   1.537 +  update_young_list_target_length();
   1.538  }
   1.539  
   1.540  void G1CollectorPolicy::record_stop_world_start() {
   1.541 @@ -871,6 +898,11 @@
   1.542      gclog_or_tty->print(" (%s)", full_young_gcs() ? "young" : "partial");
   1.543    }
   1.544  
   1.545 +  // We only need to do this here as the policy will only be applied
   1.546 +  // to the GC we're about to start. so, no point is calculating this
   1.547 +  // every time we calculate / recalculate the target young length.
   1.548 +  update_survivors_policy();
   1.549 +
   1.550    assert(_g1->used() == _g1->recalculate_used(),
   1.551           err_msg("sanity, used: "SIZE_FORMAT" recalculate_used: "SIZE_FORMAT,
   1.552                   _g1->used(), _g1->recalculate_used()));
   1.553 @@ -996,8 +1028,6 @@
   1.554    _should_revert_to_full_young_gcs = false;
   1.555    _last_full_young_gc = true;
   1.556    _in_marking_window = false;
   1.557 -  if (adaptive_young_list_length())
   1.558 -    calculate_young_list_target_length();
   1.559  }
   1.560  
   1.561  void G1CollectorPolicy::record_concurrent_pause() {
   1.562 @@ -1648,8 +1678,7 @@
   1.563    _in_marking_window = new_in_marking_window;
   1.564    _in_marking_window_im = new_in_marking_window_im;
   1.565    _free_regions_at_end_of_collection = _g1->free_regions();
   1.566 -  calculate_young_list_min_length();
   1.567 -  calculate_young_list_target_length();
   1.568 +  update_young_list_target_length();
   1.569  
   1.570    // Note that _mmu_tracker->max_gc_time() returns the time in seconds.
   1.571    double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0;
   1.572 @@ -2324,7 +2353,7 @@
   1.573    };
   1.574  }
   1.575  
   1.576 -void G1CollectorPolicy::calculate_max_gc_locker_expansion() {
   1.577 +void G1CollectorPolicy::update_max_gc_locker_expansion() {
   1.578    size_t expansion_region_num = 0;
   1.579    if (GCLockerEdenExpansionPercent > 0) {
   1.580      double perc = (double) GCLockerEdenExpansionPercent / 100.0;
   1.581 @@ -2340,9 +2369,13 @@
   1.582  }
   1.583  
   1.584  // Calculates survivor space parameters.
   1.585 -void G1CollectorPolicy::calculate_survivors_policy()
   1.586 -{
   1.587 -  _max_survivor_regions = _young_list_target_length / SurvivorRatio;
   1.588 +void G1CollectorPolicy::update_survivors_policy() {
   1.589 +  double max_survivor_regions_d =
   1.590 +                 (double) _young_list_target_length / (double) SurvivorRatio;
   1.591 +  // We use ceiling so that if max_survivor_regions_d is > 0.0 (but
   1.592 +  // smaller than 1.0) we'll get 1.
   1.593 +  _max_survivor_regions = (size_t) ceil(max_survivor_regions_d);
   1.594 +
   1.595    _tenuring_threshold = _survivors_age_table.compute_tenuring_threshold(
   1.596          HeapRegion::GrainWords * _max_survivor_regions);
   1.597  }

mercurial