1 /* 2 * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_GC_G1_G1COLLECTIONSET_HPP 26 #define SHARE_GC_G1_G1COLLECTIONSET_HPP 27 28 #include "gc/g1/g1CollectionSetCandidates.hpp" 29 #include "utilities/debug.hpp" 30 #include "utilities/globalDefinitions.hpp" 31 32 class G1CollectedHeap; 33 class G1CollectorState; 34 class G1GCPhaseTimes; 35 class G1ParScanThreadStateSet; 36 class G1Policy; 37 class G1SurvivorRegions; 38 class HeapRegion; 39 40 class G1CollectionSet { 41 G1CollectedHeap* _g1h; 42 G1Policy* _policy; 43 44 // All old gen collection set candidate regions for the current mixed gc phase. 45 G1CollectionSetCandidates* _candidates; 46 47 uint _eden_region_length; 48 uint _survivor_region_length; 49 uint _old_region_length; 50 51 // The actual collection set as a set of region indices. 52 // All entries in _collection_set_regions below _collection_set_cur_length are 53 // assumed to be valid entries. 54 // We assume that at any time there is at most only one writer and (one or more) 55 // concurrent readers. This means we are good with using storestore and loadload 56 // barriers on the writer and reader respectively only. 57 uint* _collection_set_regions; 58 volatile size_t _collection_set_cur_length; 59 size_t _collection_set_max_length; 60 61 // When doing mixed collections we can add old regions to the collection, which 62 // can be collected if there is enough time. We call these optional regions and 63 // the pointer to these regions are stored in the array below. 64 HeapRegion** _optional_regions; 65 uint _optional_region_length; 66 uint _optional_region_max_length; 67 68 // The number of bytes in the collection set before the pause. Set from 69 // the incrementally built collection set at the start of an evacuation 70 // pause, and incremented in finalize_old_part() when adding old regions 71 // (if any) to the collection set. 72 size_t _bytes_used_before; 73 74 size_t _recorded_rs_lengths; 75 76 // The associated information that is maintained while the incremental 77 // collection set is being built with young regions. Used to populate 78 // the recorded info for the evacuation pause. 79 80 enum CSetBuildType { 81 Active, // We are actively building the collection set 82 Inactive // We are not actively building the collection set 83 }; 84 85 CSetBuildType _inc_build_state; 86 87 // The number of bytes in the incrementally built collection set. 88 // Used to set _collection_set_bytes_used_before at the start of 89 // an evacuation pause. 90 size_t _inc_bytes_used_before; 91 92 // The RSet lengths recorded for regions in the CSet. It is updated 93 // by the thread that adds a new region to the CSet. We assume that 94 // only one thread can be allocating a new CSet region (currently, 95 // it does so after taking the Heap_lock) hence no need to 96 // synchronize updates to this field. 97 size_t _inc_recorded_rs_lengths; 98 99 // A concurrent refinement thread periodically samples the young 100 // region RSets and needs to update _inc_recorded_rs_lengths as 101 // the RSets grow. Instead of having to synchronize updates to that 102 // field we accumulate them in this field and add it to 103 // _inc_recorded_rs_lengths_diffs at the start of a GC. 104 ssize_t _inc_recorded_rs_lengths_diffs; 105 106 // The predicted elapsed time it will take to collect the regions in 107 // the CSet. This is updated by the thread that adds a new region to 108 // the CSet. See the comment for _inc_recorded_rs_lengths about 109 // MT-safety assumptions. 110 double _inc_predicted_elapsed_time_ms; 111 112 // See the comment for _inc_recorded_rs_lengths_diffs. 113 double _inc_predicted_elapsed_time_ms_diffs; 114 115 G1CollectorState* collector_state(); 116 G1GCPhaseTimes* phase_times(); 117 118 void verify_young_cset_indices() const NOT_DEBUG_RETURN; 119 void add_as_optional(HeapRegion* hr); 120 void add_as_old(HeapRegion* hr); 121 bool optional_is_full(); 122 123 public: 124 G1CollectionSet(G1CollectedHeap* g1h, G1Policy* policy); 125 ~G1CollectionSet(); 126 127 // Initializes the collection set giving the maximum possible length of the collection set. 128 void initialize(uint max_region_length); 129 void initialize_optional(uint max_length); 130 void free_optional_regions(); 131 132 void clear_candidates() { 133 delete _candidates; 134 _candidates = NULL; 135 } 136 void set_candidates(G1CollectionSetCandidates* candidates) { 137 assert(_candidates == NULL, "Trying to replace collection set candidates."); 138 _candidates = candidates; 139 } 140 G1CollectionSetCandidates* candidates() { return _candidates; } 141 142 void init_region_lengths(uint eden_cset_region_length, 143 uint survivor_cset_region_length); 144 145 void set_recorded_rs_lengths(size_t rs_lengths); 146 147 uint region_length() const { return young_region_length() + 148 old_region_length(); } 149 uint young_region_length() const { return eden_region_length() + 150 survivor_region_length(); } 151 152 uint eden_region_length() const { return _eden_region_length; } 153 uint survivor_region_length() const { return _survivor_region_length; } 154 uint old_region_length() const { return _old_region_length; } 155 uint optional_region_length() const { return _optional_region_length; } 156 157 // Incremental collection set support 158 159 // Initialize incremental collection set info. 160 void start_incremental_building(); 161 162 // Perform any final calculations on the incremental collection set fields 163 // before we can use them. 164 void finalize_incremental_building(); 165 166 // Reset the contents of the collection set. 167 void clear(); 168 169 // Iterate over the collection set, applying the given HeapRegionClosure on all of them. 170 // If may_be_aborted is true, iteration may be aborted using the return value of the 171 // called closure method. 172 void iterate(HeapRegionClosure* cl) const; 173 174 // Iterate over the collection set, applying the given HeapRegionClosure on all of them, 175 // trying to optimally spread out starting position of total_workers workers given the 176 // caller's worker_id. 177 void iterate_from(HeapRegionClosure* cl, uint worker_id, uint total_workers) const; 178 179 // Stop adding regions to the incremental collection set. 180 void stop_incremental_building() { _inc_build_state = Inactive; } 181 182 size_t recorded_rs_lengths() { return _recorded_rs_lengths; } 183 184 size_t bytes_used_before() const { 185 return _bytes_used_before; 186 } 187 188 void reset_bytes_used_before() { 189 _bytes_used_before = 0; 190 } 191 192 // Choose a new collection set. Marks the chosen regions as being 193 // "in_collection_set". 194 double finalize_young_part(double target_pause_time_ms, G1SurvivorRegions* survivors); 195 void finalize_old_part(double time_remaining_ms); 196 197 // Add old region "hr" to the collection set. 198 void add_old_region(HeapRegion* hr); 199 200 // Add old region "hr" to optional collection set. 201 void add_optional_region(HeapRegion* hr); 202 203 // Update information about hr in the aggregated information for 204 // the incrementally built collection set. 205 void update_young_region_prediction(HeapRegion* hr, size_t new_rs_length); 206 207 // Add eden region to the collection set. 208 void add_eden_region(HeapRegion* hr); 209 210 // Add survivor region to the collection set. 211 void add_survivor_regions(HeapRegion* hr); 212 213 #ifndef PRODUCT 214 bool verify_young_ages(); 215 216 void print(outputStream* st); 217 #endif // !PRODUCT 218 219 double predict_region_elapsed_time_ms(HeapRegion* hr); 220 221 void clear_optional_region(const HeapRegion* hr); 222 223 HeapRegion* optional_region_at(uint i) const { 224 assert(_optional_regions != NULL, "Not yet initialized"); 225 assert(i < _optional_region_length, "index %u out of bounds (%u)", i, _optional_region_length); 226 return _optional_regions[i]; 227 } 228 229 HeapRegion* remove_last_optional_region() { 230 assert(_optional_regions != NULL, "Not yet initialized"); 231 assert(_optional_region_length != 0, "No region to remove"); 232 _optional_region_length--; 233 HeapRegion* removed = _optional_regions[_optional_region_length]; 234 _optional_regions[_optional_region_length] = NULL; 235 return removed; 236 } 237 238 private: 239 // Update the incremental collection set information when adding a region. 240 void add_young_region_common(HeapRegion* hr); 241 }; 242 243 // Helper class to manage the optional regions in a Mixed collection. 244 class G1OptionalCSet : public StackObj { 245 private: 246 G1CollectionSet* _cset; 247 G1ParScanThreadStateSet* _pset; 248 uint _current_index; 249 uint _current_limit; 250 bool _prepare_failed; 251 bool _evacuation_failed; 252 253 void prepare_to_evacuate_optional_region(HeapRegion* hr); 254 255 public: 256 static const uint InvalidCSetIndex = UINT_MAX; 257 258 G1OptionalCSet(G1CollectionSet* cset, G1ParScanThreadStateSet* pset) : 259 _cset(cset), 260 _pset(pset), 261 _current_index(0), 262 _current_limit(0), 263 _prepare_failed(false), 264 _evacuation_failed(false) { } 265 // The destructor returns regions to the collection set candidates set and 266 // frees the optional structure in the collection set. 267 ~G1OptionalCSet(); 268 269 uint current_index() { return _current_index; } 270 uint current_limit() { return _current_limit; } 271 272 uint size(); 273 bool is_empty(); 274 275 HeapRegion* region_at(uint index); 276 277 // Prepare a set of regions for optional evacuation. 278 void prepare_evacuation(double time_left_ms); 279 bool prepare_failed(); 280 281 // Complete the evacuation of the previously prepared 282 // regions by updating their state and check for failures. 283 void complete_evacuation(); 284 bool evacuation_failed(); 285 }; 286 287 #endif // SHARE_GC_G1_G1COLLECTIONSET_HPP