< prev index next >

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

Print this page
rev 52675 : 8213890: Implementation of JEP 344: Abortable Mixed Collections for G1
Reviewed-by:
Contributed-by: erik.helin@oracle.com, stefan.johansson@oracle.com
rev 52676 : imported patch AMGC-impl
rev 52677 : imported patch AMGC-tsch-rev1
rev 52678 : imported patch AMGC-tsch-rev1-optcset
rev 52681 : [mq]: AMGC-kbar-rev1

@@ -30,10 +30,11 @@
 #include "utilities/globalDefinitions.hpp"
 
 class G1CollectedHeap;
 class G1CollectorState;
 class G1GCPhaseTimes;
+class G1ParScanThreadStateSet;
 class G1Policy;
 class G1SurvivorRegions;
 class HeapRegion;
 
 class G1CollectionSet {

@@ -54,10 +55,17 @@
   // 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, 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 incremented in finalize_old_part() when adding old regions
   // (if any) to the collection set.
   size_t _bytes_used_before;

@@ -104,19 +112,23 @@
   double _inc_predicted_elapsed_time_ms_diffs;
 
   G1CollectorState* collector_state();
   G1GCPhaseTimes* phase_times();
 
-  double predict_region_elapsed_time_ms(HeapRegion* hr);
-
   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();
+
 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();
 
   CollectionSetChooser* cset_chooser();
 
   void init_region_lengths(uint eden_cset_region_length,
                            uint survivor_cset_region_length);

@@ -129,10 +141,11 @@
                                             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 _optional_region_length; }
 
   // Incremental collection set support
 
   // Initialize incremental collection set info.
   void start_incremental_building();

@@ -173,10 +186,13 @@
   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);
 
   // Add eden region to the collection set.

@@ -189,12 +205,75 @@
   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 cset-chooser and
+  // frees the optional structure in the cset.
+  ~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_VM_GC_G1_G1COLLECTIONSET_HPP
 
< prev index next >