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();