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

changeset 3539
a9647476d1a4
parent 3464
eff609af17d7
child 3667
21595f05bc93
     1.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Wed Jan 18 09:50:16 2012 -0800
     1.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Wed Feb 15 13:06:53 2012 -0500
     1.3 @@ -206,7 +206,6 @@
     1.4  
     1.5    _initiate_conc_mark_if_possible(false),
     1.6    _during_initial_mark_pause(false),
     1.7 -  _should_revert_to_young_gcs(false),
     1.8    _last_young_gc(false),
     1.9    _last_gc_was_young(false),
    1.10  
    1.11 @@ -295,9 +294,6 @@
    1.12    _par_last_gc_worker_times_ms = new double[_parallel_gc_threads];
    1.13    _par_last_gc_worker_other_times_ms = new double[_parallel_gc_threads];
    1.14  
    1.15 -  // start conservatively
    1.16 -  _expensive_region_limit_ms = 0.5 * (double) MaxGCPauseMillis;
    1.17 -
    1.18    int index;
    1.19    if (ParallelGCThreads == 0)
    1.20      index = 0;
    1.21 @@ -629,16 +625,9 @@
    1.22        // possible to maximize how many old regions we can add to it.
    1.23      }
    1.24    } else {
    1.25 -    if (gcs_are_young()) {
    1.26 -      young_list_target_length = _young_list_fixed_length;
    1.27 -    } else {
    1.28 -      // A bit arbitrary: during mixed GCs we allocate half
    1.29 -      // the young regions to try to add old regions to the CSet.
    1.30 -      young_list_target_length = _young_list_fixed_length / 2;
    1.31 -      // We choose to accept that we might go under the desired min
    1.32 -      // length given that we intentionally ask for a smaller young gen.
    1.33 -      desired_min_length = absolute_min_length;
    1.34 -    }
    1.35 +    // The user asked for a fixed young gen so we'll fix the young gen
    1.36 +    // whether the next GC is young or mixed.
    1.37 +    young_list_target_length = _young_list_fixed_length;
    1.38    }
    1.39  
    1.40    // Make sure we don't go over the desired max length, nor under the
    1.41 @@ -872,7 +861,6 @@
    1.42    // transitions and make sure we start with young GCs after the Full GC.
    1.43    set_gcs_are_young(true);
    1.44    _last_young_gc = false;
    1.45 -  _should_revert_to_young_gcs = false;
    1.46    clear_initiate_conc_mark_if_possible();
    1.47    clear_during_initial_mark_pause();
    1.48    _known_garbage_bytes = 0;
    1.49 @@ -889,7 +877,7 @@
    1.50    // Reset survivors SurvRateGroup.
    1.51    _survivor_surv_rate_group->reset();
    1.52    update_young_list_target_length();
    1.53 -  _collectionSetChooser->updateAfterFullCollection();
    1.54 +  _collectionSetChooser->clearMarkedHeapRegions();
    1.55  }
    1.56  
    1.57  void G1CollectorPolicy::record_stop_world_start() {
    1.58 @@ -1000,7 +988,6 @@
    1.59  }
    1.60  
    1.61  void G1CollectorPolicy::record_concurrent_mark_cleanup_completed() {
    1.62 -  _should_revert_to_young_gcs = false;
    1.63    _last_young_gc = true;
    1.64    _in_marking_window = false;
    1.65  }
    1.66 @@ -1205,9 +1192,7 @@
    1.67    last_pause_included_initial_mark = during_initial_mark_pause();
    1.68    if (last_pause_included_initial_mark) {
    1.69      record_concurrent_mark_init_end(0.0);
    1.70 -  }
    1.71 -
    1.72 -  if (!_last_young_gc && need_to_start_conc_mark("end of GC")) {
    1.73 +  } else if (!_last_young_gc && need_to_start_conc_mark("end of GC")) {
    1.74      // Note: this might have already been set, if during the last
    1.75      // pause we decided to start a cycle but at the beginning of
    1.76      // this pause we decided to postpone it. That's OK.
    1.77 @@ -1492,12 +1477,14 @@
    1.78    }
    1.79  
    1.80    if (_last_young_gc) {
    1.81 +    // This is supposed to to be the "last young GC" before we start
    1.82 +    // doing mixed GCs. Here we decide whether to start mixed GCs or not.
    1.83 +
    1.84      if (!last_pause_included_initial_mark) {
    1.85 -      ergo_verbose2(ErgoMixedGCs,
    1.86 -                    "start mixed GCs",
    1.87 -                    ergo_format_byte_perc("known garbage"),
    1.88 -                    _known_garbage_bytes, _known_garbage_ratio * 100.0);
    1.89 -      set_gcs_are_young(false);
    1.90 +      if (next_gc_should_be_mixed("start mixed GCs",
    1.91 +                                  "do not start mixed GCs")) {
    1.92 +        set_gcs_are_young(false);
    1.93 +      }
    1.94      } else {
    1.95        ergo_verbose0(ErgoMixedGCs,
    1.96                      "do not start mixed GCs",
    1.97 @@ -1507,39 +1494,14 @@
    1.98    }
    1.99  
   1.100    if (!_last_gc_was_young) {
   1.101 -    if (_should_revert_to_young_gcs) {
   1.102 -      ergo_verbose2(ErgoMixedGCs,
   1.103 -                    "end mixed GCs",
   1.104 -                    ergo_format_reason("mixed GCs end requested")
   1.105 -                    ergo_format_byte_perc("known garbage"),
   1.106 -                    _known_garbage_bytes, _known_garbage_ratio * 100.0);
   1.107 -      set_gcs_are_young(true);
   1.108 -    } else if (_known_garbage_ratio < 0.05) {
   1.109 -      ergo_verbose3(ErgoMixedGCs,
   1.110 -               "end mixed GCs",
   1.111 -               ergo_format_reason("known garbage percent lower than threshold")
   1.112 -               ergo_format_byte_perc("known garbage")
   1.113 -               ergo_format_perc("threshold"),
   1.114 -               _known_garbage_bytes, _known_garbage_ratio * 100.0,
   1.115 -               0.05 * 100.0);
   1.116 -      set_gcs_are_young(true);
   1.117 -    } else if (adaptive_young_list_length() &&
   1.118 -              (get_gc_eff_factor() * cur_efficiency < predict_young_gc_eff())) {
   1.119 -      ergo_verbose5(ErgoMixedGCs,
   1.120 -                    "end mixed GCs",
   1.121 -                    ergo_format_reason("current GC efficiency lower than "
   1.122 -                                       "predicted young GC efficiency")
   1.123 -                    ergo_format_double("GC efficiency factor")
   1.124 -                    ergo_format_double("current GC efficiency")
   1.125 -                    ergo_format_double("predicted young GC efficiency")
   1.126 -                    ergo_format_byte_perc("known garbage"),
   1.127 -                    get_gc_eff_factor(), cur_efficiency,
   1.128 -                    predict_young_gc_eff(),
   1.129 -                    _known_garbage_bytes, _known_garbage_ratio * 100.0);
   1.130 +    // This is a mixed GC. Here we decide whether to continue doing
   1.131 +    // mixed GCs or not.
   1.132 +
   1.133 +    if (!next_gc_should_be_mixed("continue mixed GCs",
   1.134 +                                 "do not continue mixed GCs")) {
   1.135        set_gcs_are_young(true);
   1.136      }
   1.137    }
   1.138 -  _should_revert_to_young_gcs = false;
   1.139  
   1.140    if (_last_gc_was_young && !_during_marking) {
   1.141      _young_gc_eff_seq->add(cur_efficiency);
   1.142 @@ -1648,15 +1610,6 @@
   1.143  
   1.144      _pending_cards_seq->add((double) _pending_cards);
   1.145      _rs_lengths_seq->add((double) _max_rs_lengths);
   1.146 -
   1.147 -    double expensive_region_limit_ms =
   1.148 -      (double) MaxGCPauseMillis - predict_constant_other_time_ms();
   1.149 -    if (expensive_region_limit_ms < 0.0) {
   1.150 -      // this means that the other time was predicted to be longer than
   1.151 -      // than the max pause time
   1.152 -      expensive_region_limit_ms = (double) MaxGCPauseMillis;
   1.153 -    }
   1.154 -    _expensive_region_limit_ms = expensive_region_limit_ms;
   1.155    }
   1.156  
   1.157    _in_marking_window = new_in_marking_window;
   1.158 @@ -1838,13 +1791,11 @@
   1.159    if (hr->is_marked())
   1.160      bytes_to_copy = hr->max_live_bytes();
   1.161    else {
   1.162 -    guarantee( hr->is_young() && hr->age_in_surv_rate_group() != -1,
   1.163 -               "invariant" );
   1.164 +    assert(hr->is_young() && hr->age_in_surv_rate_group() != -1, "invariant");
   1.165      int age = hr->age_in_surv_rate_group();
   1.166      double yg_surv_rate = predict_yg_surv_rate(age, hr->surv_rate_group());
   1.167      bytes_to_copy = (size_t) ((double) hr->used() * yg_surv_rate);
   1.168    }
   1.169 -
   1.170    return bytes_to_copy;
   1.171  }
   1.172  
   1.173 @@ -1860,22 +1811,6 @@
   1.174    _recorded_rs_lengths = rs_lengths;
   1.175  }
   1.176  
   1.177 -void G1CollectorPolicy::check_if_region_is_too_expensive(double
   1.178 -                                                           predicted_time_ms) {
   1.179 -  // I don't think we need to do this when in young GC mode since
   1.180 -  // marking will be initiated next time we hit the soft limit anyway...
   1.181 -  if (predicted_time_ms > _expensive_region_limit_ms) {
   1.182 -    ergo_verbose2(ErgoMixedGCs,
   1.183 -              "request mixed GCs end",
   1.184 -              ergo_format_reason("predicted region time higher than threshold")
   1.185 -              ergo_format_ms("predicted region time")
   1.186 -              ergo_format_ms("threshold"),
   1.187 -              predicted_time_ms, _expensive_region_limit_ms);
   1.188 -    // no point in doing another mixed GC
   1.189 -    _should_revert_to_young_gcs = true;
   1.190 -  }
   1.191 -}
   1.192 -
   1.193  void G1CollectorPolicy::update_recent_gc_times(double end_time_sec,
   1.194                                                 double elapsed_ms) {
   1.195    _recent_gc_times_ms->add(elapsed_ms);
   1.196 @@ -2274,12 +2209,12 @@
   1.197  }
   1.198  
   1.199  class KnownGarbageClosure: public HeapRegionClosure {
   1.200 +  G1CollectedHeap* _g1h;
   1.201    CollectionSetChooser* _hrSorted;
   1.202  
   1.203  public:
   1.204    KnownGarbageClosure(CollectionSetChooser* hrSorted) :
   1.205 -    _hrSorted(hrSorted)
   1.206 -  {}
   1.207 +    _g1h(G1CollectedHeap::heap()), _hrSorted(hrSorted) { }
   1.208  
   1.209    bool doHeapRegion(HeapRegion* r) {
   1.210      // We only include humongous regions in collection
   1.211 @@ -2288,11 +2223,10 @@
   1.212  
   1.213      // Do we have any marking information for this region?
   1.214      if (r->is_marked()) {
   1.215 -      // We don't include humongous regions in collection
   1.216 -      // sets because we collect them immediately at the end of a marking
   1.217 -      // cycle.  We also don't include young regions because we *must*
   1.218 -      // include them in the next collection pause.
   1.219 -      if (!r->isHumongous() && !r->is_young()) {
   1.220 +      // We will skip any region that's currently used as an old GC
   1.221 +      // alloc region (we should not consider those for collection
   1.222 +      // before we fill them up).
   1.223 +      if (_hrSorted->shouldAdd(r) && !_g1h->is_old_gc_alloc_region(r)) {
   1.224          _hrSorted->addMarkedHeapRegion(r);
   1.225        }
   1.226      }
   1.227 @@ -2301,8 +2235,10 @@
   1.228  };
   1.229  
   1.230  class ParKnownGarbageHRClosure: public HeapRegionClosure {
   1.231 +  G1CollectedHeap* _g1h;
   1.232    CollectionSetChooser* _hrSorted;
   1.233    jint _marked_regions_added;
   1.234 +  size_t _reclaimable_bytes_added;
   1.235    jint _chunk_size;
   1.236    jint _cur_chunk_idx;
   1.237    jint _cur_chunk_end; // Cur chunk [_cur_chunk_idx, _cur_chunk_end)
   1.238 @@ -2320,6 +2256,7 @@
   1.239      assert(_cur_chunk_idx < _cur_chunk_end, "postcondition");
   1.240      _hrSorted->setMarkedHeapRegion(_cur_chunk_idx, r);
   1.241      _marked_regions_added++;
   1.242 +    _reclaimable_bytes_added += r->reclaimable_bytes();
   1.243      _cur_chunk_idx++;
   1.244    }
   1.245  
   1.246 @@ -2327,10 +2264,10 @@
   1.247    ParKnownGarbageHRClosure(CollectionSetChooser* hrSorted,
   1.248                             jint chunk_size,
   1.249                             int worker) :
   1.250 -    _hrSorted(hrSorted), _chunk_size(chunk_size), _worker(worker),
   1.251 -    _marked_regions_added(0), _cur_chunk_idx(0), _cur_chunk_end(0),
   1.252 -    _invokes(0)
   1.253 -  {}
   1.254 +      _g1h(G1CollectedHeap::heap()),
   1.255 +      _hrSorted(hrSorted), _chunk_size(chunk_size), _worker(worker),
   1.256 +      _marked_regions_added(0), _reclaimable_bytes_added(0),
   1.257 +      _cur_chunk_idx(0), _cur_chunk_end(0), _invokes(0) { }
   1.258  
   1.259    bool doHeapRegion(HeapRegion* r) {
   1.260      // We only include humongous regions in collection
   1.261 @@ -2340,17 +2277,17 @@
   1.262  
   1.263      // Do we have any marking information for this region?
   1.264      if (r->is_marked()) {
   1.265 -      // We don't include humongous regions in collection
   1.266 -      // sets because we collect them immediately at the end of a marking
   1.267 -      // cycle.
   1.268 -      // We also do not include young regions in collection sets
   1.269 -      if (!r->isHumongous() && !r->is_young()) {
   1.270 +      // We will skip any region that's currently used as an old GC
   1.271 +      // alloc region (we should not consider those for collection
   1.272 +      // before we fill them up).
   1.273 +      if (_hrSorted->shouldAdd(r) && !_g1h->is_old_gc_alloc_region(r)) {
   1.274          add_region(r);
   1.275        }
   1.276      }
   1.277      return false;
   1.278    }
   1.279    jint marked_regions_added() { return _marked_regions_added; }
   1.280 +  size_t reclaimable_bytes_added() { return _reclaimable_bytes_added; }
   1.281    int invokes() { return _invokes; }
   1.282  };
   1.283  
   1.284 @@ -2362,8 +2299,7 @@
   1.285    ParKnownGarbageTask(CollectionSetChooser* hrSorted, jint chunk_size) :
   1.286      AbstractGangTask("ParKnownGarbageTask"),
   1.287      _hrSorted(hrSorted), _chunk_size(chunk_size),
   1.288 -    _g1(G1CollectedHeap::heap())
   1.289 -  {}
   1.290 +    _g1(G1CollectedHeap::heap()) { }
   1.291  
   1.292    void work(uint worker_id) {
   1.293      ParKnownGarbageHRClosure parKnownGarbageCl(_hrSorted,
   1.294 @@ -2374,7 +2310,9 @@
   1.295                                           _g1->workers()->active_workers(),
   1.296                                           HeapRegion::InitialClaimValue);
   1.297      jint regions_added = parKnownGarbageCl.marked_regions_added();
   1.298 -    _hrSorted->incNumMarkedHeapRegions(regions_added);
   1.299 +    size_t reclaimable_bytes_added =
   1.300 +                                   parKnownGarbageCl.reclaimable_bytes_added();
   1.301 +    _hrSorted->updateTotals(regions_added, reclaimable_bytes_added);
   1.302      if (G1PrintParCleanupStats) {
   1.303        gclog_or_tty->print_cr("     Thread %d called %d times, added %d regions to list.",
   1.304                   worker_id, parKnownGarbageCl.invokes(), regions_added);
   1.305 @@ -2658,7 +2596,43 @@
   1.306  }
   1.307  #endif // !PRODUCT
   1.308  
   1.309 -void G1CollectorPolicy::choose_collection_set(double target_pause_time_ms) {
   1.310 +bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str,
   1.311 +                                                const char* false_action_str) {
   1.312 +  CollectionSetChooser* cset_chooser = _collectionSetChooser;
   1.313 +  if (cset_chooser->isEmpty()) {
   1.314 +    ergo_verbose0(ErgoMixedGCs,
   1.315 +                  false_action_str,
   1.316 +                  ergo_format_reason("candidate old regions not available"));
   1.317 +    return false;
   1.318 +  }
   1.319 +  size_t reclaimable_bytes = cset_chooser->remainingReclaimableBytes();
   1.320 +  size_t capacity_bytes = _g1->capacity();
   1.321 +  double perc = (double) reclaimable_bytes * 100.0 / (double) capacity_bytes;
   1.322 +  double threshold = (double) G1OldReclaimableThresholdPercent;
   1.323 +  if (perc < threshold) {
   1.324 +    ergo_verbose4(ErgoMixedGCs,
   1.325 +              false_action_str,
   1.326 +              ergo_format_reason("reclaimable percentage lower than threshold")
   1.327 +              ergo_format_region("candidate old regions")
   1.328 +              ergo_format_byte_perc("reclaimable")
   1.329 +              ergo_format_perc("threshold"),
   1.330 +              cset_chooser->remainingRegions(),
   1.331 +              reclaimable_bytes, perc, threshold);
   1.332 +    return false;
   1.333 +  }
   1.334 +
   1.335 +  ergo_verbose4(ErgoMixedGCs,
   1.336 +                true_action_str,
   1.337 +                ergo_format_reason("candidate old regions available")
   1.338 +                ergo_format_region("candidate old regions")
   1.339 +                ergo_format_byte_perc("reclaimable")
   1.340 +                ergo_format_perc("threshold"),
   1.341 +                cset_chooser->remainingRegions(),
   1.342 +                reclaimable_bytes, perc, threshold);
   1.343 +  return true;
   1.344 +}
   1.345 +
   1.346 +void G1CollectorPolicy::finalize_cset(double target_pause_time_ms) {
   1.347    // Set this here - in case we're not doing young collections.
   1.348    double non_young_start_time_sec = os::elapsedTime();
   1.349  
   1.350 @@ -2672,7 +2646,6 @@
   1.351  
   1.352    double base_time_ms = predict_base_elapsed_time_ms(_pending_cards);
   1.353    double predicted_pause_time_ms = base_time_ms;
   1.354 -
   1.355    double time_remaining_ms = target_pause_time_ms - base_time_ms;
   1.356  
   1.357    ergo_verbose3(ErgoCSetConstruction | ErgoHigh,
   1.358 @@ -2682,22 +2655,6 @@
   1.359                  ergo_format_ms("target pause time"),
   1.360                  base_time_ms, time_remaining_ms, target_pause_time_ms);
   1.361  
   1.362 -  // the 10% and 50% values are arbitrary...
   1.363 -  double threshold = 0.10 * target_pause_time_ms;
   1.364 -  if (time_remaining_ms < threshold) {
   1.365 -    double prev_time_remaining_ms = time_remaining_ms;
   1.366 -    time_remaining_ms = 0.50 * target_pause_time_ms;
   1.367 -    ergo_verbose3(ErgoCSetConstruction,
   1.368 -                  "adjust remaining time",
   1.369 -                  ergo_format_reason("remaining time lower than threshold")
   1.370 -                  ergo_format_ms("remaining time")
   1.371 -                  ergo_format_ms("threshold")
   1.372 -                  ergo_format_ms("adjusted remaining time"),
   1.373 -                  prev_time_remaining_ms, threshold, time_remaining_ms);
   1.374 -  }
   1.375 -
   1.376 -  size_t expansion_bytes = _g1->expansion_regions() * HeapRegion::GrainBytes;
   1.377 -
   1.378    HeapRegion* hr;
   1.379    double young_start_time_sec = os::elapsedTime();
   1.380  
   1.381 @@ -2752,78 +2709,97 @@
   1.382    non_young_start_time_sec = young_end_time_sec;
   1.383  
   1.384    if (!gcs_are_young()) {
   1.385 -    bool should_continue = true;
   1.386 -    NumberSeq seq;
   1.387 -    double avg_prediction = 100000000000000000.0; // something very large
   1.388 -
   1.389 -    double prev_predicted_pause_time_ms = predicted_pause_time_ms;
   1.390 -    do {
   1.391 -      // Note that add_old_region_to_cset() increments the
   1.392 -      // _old_cset_region_length field and cset_region_length() returns the
   1.393 -      // sum of _eden_cset_region_length, _survivor_cset_region_length, and
   1.394 -      // _old_cset_region_length. So, as old regions are added to the
   1.395 -      // CSet, _old_cset_region_length will be incremented and
   1.396 -      // cset_region_length(), which is used below, will always reflect
   1.397 -      // the the total number of regions added up to this point to the CSet.
   1.398 -
   1.399 -      hr = _collectionSetChooser->getNextMarkedRegion(time_remaining_ms,
   1.400 -                                                      avg_prediction);
   1.401 -      if (hr != NULL) {
   1.402 -        _g1->old_set_remove(hr);
   1.403 -        double predicted_time_ms = predict_region_elapsed_time_ms(hr, false);
   1.404 -        time_remaining_ms -= predicted_time_ms;
   1.405 -        predicted_pause_time_ms += predicted_time_ms;
   1.406 -        add_old_region_to_cset(hr);
   1.407 -        seq.add(predicted_time_ms);
   1.408 -        avg_prediction = seq.avg() + seq.sd();
   1.409 +    CollectionSetChooser* cset_chooser = _collectionSetChooser;
   1.410 +    assert(cset_chooser->verify(), "CSet Chooser verification - pre");
   1.411 +    const size_t min_old_cset_length = cset_chooser->calcMinOldCSetLength();
   1.412 +    const size_t max_old_cset_length = cset_chooser->calcMaxOldCSetLength();
   1.413 +
   1.414 +    size_t expensive_region_num = 0;
   1.415 +    bool check_time_remaining = adaptive_young_list_length();
   1.416 +    HeapRegion* hr = cset_chooser->peek();
   1.417 +    while (hr != NULL) {
   1.418 +      if (old_cset_region_length() >= max_old_cset_length) {
   1.419 +        // Added maximum number of old regions to the CSet.
   1.420 +        ergo_verbose2(ErgoCSetConstruction,
   1.421 +                      "finish adding old regions to CSet",
   1.422 +                      ergo_format_reason("old CSet region num reached max")
   1.423 +                      ergo_format_region("old")
   1.424 +                      ergo_format_region("max"),
   1.425 +                      old_cset_region_length(), max_old_cset_length);
   1.426 +        break;
   1.427        }
   1.428  
   1.429 -      should_continue = true;
   1.430 -      if (hr == NULL) {
   1.431 -        // No need for an ergo verbose message here,
   1.432 -        // getNextMarkRegion() does this when it returns NULL.
   1.433 -        should_continue = false;
   1.434 +      double predicted_time_ms = predict_region_elapsed_time_ms(hr, false);
   1.435 +      if (check_time_remaining) {
   1.436 +        if (predicted_time_ms > time_remaining_ms) {
   1.437 +          // Too expensive for the current CSet.
   1.438 +
   1.439 +          if (old_cset_region_length() >= min_old_cset_length) {
   1.440 +            // We have added the minimum number of old regions to the CSet,
   1.441 +            // we are done with this CSet.
   1.442 +            ergo_verbose4(ErgoCSetConstruction,
   1.443 +                          "finish adding old regions to CSet",
   1.444 +                          ergo_format_reason("predicted time is too high")
   1.445 +                          ergo_format_ms("predicted time")
   1.446 +                          ergo_format_ms("remaining time")
   1.447 +                          ergo_format_region("old")
   1.448 +                          ergo_format_region("min"),
   1.449 +                          predicted_time_ms, time_remaining_ms,
   1.450 +                          old_cset_region_length(), min_old_cset_length);
   1.451 +            break;
   1.452 +          }
   1.453 +
   1.454 +          // We'll add it anyway given that we haven't reached the
   1.455 +          // minimum number of old regions.
   1.456 +          expensive_region_num += 1;
   1.457 +        }
   1.458        } else {
   1.459 -        if (adaptive_young_list_length()) {
   1.460 -          if (time_remaining_ms < 0.0) {
   1.461 -            ergo_verbose1(ErgoCSetConstruction,
   1.462 -                          "stop adding old regions to CSet",
   1.463 -                          ergo_format_reason("remaining time is lower than 0")
   1.464 -                          ergo_format_ms("remaining time"),
   1.465 -                          time_remaining_ms);
   1.466 -            should_continue = false;
   1.467 -          }
   1.468 -        } else {
   1.469 -          if (cset_region_length() >= _young_list_fixed_length) {
   1.470 -            ergo_verbose2(ErgoCSetConstruction,
   1.471 -                          "stop adding old regions to CSet",
   1.472 -                          ergo_format_reason("CSet length reached target")
   1.473 -                          ergo_format_region("CSet")
   1.474 -                          ergo_format_region("young target"),
   1.475 -                          cset_region_length(), _young_list_fixed_length);
   1.476 -            should_continue = false;
   1.477 -          }
   1.478 +        if (old_cset_region_length() >= min_old_cset_length) {
   1.479 +          // In the non-auto-tuning case, we'll finish adding regions
   1.480 +          // to the CSet if we reach the minimum.
   1.481 +          ergo_verbose2(ErgoCSetConstruction,
   1.482 +                        "finish adding old regions to CSet",
   1.483 +                        ergo_format_reason("old CSet region num reached min")
   1.484 +                        ergo_format_region("old")
   1.485 +                        ergo_format_region("min"),
   1.486 +                        old_cset_region_length(), min_old_cset_length);
   1.487 +          break;
   1.488          }
   1.489        }
   1.490 -    } while (should_continue);
   1.491 -
   1.492 -    if (!adaptive_young_list_length() &&
   1.493 -        cset_region_length() < _young_list_fixed_length) {
   1.494 -      ergo_verbose2(ErgoCSetConstruction,
   1.495 -                    "request mixed GCs end",
   1.496 -                    ergo_format_reason("CSet length lower than target")
   1.497 -                    ergo_format_region("CSet")
   1.498 -                    ergo_format_region("young target"),
   1.499 -                    cset_region_length(), _young_list_fixed_length);
   1.500 -      _should_revert_to_young_gcs  = true;
   1.501 +
   1.502 +      // We will add this region to the CSet.
   1.503 +      time_remaining_ms -= predicted_time_ms;
   1.504 +      predicted_pause_time_ms += predicted_time_ms;
   1.505 +      cset_chooser->remove_and_move_to_next(hr);
   1.506 +      _g1->old_set_remove(hr);
   1.507 +      add_old_region_to_cset(hr);
   1.508 +
   1.509 +      hr = cset_chooser->peek();
   1.510      }
   1.511 -
   1.512 -    ergo_verbose2(ErgoCSetConstruction | ErgoHigh,
   1.513 -                  "add old regions to CSet",
   1.514 -                  ergo_format_region("old")
   1.515 -                  ergo_format_ms("predicted old region time"),
   1.516 -                  old_cset_region_length(),
   1.517 -                  predicted_pause_time_ms - prev_predicted_pause_time_ms);
   1.518 +    if (hr == NULL) {
   1.519 +      ergo_verbose0(ErgoCSetConstruction,
   1.520 +                    "finish adding old regions to CSet",
   1.521 +                    ergo_format_reason("candidate old regions not available"));
   1.522 +    }
   1.523 +
   1.524 +    if (expensive_region_num > 0) {
   1.525 +      // We print the information once here at the end, predicated on
   1.526 +      // whether we added any apparently expensive regions or not, to
   1.527 +      // avoid generating output per region.
   1.528 +      ergo_verbose4(ErgoCSetConstruction,
   1.529 +                    "added expensive regions to CSet",
   1.530 +                    ergo_format_reason("old CSet region num not reached min")
   1.531 +                    ergo_format_region("old")
   1.532 +                    ergo_format_region("expensive")
   1.533 +                    ergo_format_region("min")
   1.534 +                    ergo_format_ms("remaining time"),
   1.535 +                    old_cset_region_length(),
   1.536 +                    expensive_region_num,
   1.537 +                    min_old_cset_length,
   1.538 +                    time_remaining_ms);
   1.539 +    }
   1.540 +
   1.541 +    assert(cset_chooser->verify(), "CSet Chooser verification - post");
   1.542    }
   1.543  
   1.544    stop_incremental_cset_building();

mercurial