< prev index next >

src/share/vm/gc/g1/g1CollectorPolicy.hpp

Print this page
rev 9277 : imported patch 8140597-forcing-initial-mark-causes-abort-mixed-collections
rev 9279 : imported patch 8138740-start-initial-mark-right-after-mixed-gc-if-needed
rev 9282 : dihop-changes

@@ -38,10 +38,11 @@
 //   * choice of collection set.
 //   * when to collect.
 
 class HeapRegion;
 class CollectionSetChooser;
+class G1IHOPControl;
 
 // TraceYoungGenTime collects data on _both_ young and mixed evacuation pauses
 // (the latter may contain non-young regions - i.e. regions that are
 // technically in old) while TraceOldGenTime collects data about full GCs.
 class TraceYoungGenTimeData : public CHeapObj<mtGC> {

@@ -161,10 +162,19 @@
   }
 };
 
 class G1CollectorPolicy: public CollectorPolicy {
  private:
+  G1IHOPControl* _ihop_control;
+
+  G1IHOPControl* create_ihop_control() const;
+  void update_ihop_statistics(double marking_to_mixed_time,
+                              double mutator_time_s,
+                              size_t mutator_alloc_bytes,
+                              size_t young_gen_size);
+  void report_ihop_statistics();
+
   G1Predictions _predictor;
 
   double get_new_prediction(TruncatedSeq const* seq) const;
 
   // either equal to the number of parallel threads, if ParallelGCThreads

@@ -269,13 +279,71 @@
 
   double _pause_time_target_ms;
 
   size_t _pending_cards;
 
+  // The amount of allocated bytes in old gen during the last mutator and the following
+  // young GC phase.
+  size_t _last_old_allocated_bytes;
+
+  // Used to track time from the end of initial mark to the first mixed GC.
+  class InitialMarkToMixedTimeTracker {
+   private:
+    bool _active;
+    double _initial_mark_end_time;
+    double _mixed_start_time;
+    double _total_pause_time;
+
+    double wall_time() const {
+      return _mixed_start_time - _initial_mark_end_time;
+    }
+   public:
+    InitialMarkToMixedTimeTracker() { reset(); }
+
+    void record_initial_mark_end(double end_time) {
+      assert(!_active, "Initial mark out of order.");
+      _initial_mark_end_time = end_time;
+      _active = true;
+    }
+
+    void record_mixed_gc_start(double start_time) {
+      if (_active) {
+        _mixed_start_time = start_time;
+        _active = false;
+      }
+    }
+
+    double last_marking_time() {
+      assert(has_result(), "Do not have all measurements yet.");
+      double result = (_mixed_start_time - _initial_mark_end_time) - _total_pause_time;
+      reset();
+      return result;
+    }
+
+    void reset() {
+      _active = false;
+      _total_pause_time = 0.0;
+      _initial_mark_end_time = -1.0;
+      _mixed_start_time = -1.0;
+    }
+
+    void add_pause(double time) {
+      if (_active) {
+        _total_pause_time += time;
+      }
+    }
+
+    bool has_result() const { return _mixed_start_time > 0.0 && _initial_mark_end_time > 0.0; }
+  };
+
+  InitialMarkToMixedTimeTracker _initial_mark_to_mixed;
 public:
   G1Predictions& predictor() { return _predictor; }
 
+  // Add the given number of bytes to the total number of allocated bytes in the old gen.
+  void add_last_old_allocated_bytes(size_t bytes) { _last_old_allocated_bytes += bytes; }
+
   // Accessors
 
   void set_region_eden(HeapRegion* hr, int young_index_in_cset) {
     hr->set_eden();
     hr->install_surv_rate_group(_short_lived_surv_rate_group);

@@ -471,20 +539,20 @@
   // determine whether we should initiate a new marking.
   double _cur_mark_stop_world_time_ms;
   double _mark_remark_start_sec;
   double _mark_cleanup_start_sec;
 
-  void update_young_list_max_and_target_length();
-  void update_young_list_max_and_target_length(size_t rs_lengths);
+  void update_young_list_max_and_target_length(size_t* unbounded_target_length = NULL);
+  void update_young_list_max_and_target_length(size_t rs_lengths, size_t* unbounded_target_length = NULL);
 
   // Update the young list target length either by setting it to the
   // desired fixed value or by calculating it using G1's pause
   // prediction model. If no rs_lengths parameter is passed, predict
   // the RS lengths using the prediction model, otherwise use the
   // given rs_lengths as the prediction.
   void update_young_list_target_length();
-  void update_young_list_target_length(size_t rs_lengths);
+  void update_young_list_target_length(size_t rs_lengths, size_t* unbounded_target_length = NULL);
 
   // Calculate and return the minimum desired young list target
   // length. This is the minimum desired young list length according
   // to the user's inputs.
   uint calculate_young_list_desired_min_length(uint base_min_length) const;

@@ -503,11 +571,11 @@
   uint calculate_young_list_target_length(size_t rs_lengths,
                                           uint base_min_length,
                                           uint desired_min_length,
                                           uint desired_max_length) const;
 
-  uint bounded_young_list_target_length(size_t rs_lengths) const;
+  uint bounded_young_list_target_length(size_t rs_lengths, size_t* unbounded_target_length = NULL) const;
 
   void update_rs_lengths_prediction();
   void update_rs_lengths_prediction(size_t prediction);
 
   // Calculate and return chunk size (in number of regions) for parallel

@@ -534,14 +602,34 @@
   // as a percentage of the current heap capacity.
   double reclaimable_bytes_perc(size_t reclaimable_bytes) const;
 
   // Sets up marking if proper conditions are met.
   void maybe_start_marking();
+
+  // The kind of STW pause.
+  enum PauseKind {
+    FullGC,
+    YoungOnlyGC,
+    MixedGC,
+    LastYoungGC,
+    InitialMarkGC,
+    Cleanup,
+    Remark
+  };
+
+  // Calculate PauseKind from internal state.
+  PauseKind young_gc_pause_kind() const;
+  // Record the given STW pause with the given start and end times (in s).
+  void record_pause(PauseKind kind, double start, double end);
+  // Indicate that we aborted marking before doing any mixed GCs.
+  void abort_time_to_mixed_tracking();
 public:
 
   G1CollectorPolicy();
 
+  virtual ~G1CollectorPolicy();
+
   virtual G1CollectorPolicy* as_g1_policy() { return this; }
 
   G1CollectorState* collector_state() const;
 
   G1GCPhaseTimes* phase_times() const { return _phase_times; }
< prev index next >