< prev index next >

src/hotspot/share/gc/g1/g1Policy.cpp

Print this page
rev 56969 : imported patch 8228609-used-vs-copied-bytes
rev 56970 : imported patch 8228609-kbarrett-review
rev 56971 : imported patch 8227739-merge-scan-rs-update-rs-cost
rev 56975 : imported patch 8227434-g1-predictions-overflow
rev 56981 : imported patch 8233588-cleanup-survrategroup
rev 56982 : [mq]: 8231579-incremental-calculation-wrong

@@ -60,11 +60,11 @@
   _full_collection_start_sec(0.0),
   _collection_pause_end_millis(os::javaTimeNanos() / NANOSECS_PER_MILLISEC),
   _young_list_target_length(0),
   _young_list_fixed_length(0),
   _young_list_max_length(0),
-  _short_lived_surv_rate_group(new SurvRateGroup()),
+  _eden_surv_rate_group(new SurvRateGroup()),
   _survivor_surv_rate_group(new SurvRateGroup()),
   _reserve_factor((double) G1ReservePercent / 100.0),
   _reserve_regions(0),
   _young_gen_sizer(G1YoungGenSizer::create_gen_sizer()),
   _free_regions_at_end_of_collection(0),

@@ -125,11 +125,10 @@
 void G1Policy::note_gc_start() {
   phase_times()->note_gc_start();
 }
 
 class G1YoungLengthPredictor {
-  const bool _during_cm;
   const double _base_time_ms;
   const double _base_free_regions;
   const double _target_pause_time_ms;
   const G1Policy* const _policy;
 

@@ -137,11 +136,10 @@
   G1YoungLengthPredictor(bool during_cm,
                          double base_time_ms,
                          double base_free_regions,
                          double target_pause_time_ms,
                          const G1Policy* policy) :
-    _during_cm(during_cm),
     _base_time_ms(base_time_ms),
     _base_free_regions(base_free_regions),
     _target_pause_time_ms(target_pause_time_ms),
     _policy(policy) {}
 

@@ -149,15 +147,12 @@
     if (young_length >= _base_free_regions) {
       // end condition 1: not enough space for the young regions
       return false;
     }
 
-    const double accum_surv_rate = _policy->accum_yg_surv_rate_pred((int) young_length - 1);
-    const size_t bytes_to_copy =
-                 (size_t) (accum_surv_rate * (double) HeapRegion::GrainBytes);
-    const double copy_time_ms =
-      _policy->analytics()->predict_object_copy_time_ms(bytes_to_copy, _during_cm);
+    size_t bytes_to_copy = 0;
+    const double copy_time_ms = _policy->predict_eden_copy_time_ms(young_length, &bytes_to_copy);
     const double young_other_time_ms = _policy->analytics()->predict_young_other_time_ms(young_length);
     const double pause_time_ms = _base_time_ms + copy_time_ms + young_other_time_ms;
     if (pause_time_ms > _target_pause_time_ms) {
       // end condition 2: prediction is over the target pause time
       return false;

@@ -301,12 +296,11 @@
 
   result.first = young_list_target_length;
   return result;
 }
 
-uint
-G1Policy::calculate_young_list_target_length(size_t rs_length,
+uint G1Policy::calculate_young_list_target_length(size_t rs_length,
                                                     uint base_min_length,
                                                     uint desired_min_length,
                                                     uint desired_max_length) const {
   assert(use_adaptive_young_list_length(), "pre-condition");
   assert(collector_state()->in_young_only_phase(), "only call this for young GCs");

@@ -325,15 +319,12 @@
   uint min_young_length = desired_min_length - base_min_length;
   assert(desired_max_length > base_min_length, "invariant");
   uint max_young_length = desired_max_length - base_min_length;
 
   const double target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0;
-  const double survivor_regions_evac_time = predict_survivor_regions_evac_time();
   const size_t pending_cards = _analytics->predict_pending_cards();
-  const double base_time_ms =
-    predict_base_elapsed_time_ms(pending_cards, rs_length) +
-    survivor_regions_evac_time;
+  const double base_time_ms = predict_base_elapsed_time_ms(pending_cards, rs_length);
   const uint available_free_regions = _free_regions_at_end_of_collection;
   const uint base_free_regions =
     available_free_regions > _reserve_regions ? available_free_regions - _reserve_regions : 0;
 
   // Here, we will make sure that the shortest young length that

@@ -404,15 +395,14 @@
 }
 
 double G1Policy::predict_survivor_regions_evac_time() const {
   double survivor_regions_evac_time = 0.0;
   const GrowableArray<HeapRegion*>* survivor_regions = _g1h->survivor()->regions();
-
   for (GrowableArrayIterator<HeapRegion*> it = survivor_regions->begin();
        it != survivor_regions->end();
        ++it) {
-    survivor_regions_evac_time += predict_region_elapsed_time_ms(*it, collector_state()->in_young_only_phase());
+    survivor_regions_evac_time += predict_region_total_time_ms(*it, collector_state()->in_young_only_phase());
   }
   return survivor_regions_evac_time;
 }
 
 void G1Policy::revise_young_list_target_length_if_necessary(size_t rs_length) {

@@ -464,11 +454,11 @@
   collector_state()->set_initiate_conc_mark_if_possible(need_to_start_conc_mark("end of Full GC", 0));
   collector_state()->set_in_initial_mark_gc(false);
   collector_state()->set_mark_or_rebuild_in_progress(false);
   collector_state()->set_clearing_next_bitmap(false);
 
-  _short_lived_surv_rate_group->start_adding_regions();
+  _eden_surv_rate_group->start_adding_regions();
   // also call this on any additional surv rate groups
 
   _free_regions_at_end_of_collection = _g1h->num_free_regions();
   // Reset survivors SurvRateGroup.
   _survivor_surv_rate_group->reset();

@@ -551,11 +541,11 @@
   record_concurrent_refinement_data(false /* is_full_collection */);
 
   _collection_set->reset_bytes_used_before();
 
   // do that for any other surv rate groups
-  _short_lived_surv_rate_group->stop_adding_regions();
+  _eden_surv_rate_group->stop_adding_regions();
   _survivors_age_table.clear();
 
   assert(_g1h->collection_set()->verify_young_ages(), "region age verification failed");
 }
 

@@ -709,11 +699,11 @@
       clear_collection_set_candidates();
       maybe_start_marking();
     }
   }
 
