hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp
changeset 33214 5a00fba36171
parent 33204 b8a3901ac5b3
child 33218 32b706c7c6a0
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Thu Oct 15 00:42:15 2015 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Thu Oct 15 10:07:28 2015 +0200
@@ -80,6 +80,7 @@
 };
 
 G1CollectorPolicy::G1CollectorPolicy() :
+  _predictor(G1ConfidencePercent / 100.0),
   _parallel_gc_threads(ParallelGCThreads),
 
   _recent_gc_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
@@ -127,8 +128,6 @@
   _survivor_cset_region_length(0),
   _old_cset_region_length(0),
 
-  _sigma(G1ConfidencePercent / 100.0),
-
   _collection_set(NULL),
   _collection_set_bytes_used_before(0),
 
@@ -151,12 +150,12 @@
 
   _gc_overhead_perc(0.0) {
 
-  // SurvRateGroups below must be initialized after '_sigma' because they
-  // indirectly access '_sigma' through this object passed to their constructor.
+  // SurvRateGroups below must be initialized after the predictor because they
+  // indirectly use it through this object passed to their constructor.
   _short_lived_surv_rate_group =
-    new SurvRateGroup(this, "Short Lived", G1YoungSurvRateNumRegionsSummary);
+    new SurvRateGroup(&_predictor, "Short Lived", G1YoungSurvRateNumRegionsSummary);
   _survivor_surv_rate_group =
-    new SurvRateGroup(this, "Survivor", G1YoungSurvRateNumRegionsSummary);
+    new SurvRateGroup(&_predictor, "Survivor", G1YoungSurvRateNumRegionsSummary);
 
   // Set up the region size and associated fields. Given that the
   // policy is created before the heap, we have to set this up here,
@@ -289,6 +288,10 @@
   _collectionSetChooser = new CollectionSetChooser();
 }
 
+double G1CollectorPolicy::get_new_prediction(TruncatedSeq const* seq) const {
+  return _predictor.get_new_prediction(seq);
+}
+
 void G1CollectorPolicy::initialize_alignments() {
   _space_alignment = HeapRegion::GrainBytes;
   size_t card_table_alignment = GenRemSet::max_alignment_constraint();
@@ -316,8 +319,7 @@
   }
 }
 
-const G1CollectorState* G1CollectorPolicy::collector_state() const { return _g1->collector_state(); }
-G1CollectorState* G1CollectorPolicy::collector_state() { return _g1->collector_state(); }
+G1CollectorState* G1CollectorPolicy::collector_state() const { return _g1->collector_state(); }
 
 G1YoungGenSizer::G1YoungGenSizer() : _sizer_kind(SizerDefaults), _adaptive_size(true),
         _min_desired_young_length(0), _max_desired_young_length(0) {
@@ -428,8 +430,8 @@
     _young_list_fixed_length = _young_gen_sizer->min_desired_young_length();
   }
   _free_regions_at_end_of_collection = _g1->num_free_regions();
+
   update_young_list_target_length();
-
   // We may immediately start allocating regions and placing them on the
   // collection set list. Initialize the per-collection set info
   start_incremental_cset_building();
@@ -460,9 +462,8 @@
     return false;
   }
 
-  size_t free_bytes =
-                   (base_free_regions - young_length) * HeapRegion::GrainBytes;
-  if ((2.0 * sigma()) * (double) bytes_to_copy > (double) free_bytes) {
+  size_t free_bytes = (base_free_regions - young_length) * HeapRegion::GrainBytes;
+  if ((2.0 /* magic */ * _predictor.sigma()) * bytes_to_copy > free_bytes) {
     // end condition 3: out-of-space (conservatively!)
     return false;
   }
@@ -1269,7 +1270,7 @@
     cg1r->set_red_zone(g * k_gr);
     cg1r->reinitialize_threads();
 
-    int processing_threshold_delta = MAX2((int)(cg1r->green_zone() * sigma()), 1);
+    int processing_threshold_delta = MAX2((int)(cg1r->green_zone() * _predictor.sigma()), 1);
     int processing_threshold = MIN2(cg1r->green_zone() + processing_threshold_delta,
                                     cg1r->yellow_zone());
     // Change the barrier params
@@ -1286,17 +1287,125 @@
   dcqs.notify_if_necessary();
 }
 
