--- old/src/hotspot/share/gc/g1/g1CollectionSet.hpp 2018-11-27 18:22:06.122790590 +0100 +++ new/src/hotspot/share/gc/g1/g1CollectionSet.hpp 2018-11-27 18:22:05.698788488 +0100 @@ -32,6 +32,7 @@ class G1CollectedHeap; class G1CollectorState; class G1GCPhaseTimes; +class G1ParScanThreadStateSet; class G1Policy; class G1SurvivorRegions; class HeapRegion; @@ -56,6 +57,13 @@ 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 @@ -106,15 +114,19 @@ 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(); @@ -131,6 +143,7 @@ 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 @@ -175,6 +188,9 @@ // 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); @@ -191,10 +207,73 @@ 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