-  _short_lived_surv_rate_group->start_adding_regions();
+  _eden_surv_rate_group->start_adding_regions();
 
   double merge_hcc_time_ms = average_time_ms(G1GCPhaseTimes::MergeHCC);
   if (update_stats) {
     size_t const total_log_buffer_cards = p->sum_thread_work_items(G1GCPhaseTimes::MergeHCC, G1GCPhaseTimes::MergeHCCDirtyCards) +
                                           p->sum_thread_work_items(G1GCPhaseTimes::MergeLB, G1GCPhaseTimes::MergeLBDirtyCards);

@@ -905,21 +895,18 @@
 
 void G1Policy::print_phases() {
   phase_times()->print();
 }
 
-double G1Policy::accum_yg_surv_rate_pred(int age) const {
-  return _short_lived_surv_rate_group->accum_surv_rate_pred(age);
-}
-
 double G1Policy::predict_base_elapsed_time_ms(size_t pending_cards,
                                               size_t rs_length) const {
   size_t effective_scanned_cards = _analytics->predict_scan_card_num(rs_length, collector_state()->in_young_only_phase());
   return
     _analytics->predict_card_merge_time_ms(pending_cards + rs_length, collector_state()->in_young_only_phase()) +
     _analytics->predict_card_scan_time_ms(effective_scanned_cards, collector_state()->in_young_only_phase()) +
-    _analytics->predict_constant_other_time_ms();
+    _analytics->predict_constant_other_time_ms() +
+    predict_survivor_regions_evac_time();
 }
 
 double G1Policy::predict_base_elapsed_time_ms(size_t pending_cards) const {
   size_t rs_length = _analytics->predict_rs_length();
   return predict_base_elapsed_time_ms(pending_cards, rs_length);

@@ -933,21 +920,34 @@
     bytes_to_copy = (size_t) (hr->used() * hr->surv_rate_prediction(_predictor));
   }
   return bytes_to_copy;
 }
 
