< prev index next >

src/hotspot/share/gc/g1/g1CollectionSet.hpp

Print this page

        

@@ -36,148 +36,56 @@
 class G1Policy;
 class G1SurvivorRegions;
 class HeapRegion;
 class HeapRegionClosure;
 
-// The collection set.
-//
-// The set of regions that are evacuated during an evacuation pause.
-//
-// At the end of a collection, before freeing the collection set, this set
-// contains all regions that were evacuated during this collection:
-//
-// - survivor regions from the last collection (if any)
-// - eden regions allocated by the mutator
-// - old gen regions evacuated during mixed gc
-//
-// This set is built incrementally at mutator time as regions are retired, and
-// if this had been a mixed gc, some additional (during gc) incrementally added
-// old regions from the collection set candidates built during the concurrent
-// cycle.
-//
-// A more detailed overview of how the collection set changes over time follows:
-//
-// 0) at the end of GC the survivor regions are added to this collection set.
-// 1) the mutator incrementally adds eden regions as they retire
-//
-// ----- gc starts
-//
-// 2) prepare (finalize) young regions of the collection set for collection
-//    - relabel the survivors as eden
-//    - finish up the incremental building that happened at mutator time
-//
-// iff this is a young-only collection:
-//
-// a3) evacuate the current collection set in one "initial evacuation" phase
-//
-// iff this is a mixed collection:
-//
-// b3) calculate the set of old gen regions we may be able to collect in this
-//     collection from the list of collection set candidates.
-//     - one part is added to the current collection set
-//     - the remainder regions are labeled as optional, and NOT yet added to the
-//     collection set.
-// b4) evacuate the current collection set in the "initial evacuation" phase
-// b5) evacuate the optional regions in the "optional evacuation" phase. This is
-//     done in increments (or rounds).
-//     b5-1) add a few of the optional regions to the current collection set
-//     b5-2) evacuate only these newly added optional regions. For this mechanism we
-//     reuse the incremental collection set building infrastructure (used also at
-//     mutator time).
-//     b5-3) repeat from b5-1 until the policy determines we are done
-//
-// all collections
-//
-// 6) free the collection set (contains all regions now; empties collection set
-//    afterwards)
-// 7) add survivors to this collection set
-//
-// ----- gc ends
-//
-// goto 1)
-//
-// Examples of how the collection set might look over time:
-//
-// Legend:
-// S = survivor, E = eden, O = old.
-// |xxxx| = increment (with increment markers), containing four regions
-//
-// |SSSS|                         ... after step 0), with four survivor regions
-// |SSSSEE|                       ... at step 1), after retiring two eden regions
-// |SSSSEEEE|                     ... after step 1), after retiring four eden regions
-// |EEEEEEEE|                     ... after step 2)
-//
-// iff this is a young-only collection
-//
-// EEEEEEEE||                      ... after step a3), after initial evacuation phase
-// ||                              ... after step 6)
-// |SS|                            ... after step 7), with two survivor regions
-//
-// iff this is a mixed collection
-//
-// |EEEEEEEEOOOO|                  ... after step b3), added four regions to be
-//                                     evacuated in the "initial evacuation" phase
-// EEEEEEEEOOOO||                  ... after step b4), incremental part is empty
-//                                     after evacuation
-// EEEEEEEEOOOO|OO|                ... after step b5.1), added two regions to be
-//                                     evacuated in the first round of the
-//                                     "optional evacuation" phase
-// EEEEEEEEOOOOOO|O|               ... after step b5.1), added one region to be
-//                                     evacuated in the second round of the
-//                                     "optional evacuation" phase
-// EEEEEEEEOOOOOOO||               ... after step b5), the complete collection set.
-// ||                              ... after step b6)
-// |SSS|                           ... after step 7), with three survivor regions
-//
 class G1CollectionSet {
   G1CollectedHeap* _g1h;
   G1Policy* _policy;
 
-  // All old gen collection set candidate regions for the current mixed phase.
+  // All old gen collection set candidate regions for the current mixed gc phase.
   G1CollectionSetCandidates* _candidates;
 
   uint _eden_region_length;
   uint _survivor_region_length;
   uint _old_region_length;
 
   // The actual collection set as a set of region indices.
   // All entries in _collection_set_regions below _collection_set_cur_length are
-  // assumed to be part of the collection set.
+  // assumed to be valid entries.
   // We assume that at any time there is at most only one writer and (one or more)
   // concurrent readers. This means we are good with using storestore and loadload
   // barriers on the writer and reader respectively only.
   uint* _collection_set_regions;
   volatile size_t _collection_set_cur_length;
   size_t _collection_set_max_length;
 
-  // When doing mixed collections we can add old regions to the collection set, which
-  // will be collected only if there is enough time. We call these optional regions.
-  // This member records the current number of regions that are of that type that
-  // correspond to the first x entries in the collection set candidates.
-  uint _num_optional_regions;
+  // When doing mixed collections we can add old regions to the collection, which
+  // can be collected if there is enough time. We call these optional regions and
+  // the pointer to these regions are stored in the array below.
+  HeapRegion** _optional_regions;
+  uint _optional_region_length;
+  uint _optional_region_max_length;
 
   // The number of bytes in the collection set before the pause. Set from
   // the incrementally built collection set at the start of an evacuation
-  // pause, and updated as more regions are added to the collection set.
+  // pause, and incremented in finalize_old_part() when adding old regions
+  // (if any) to the collection set.
   size_t _bytes_used_before;
 
-  // The number of cards in the remembered set in the collection set. Set from
-  // the incrementally built collection set at the start of an evacuation
-  // pause, and updated as more regions are added to the collection set.
   size_t _recorded_rs_lengths;
 
+  // The associated information that is maintained while the incremental
+  // collection set is being built with young regions. Used to populate
+  // the recorded info for the evacuation pause.
+
   enum CSetBuildType {
     Active,             // We are actively building the collection set
     Inactive            // We are not actively building the collection set
   };
 
   CSetBuildType _inc_build_state;
-  size_t _inc_part_start;
-
-  // The associated information that is maintained while the incremental
-  // collection set is being built with *young* regions. Used to populate
-  // the recorded info for the evacuation pause.
 
   // The number of bytes in the incrementally built collection set.
   // Used to set _collection_set_bytes_used_before at the start of
   // an evacuation pause.
   size_t _inc_bytes_used_before;

@@ -203,48 +111,26 @@
   double _inc_predicted_elapsed_time_ms;
 
   // See the comment for _inc_recorded_rs_lengths_diffs.
   double _inc_predicted_elapsed_time_ms_diffs;
 
-  void set_recorded_rs_lengths(size_t rs_lengths);
-
   G1CollectorState* collector_state();
   G1GCPhaseTimes* phase_times();
 
   void verify_young_cset_indices() const NOT_DEBUG_RETURN;
+  void add_as_optional(HeapRegion* hr);
+  void add_as_old(HeapRegion* hr);
+  bool optional_is_full();
 
-  double predict_region_elapsed_time_ms(HeapRegion* hr);
-
-  // Update the incremental collection set information when adding a region.
-  void add_young_region_common(HeapRegion* hr);
-
-  // Add old region "hr" to the collection set.
-  void add_old_region(HeapRegion* hr);
-  void free_optional_regions();
-
-  // Add old region "hr" to optional collection set.
-  void add_optional_region(HeapRegion* hr);
-
-  void move_candidates_to_collection_set(uint num_regions);
-
-  // Finalize the young part of the initial collection set. Relabel survivor regions
-  // as Eden and calculate a prediction on how long the evacuation of all young regions
-  // will take.
-  double finalize_young_part(double target_pause_time_ms, G1SurvivorRegions* survivors);
-  // Perform any final calculations on the incremental collection set fields before we
-  // can use them.
-  void finalize_incremental_building();
-
-  // Select the old regions of the initial collection set and determine how many optional
-  // regions we might be able to evacuate in this pause.
-  void finalize_old_part(double time_remaining_ms);
 public:
   G1CollectionSet(G1CollectedHeap* g1h, G1Policy* policy);
   ~G1CollectionSet();
 
   // Initializes the collection set giving the maximum possible length of the collection set.
   void initialize(uint max_region_length);
+  void initialize_optional(uint max_length);
+  void free_optional_regions();
 
   void clear_candidates();
 
   void set_candidates(G1CollectionSetCandidates* candidates) {
     assert(_candidates == NULL, "Trying to replace collection set candidates.");

@@ -253,41 +139,46 @@
   G1CollectionSetCandidates* candidates() { return _candidates; }
 
   void init_region_lengths(uint eden_cset_region_length,
                            uint survivor_cset_region_length);
 
+  void set_recorded_rs_lengths(size_t rs_lengths);
+
   uint region_length() const       { return young_region_length() +
                                             old_region_length(); }
   uint young_region_length() const { return eden_region_length() +
                                             survivor_region_length(); }
 
   uint eden_region_length() const     { return _eden_region_length;     }
   uint survivor_region_length() const { return _survivor_region_length; }
   uint old_region_length() const      { return _old_region_length;      }
-  uint optional_region_length() const { return _num_optional_regions; }
-
-  // Reset the contents of the collection set.
-  void clear();
+  uint optional_region_length() const { return _optional_region_length; }
 
   // Incremental collection set support
 
   // Initialize incremental collection set info.
   void start_incremental_building();
-  // Start a new collection set increment.
-  void update_incremental_marker() { _inc_build_state = Active; _inc_part_start = _collection_set_cur_length; }
-  // Stop adding regions to the current collection set increment.
-  void stop_incremental_building() { _inc_build_state = Inactive; }
 
-  // Iterate over the current collection set increment applying the given HeapRegionClosure
-  // from a starting position determined by the given worker id.
-  void iterate_incremental_part_from(HeapRegionClosure* cl, uint worker_id, uint total_workers) const;
+  // Perform any final calculations on the incremental collection set fields
+  // before we can use them.
+  void finalize_incremental_building();
+
+  // Reset the contents of the collection set.
+  void clear();
 
-  // Iterate over the entire collection set (all increments calculated so far), applying
-  // the given HeapRegionClosure on all of them.
+  // Iterate over the collection set, applying the given HeapRegionClosure on all of them.
+  // If may_be_aborted is true, iteration may be aborted using the return value of the
+  // called closure method.
   void iterate(HeapRegionClosure* cl) const;
 
-  void iterate_optional(HeapRegionClosure* cl) const;
+  // Iterate over the collection set, applying the given HeapRegionClosure on all of them,
+  // trying to optimally spread out starting position of total_workers workers given the
+  // caller's worker_id.
+  void iterate_from(HeapRegionClosure* cl, uint worker_id, uint total_workers) const;
+
+  // Stop adding regions to the incremental collection set.
+  void stop_incremental_building() { _inc_build_state = Inactive; }
 
   size_t recorded_rs_lengths() { return _recorded_rs_lengths; }
 
   size_t bytes_used_before() const {
     return _bytes_used_before;

@@ -295,18 +186,20 @@
 
   void reset_bytes_used_before() {
     _bytes_used_before = 0;
   }
 
-  // Finalize the initial collection set consisting of all young regions potentially a
-  // few old gen regions.
-  void finalize_initial_collection_set(double target_pause_time_ms, G1SurvivorRegions* survivor);
-  // Finalize the next collection set from the set of available optional old gen regions.
-  bool finalize_optional_for_evacuation(double remaining_pause_time);
-  // Abandon (clean up) optional collection set regions that were not evacuated in this
-  // pause.
-  void abandon_optional_collection_set(G1ParScanThreadStateSet* pss);
+  // Choose a new collection set.  Marks the chosen regions as being
+  // "in_collection_set".
+  double finalize_young_part(double target_pause_time_ms, G1SurvivorRegions* survivors);
+  void finalize_old_part(double time_remaining_ms);
+
+  // Add old region "hr" to the collection set.
+  void add_old_region(HeapRegion* hr);
+
+  // Add old region "hr" to optional collection set.
+  void add_optional_region(HeapRegion* hr);
 
   // Update information about hr in the aggregated information for
   // the incrementally built collection set.
   void update_young_region_prediction(HeapRegion* hr, size_t new_rs_length);
 

@@ -319,8 +212,75 @@
 #ifndef PRODUCT
   bool verify_young_ages();
 
   void print(outputStream* st);
 #endif // !PRODUCT
+
+  double predict_region_elapsed_time_ms(HeapRegion* hr);
+
+  void clear_optional_region(const HeapRegion* hr);
+
+  HeapRegion* optional_region_at(uint i) const {
+    assert(_optional_regions != NULL, "Not yet initialized");
+    assert(i < _optional_region_length, "index %u out of bounds (%u)", i, _optional_region_length);
+    return _optional_regions[i];
+  }
+
+  HeapRegion* remove_last_optional_region() {
+    assert(_optional_regions != NULL, "Not yet initialized");
+    assert(_optional_region_length != 0, "No region to remove");
+    _optional_region_length--;
+    HeapRegion* removed = _optional_regions[_optional_region_length];
+    _optional_regions[_optional_region_length] = NULL;
+    return removed;
+  }
+
+private:
+  // Update the incremental collection set information when adding a region.
+  void add_young_region_common(HeapRegion* hr);
+};
+
+// Helper class to manage the optional regions in a Mixed collection.
+class G1OptionalCSet : public StackObj {
+private:
+  G1CollectionSet* _cset;
+  G1ParScanThreadStateSet* _pset;
+  uint _current_index;
+  uint _current_limit;
+  bool _prepare_failed;
+  bool _evacuation_failed;
+
+  void prepare_to_evacuate_optional_region(HeapRegion* hr);
+
+public:
+  static const uint InvalidCSetIndex = UINT_MAX;
+
+  G1OptionalCSet(G1CollectionSet* cset, G1ParScanThreadStateSet* pset) :
+    _cset(cset),
+    _pset(pset),
+    _current_index(0),
+    _current_limit(0),
+    _prepare_failed(false),
+    _evacuation_failed(false) { }
+  // The destructor returns regions to the collection set candidates set and
+  // frees the optional structure in the collection set.
+  ~G1OptionalCSet();
+
+  uint current_index() { return _current_index; }
+  uint current_limit() { return _current_limit; }
+
+  uint size();
+  bool is_empty();
+
+  HeapRegion* region_at(uint index);
+
+  // Prepare a set of regions for optional evacuation.
+  void prepare_evacuation(double time_left_ms);
+  bool prepare_failed();
+
+  // Complete the evacuation of the previously prepared
+  // regions by updating their state and check for failures.
+  void complete_evacuation();
+  bool evacuation_failed();
 };
 
 #endif // SHARE_GC_G1_G1COLLECTIONSET_HPP
< prev index next >