-double
-G1CollectorPolicy::predict_base_elapsed_time_ms(size_t pending_cards,
-                                                size_t scanned_cards) const {
+size_t G1CollectorPolicy::predict_rs_length_diff() const {
+  return (size_t) get_new_prediction(_rs_length_diff_seq);
+}
+
+double G1CollectorPolicy::predict_alloc_rate_ms() const {
+  return get_new_prediction(_alloc_rate_ms_seq);
+}
+
+double G1CollectorPolicy::predict_cost_per_card_ms() const {
+  return get_new_prediction(_cost_per_card_ms_seq);
+}
+
+double G1CollectorPolicy::predict_scan_hcc_ms() const {
+  return get_new_prediction(_cost_scan_hcc_seq);
+}
+
+double G1CollectorPolicy::predict_rs_update_time_ms(size_t pending_cards) const {
+  return pending_cards * predict_cost_per_card_ms() + predict_scan_hcc_ms();
+}
+
+double G1CollectorPolicy::predict_young_cards_per_entry_ratio() const {
+  return get_new_prediction(_young_cards_per_entry_ratio_seq);
+}
+
+double G1CollectorPolicy::predict_mixed_cards_per_entry_ratio() const {
+  if (_mixed_cards_per_entry_ratio_seq->num() < 2) {
+    return predict_young_cards_per_entry_ratio();
+  } else {
+    return get_new_prediction(_mixed_cards_per_entry_ratio_seq);
+  }
+}
+
+size_t G1CollectorPolicy::predict_young_card_num(size_t rs_length) const {
+  return (size_t) (rs_length * predict_young_cards_per_entry_ratio());
+}
+
+size_t G1CollectorPolicy::predict_non_young_card_num(size_t rs_length) const {
+  return (size_t)(rs_length * predict_mixed_cards_per_entry_ratio());
+}
+
+double G1CollectorPolicy::predict_rs_scan_time_ms(size_t card_num) const {
+  if (collector_state()->gcs_are_young()) {
+    return card_num * get_new_prediction(_cost_per_entry_ms_seq);
+  } else {
+    return predict_mixed_rs_scan_time_ms(card_num);
+  }
+}
+
+double G1CollectorPolicy::predict_mixed_rs_scan_time_ms(size_t card_num) const {
+  if (_mixed_cost_per_entry_ms_seq->num() < 3) {
+    return card_num * get_new_prediction(_cost_per_entry_ms_seq);
+  } else {
+    return card_num * get_new_prediction(_mixed_cost_per_entry_ms_seq);
+  }
+}
+
+double G1CollectorPolicy::predict_object_copy_time_ms_during_cm(size_t bytes_to_copy) const {
+  if (_cost_per_byte_ms_during_cm_seq->num() < 3) {
+    return (1.1 * bytes_to_copy) * get_new_prediction(_cost_per_byte_ms_seq);
+  } else {
+    return bytes_to_copy * get_new_prediction(_cost_per_byte_ms_during_cm_seq);
+  }
+}
+
+double G1CollectorPolicy::predict_object_copy_time_ms(size_t bytes_to_copy) const {
+  if (collector_state()->during_concurrent_mark()) {
+    return predict_object_copy_time_ms_during_cm(bytes_to_copy);
+  } else {
+    return bytes_to_copy * get_new_prediction(_cost_per_byte_ms_seq);
+  }
+}
+
+double G1CollectorPolicy::predict_constant_other_time_ms() const {
+  return get_new_prediction(_constant_other_time_ms_seq);
+}
+
+double G1CollectorPolicy::predict_young_other_time_ms(size_t young_num) const {
+  return young_num * get_new_prediction(_young_other_cost_per_region_ms_seq);
+}
+
+double G1CollectorPolicy::predict_non_young_other_time_ms(size_t non_young_num) const {
+  return non_young_num * get_new_prediction(_non_young_other_cost_per_region_ms_seq);
+}
+
+double G1CollectorPolicy::predict_remark_time_ms() const {
+  return get_new_prediction(_concurrent_mark_remark_times_ms);
+}
+
+double G1CollectorPolicy::predict_cleanup_time_ms() const {
+  return get_new_prediction(_concurrent_mark_cleanup_times_ms);
+}
+
+double G1CollectorPolicy::predict_yg_surv_rate(int age, SurvRateGroup* surv_rate_group) const {
+  TruncatedSeq* seq = surv_rate_group->get_seq(age);
+  guarantee(seq->num() > 0, "There should be some young gen survivor samples available. Tried to access with age %d", age);
+  double pred = get_new_prediction(seq);
+  if (pred > 1.0) {
+    pred = 1.0;
+  }
+  return pred;
+}
+
+double G1CollectorPolicy::predict_yg_surv_rate(int age) const {
+  return predict_yg_surv_rate(age, _short_lived_surv_rate_group);
+}
+
+double G1CollectorPolicy::accum_yg_surv_rate_pred(int age) const {
+  return _short_lived_surv_rate_group->accum_surv_rate_pred(age);
+}
+
+double G1CollectorPolicy::predict_base_elapsed_time_ms(size_t pending_cards,
+                                                       size_t scanned_cards) const {
   return
     predict_rs_update_time_ms(pending_cards) +
     predict_rs_scan_time_ms(scanned_cards) +
     predict_constant_other_time_ms();
 }
 
-double
-G1CollectorPolicy::predict_base_elapsed_time_ms(size_t pending_cards) const {
+double G1CollectorPolicy::predict_base_elapsed_time_ms(size_t pending_cards) const {
   size_t rs_length = predict_rs_length_diff();
   size_t card_num;
   if (collector_state()->gcs_are_young()) {
@@ -1315,14 +1424,13 @@
     assert(hr->is_young() && hr->age_in_surv_rate_group() != -1, "invariant");
     int age = hr->age_in_surv_rate_group();
     double yg_surv_rate = predict_yg_surv_rate(age, hr->surv_rate_group());
-    bytes_to_copy = (size_t) ((double) hr->used() * yg_surv_rate);
+    bytes_to_copy = (size_t) (hr->used() * yg_surv_rate);
   }
   return bytes_to_copy;
 }
 
-double
-G1CollectorPolicy::predict_region_elapsed_time_ms(HeapRegion* hr,
-                                                  bool for_young_gc) const {
+double G1CollectorPolicy::predict_region_elapsed_time_ms(HeapRegion* hr,
+                                                         bool for_young_gc) const {
   size_t rs_length = hr->rem_set()->occupied();
   size_t card_num;
 
@@ -1349,9 +1457,8 @@
   return region_elapsed_time_ms;
 }
 
-void
-G1CollectorPolicy::init_cset_region_lengths(uint eden_cset_region_length,
-                                            uint survivor_cset_region_length) {
+void G1CollectorPolicy::init_cset_region_lengths(uint eden_cset_region_length,
+                                                 uint survivor_cset_region_length) {
   _eden_cset_region_length     = eden_cset_region_length;
   _survivor_cset_region_length = survivor_cset_region_length;
   _old_cset_region_length      = 0;