-double G1Policy::predict_region_elapsed_time_ms(HeapRegion* hr,
+double G1Policy::predict_eden_copy_time_ms(uint count, size_t* bytes_to_copy) const {
+  if (count == 0) {
+    return 0.0;
+  }
+  size_t const expected_bytes = _eden_surv_rate_group->accum_surv_rate_pred(count) * HeapRegion::GrainBytes;
+  if (bytes_to_copy != NULL) {
+    *bytes_to_copy = expected_bytes;
+  }
+  return _analytics->predict_object_copy_time_ms(expected_bytes, collector_state()->mark_or_rebuild_in_progress());
+}
+
+double G1Policy::predict_region_copy_time_ms(HeapRegion* hr) const {
+  size_t const bytes_to_copy = predict_bytes_to_copy(hr);
+  return _analytics->predict_object_copy_time_ms(bytes_to_copy, collector_state()->mark_or_rebuild_in_progress());
+}
+
+double G1Policy::predict_region_non_copy_time_ms(HeapRegion* hr,
                                                 bool for_young_gc) const {
   size_t rs_length = hr->rem_set()->occupied();
   size_t scan_card_num = _analytics->predict_scan_card_num(rs_length, for_young_gc);
 
-  size_t bytes_to_copy = predict_bytes_to_copy(hr);
-
   double region_elapsed_time_ms =
     _analytics->predict_card_merge_time_ms(rs_length, collector_state()->in_young_only_phase()) +
-    _analytics->predict_card_scan_time_ms(scan_card_num, collector_state()->in_young_only_phase()) +
-    _analytics->predict_object_copy_time_ms(bytes_to_copy, collector_state()->mark_or_rebuild_in_progress());
+    _analytics->predict_card_scan_time_ms(scan_card_num, collector_state()->in_young_only_phase());
 
   // The prediction of the "other" time for this region is based
   // upon the region type and NOT the GC type.
   if (hr->is_young()) {
     region_elapsed_time_ms += _analytics->predict_young_other_time_ms(1);

@@ -955,10 +955,14 @@
     region_elapsed_time_ms += _analytics->predict_non_young_other_time_ms(1);
   }
   return region_elapsed_time_ms;
 }
 
+double G1Policy::predict_region_total_time_ms(HeapRegion* hr, bool for_young_gc) const {
+  return predict_region_non_copy_time_ms(hr, for_young_gc) + predict_region_copy_time_ms(hr);
+}
+
 bool G1Policy::should_allocate_mutator_region() const {
   uint young_list_length = _g1h->young_regions_count();
   uint young_list_target_length = _young_list_target_length;
   return young_list_length < young_list_target_length;
 }

@@ -1302,11 +1306,11 @@
                                 byte_size_in_proper_unit(reclaimable_bytes), proper_unit_for_byte_size(reclaimable_bytes),
                                 reclaimable_percent, G1HeapWastePercent);
       break;
     }
 
-    double predicted_time_ms = predict_region_elapsed_time_ms(hr, false);
+    double predicted_time_ms = predict_region_total_time_ms(hr, false);
     time_remaining_ms = MAX2(time_remaining_ms - predicted_time_ms, 0.0);
     // Add regions to old set until we reach the minimum amount
     if (num_initial_regions < min_old_cset_length) {
       predicted_old_time_ms += predicted_time_ms;
       num_initial_regions++;

@@ -1362,11 +1366,11 @@
   uint candidate_idx = candidates->cur_idx();
 
   HeapRegion* r = candidates->at(candidate_idx);
   while (num_optional_regions < max_optional_regions) {
     assert(r != NULL, "Region must exist");
-    prediction_ms += predict_region_elapsed_time_ms(r, false);
+    prediction_ms += predict_region_total_time_ms(r, false);
 
     if (prediction_ms > time_remaining_ms) {
       log_debug(gc, ergo, cset)("Prediction %.3fms for region %u does not fit remaining time: %.3fms.",
                                 prediction_ms, r->hrm_index(), time_remaining_ms);
       break;
< prev index next >