| 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 "utilities/debug.hpp" | 
|---|
| 29 | #include "utilities/globalDefinitions.hpp" | 
|---|
| 30 |  | 
|---|
| 31 | class G1CollectedHeap; | 
|---|
| 32 | class G1CollectionSetCandidates; | 
|---|
| 33 | class G1CollectorState; | 
|---|
| 34 | class G1GCPhaseTimes; | 
|---|
| 35 | class G1ParScanThreadStateSet; | 
|---|
| 36 | class G1Policy; | 
|---|
| 37 | class G1SurvivorRegions; | 
|---|
| 38 | class HeapRegion; | 
|---|
| 39 | class HeapRegionClosure; | 
|---|
| 40 |  | 
|---|
| 41 | // The collection set. | 
|---|
| 42 | // | 
|---|
| 43 | // The set of regions that are evacuated during an evacuation pause. | 
|---|
| 44 | // | 
|---|
| 45 | // At the end of a collection, before freeing the collection set, this set | 
|---|
| 46 | // contains all regions that were evacuated during this collection: | 
|---|
| 47 | // | 
|---|
| 48 | // - survivor regions from the last collection (if any) | 
|---|
| 49 | // - eden regions allocated by the mutator | 
|---|
| 50 | // - old gen regions evacuated during mixed gc | 
|---|
| 51 | // | 
|---|
| 52 | // This set is built incrementally at mutator time as regions are retired, and | 
|---|
| 53 | // if this had been a mixed gc, some additional (during gc) incrementally added | 
|---|
| 54 | // old regions from the collection set candidates built during the concurrent | 
|---|
| 55 | // cycle. | 
|---|
| 56 | // | 
|---|
| 57 | // A more detailed overview of how the collection set changes over time follows: | 
|---|
| 58 | // | 
|---|
| 59 | // 0) at the end of GC the survivor regions are added to this collection set. | 
|---|
| 60 | // 1) the mutator incrementally adds eden regions as they retire | 
|---|
| 61 | // | 
|---|
| 62 | // ----- gc starts | 
|---|
| 63 | // | 
|---|
| 64 | // 2) prepare (finalize) young regions of the collection set for collection | 
|---|
| 65 | //    - relabel the survivors as eden | 
|---|
| 66 | //    - finish up the incremental building that happened at mutator time | 
|---|
| 67 | // | 
|---|
| 68 | // iff this is a young-only collection: | 
|---|
| 69 | // | 
|---|
| 70 | // a3) evacuate the current collection set in one "initial evacuation" phase | 
|---|
| 71 | // | 
|---|
| 72 | // iff this is a mixed collection: | 
|---|
| 73 | // | 
|---|
| 74 | // b3) calculate the set of old gen regions we may be able to collect in this | 
|---|
| 75 | //     collection from the list of collection set candidates. | 
|---|
| 76 | //     - one part is added to the current collection set | 
|---|
| 77 | //     - the remainder regions are labeled as optional, and NOT yet added to the | 
|---|
| 78 | //     collection set. | 
|---|
| 79 | // b4) evacuate the current collection set in the "initial evacuation" phase | 
|---|
| 80 | // b5) evacuate the optional regions in the "optional evacuation" phase. This is | 
|---|
| 81 | //     done in increments (or rounds). | 
|---|
| 82 | //     b5-1) add a few of the optional regions to the current collection set | 
|---|
| 83 | //     b5-2) evacuate only these newly added optional regions. For this mechanism we | 
|---|
| 84 | //     reuse the incremental collection set building infrastructure (used also at | 
|---|
| 85 | //     mutator time). | 
|---|
| 86 | //     b5-3) repeat from b5-1 until the policy determines we are done | 
|---|
| 87 | // | 
|---|
| 88 | // all collections | 
|---|
| 89 | // | 
|---|
| 90 | // 6) free the collection set (contains all regions now; empties collection set | 
|---|
| 91 | //    afterwards) | 
|---|
| 92 | // 7) add survivors to this collection set | 
|---|
| 93 | // | 
|---|
| 94 | // ----- gc ends | 
|---|
| 95 | // | 
|---|
| 96 | // goto 1) | 
|---|
| 97 | // | 
|---|
| 98 | // Examples of how the collection set might look over time: | 
|---|
| 99 | // | 
|---|
| 100 | // Legend: | 
|---|
| 101 | // S = survivor, E = eden, O = old. | 
|---|
| 102 | // |xxxx| = increment (with increment markers), containing four regions | 
|---|
| 103 | // | 
|---|
| 104 | // |SSSS|                         ... after step 0), with four survivor regions | 
|---|
| 105 | // |SSSSEE|                       ... at step 1), after retiring two eden regions | 
|---|
| 106 | // |SSSSEEEE|                     ... after step 1), after retiring four eden regions | 
|---|
| 107 | // |EEEEEEEE|                     ... after step 2) | 
|---|
| 108 | // | 
|---|
| 109 | // iff this is a young-only collection | 
|---|
| 110 | // | 
|---|
| 111 | // EEEEEEEE||                      ... after step a3), after initial evacuation phase | 
|---|
| 112 | // ||                              ... after step 6) | 
|---|
| 113 | // |SS|                            ... after step 7), with two survivor regions | 
|---|
| 114 | // | 
|---|
| 115 | // iff this is a mixed collection | 
|---|
| 116 | // | 
|---|
| 117 | // |EEEEEEEEOOOO|                  ... after step b3), added four regions to be | 
|---|
| 118 | //                                     evacuated in the "initial evacuation" phase | 
|---|
| 119 | // EEEEEEEEOOOO||                  ... after step b4), incremental part is empty | 
|---|
| 120 | //                                     after evacuation | 
|---|
| 121 | // EEEEEEEEOOOO|OO|                ... after step b5.1), added two regions to be | 
|---|
| 122 | //                                     evacuated in the first round of the | 
|---|
| 123 | //                                     "optional evacuation" phase | 
|---|
| 124 | // EEEEEEEEOOOOOO|O|               ... after step b5.1), added one region to be | 
|---|
| 125 | //                                     evacuated in the second round of the | 
|---|
| 126 | //                                     "optional evacuation" phase | 
|---|
| 127 | // EEEEEEEEOOOOOOO||               ... after step b5), the complete collection set. | 
|---|
| 128 | // ||                              ... after step b6) | 
|---|
| 129 | // |SSS|                           ... after step 7), with three survivor regions | 
|---|
| 130 | // | 
|---|
| 131 | class G1CollectionSet { | 
|---|
| 132 | G1CollectedHeap* _g1h; | 
|---|
| 133 | G1Policy* _policy; | 
|---|
| 134 |  | 
|---|
| 135 | // All old gen collection set candidate regions for the current mixed phase. | 
|---|
| 136 | G1CollectionSetCandidates* _candidates; | 
|---|
| 137 |  | 
|---|
| 138 | uint _eden_region_length; | 
|---|
| 139 | uint _survivor_region_length; | 
|---|
| 140 | uint _old_region_length; | 
|---|
| 141 |  | 
|---|
| 142 | // The actual collection set as a set of region indices. | 
|---|
| 143 | // All entries in _collection_set_regions below _collection_set_cur_length are | 
|---|
| 144 | // assumed to be part of the collection set. | 
|---|
| 145 | // We assume that at any time there is at most only one writer and (one or more) | 
|---|
| 146 | // concurrent readers. This means we are good with using storestore and loadload | 
|---|
| 147 | // barriers on the writer and reader respectively only. | 
|---|
| 148 | uint* _collection_set_regions; | 
|---|
| 149 | volatile size_t _collection_set_cur_length; | 
|---|
| 150 | size_t _collection_set_max_length; | 
|---|
| 151 |  | 
|---|
| 152 | // When doing mixed collections we can add old regions to the collection set, which | 
|---|
| 153 | // will be collected only if there is enough time. We call these optional regions. | 
|---|
| 154 | // This member records the current number of regions that are of that type that | 
|---|
| 155 | // correspond to the first x entries in the collection set candidates. | 
|---|
| 156 | uint _num_optional_regions; | 
|---|
| 157 |  | 
|---|
| 158 | // The number of bytes in the collection set before the pause. Set from | 
|---|
| 159 | // the incrementally built collection set at the start of an evacuation | 
|---|
| 160 | // pause, and updated as more regions are added to the collection set. | 
|---|
| 161 | size_t _bytes_used_before; | 
|---|
| 162 |  | 
|---|
| 163 | // The number of cards in the remembered set in the collection set. Set from | 
|---|
| 164 | // the incrementally built collection set at the start of an evacuation | 
|---|
| 165 | // pause, and updated as more regions are added to the collection set. | 
|---|
| 166 | size_t _recorded_rs_lengths; | 
|---|
| 167 |  | 
|---|
| 168 | enum CSetBuildType { | 
|---|
| 169 | Active,             // We are actively building the collection set | 
|---|
| 170 | Inactive            // We are not actively building the collection set | 
|---|
| 171 | }; | 
|---|
| 172 |  | 
|---|
| 173 | CSetBuildType _inc_build_state; | 
|---|
| 174 | size_t _inc_part_start; | 
|---|
| 175 |  | 
|---|
| 176 | // The associated information that is maintained while the incremental | 
|---|
| 177 | // collection set is being built with *young* regions. Used to populate | 
|---|
| 178 | // the recorded info for the evacuation pause. | 
|---|
| 179 |  | 
|---|
| 180 | // The number of bytes in the incrementally built collection set. | 
|---|
| 181 | // Used to set _collection_set_bytes_used_before at the start of | 
|---|
| 182 | // an evacuation pause. | 
|---|
| 183 | size_t _inc_bytes_used_before; | 
|---|
| 184 |  | 
|---|
| 185 | // The RSet lengths recorded for regions in the CSet. It is updated | 
|---|
| 186 | // by the thread that adds a new region to the CSet. We assume that | 
|---|
| 187 | // only one thread can be allocating a new CSet region (currently, | 
|---|
| 188 | // it does so after taking the Heap_lock) hence no need to | 
|---|
| 189 | // synchronize updates to this field. | 
|---|
| 190 | size_t _inc_recorded_rs_lengths; | 
|---|
| 191 |  | 
|---|
| 192 | // A concurrent refinement thread periodically samples the young | 
|---|
| 193 | // region RSets and needs to update _inc_recorded_rs_lengths as | 
|---|
| 194 | // the RSets grow. Instead of having to synchronize updates to that | 
|---|
| 195 | // field we accumulate them in this field and add it to | 
|---|
| 196 | // _inc_recorded_rs_lengths_diffs at the start of a GC. | 
|---|
| 197 | ssize_t _inc_recorded_rs_lengths_diffs; | 
|---|
| 198 |  | 
|---|
| 199 | // The predicted elapsed time it will take to collect the regions in | 
|---|
| 200 | // the CSet. This is updated by the thread that adds a new region to | 
|---|
| 201 | // the CSet. See the comment for _inc_recorded_rs_lengths about | 
|---|
| 202 | // MT-safety assumptions. | 
|---|
| 203 | double _inc_predicted_elapsed_time_ms; | 
|---|
| 204 |  | 
|---|
| 205 | // See the comment for _inc_recorded_rs_lengths_diffs. | 
|---|
| 206 | double _inc_predicted_elapsed_time_ms_diffs; | 
|---|
| 207 |  | 
|---|
| 208 | void set_recorded_rs_lengths(size_t rs_lengths); | 
|---|
| 209 |  | 
|---|
| 210 | G1CollectorState* collector_state(); | 
|---|
| 211 | G1GCPhaseTimes* phase_times(); | 
|---|
| 212 |  | 
|---|
| 213 | void verify_young_cset_indices() const NOT_DEBUG_RETURN; | 
|---|
| 214 |  | 
|---|
| 215 | double predict_region_elapsed_time_ms(HeapRegion* hr); | 
|---|
| 216 |  | 
|---|
| 217 | // Update the incremental collection set information when adding a region. | 
|---|
| 218 | void add_young_region_common(HeapRegion* hr); | 
|---|
| 219 |  | 
|---|
| 220 | // Add old region "hr" to the collection set. | 
|---|
| 221 | void add_old_region(HeapRegion* hr); | 
|---|
| 222 | void free_optional_regions(); | 
|---|
| 223 |  | 
|---|
| 224 | // Add old region "hr" to optional collection set. | 
|---|
| 225 | void add_optional_region(HeapRegion* hr); | 
|---|
| 226 |  | 
|---|
| 227 | void move_candidates_to_collection_set(uint num_regions); | 
|---|
| 228 |  | 
|---|
| 229 | // Finalize the young part of the initial collection set. Relabel survivor regions | 
|---|
| 230 | // as Eden and calculate a prediction on how long the evacuation of all young regions | 
|---|
| 231 | // will take. | 
|---|
| 232 | double finalize_young_part(double target_pause_time_ms, G1SurvivorRegions* survivors); | 
|---|
| 233 | // Perform any final calculations on the incremental collection set fields before we | 
|---|
| 234 | // can use them. | 
|---|
| 235 | void finalize_incremental_building(); | 
|---|
| 236 |  | 
|---|
| 237 | // Select the old regions of the initial collection set and determine how many optional | 
|---|
| 238 | // regions we might be able to evacuate in this pause. | 
|---|
| 239 | void finalize_old_part(double time_remaining_ms); | 
|---|
| 240 | public: | 
|---|
| 241 | G1CollectionSet(G1CollectedHeap* g1h, G1Policy* policy); | 
|---|
| 242 | ~G1CollectionSet(); | 
|---|
| 243 |  | 
|---|
| 244 | // Initializes the collection set giving the maximum possible length of the collection set. | 
|---|
| 245 | void initialize(uint max_region_length); | 
|---|
| 246 |  | 
|---|
| 247 | void clear_candidates(); | 
|---|
| 248 |  | 
|---|
| 249 | void set_candidates(G1CollectionSetCandidates* candidates) { | 
|---|
| 250 | assert(_candidates == NULL, "Trying to replace collection set candidates."); | 
|---|
| 251 | _candidates = candidates; | 
|---|
| 252 | } | 
|---|
| 253 | G1CollectionSetCandidates* candidates() { return _candidates; } | 
|---|
| 254 |  | 
|---|
| 255 | void init_region_lengths(uint eden_cset_region_length, | 
|---|
| 256 | uint survivor_cset_region_length); | 
|---|
| 257 |  | 
|---|
| 258 | uint region_length() const       { return young_region_length() + | 
|---|
| 259 | old_region_length(); } | 
|---|
| 260 | uint young_region_length() const { return eden_region_length() + | 
|---|
| 261 | survivor_region_length(); } | 
|---|
| 262 |  | 
|---|
| 263 | uint eden_region_length() const     { return _eden_region_length;     } | 
|---|
| 264 | uint survivor_region_length() const { return _survivor_region_length; } | 
|---|
| 265 | uint old_region_length() const      { return _old_region_length;      } | 
|---|
| 266 | uint optional_region_length() const { return _num_optional_regions; } | 
|---|
| 267 |  | 
|---|
| 268 | // Reset the contents of the collection set. | 
|---|
| 269 | void clear(); | 
|---|
| 270 |  | 
|---|
| 271 | // Incremental collection set support | 
|---|
| 272 |  | 
|---|
| 273 | // Initialize incremental collection set info. | 
|---|
| 274 | void start_incremental_building(); | 
|---|
| 275 | // Start a new collection set increment. | 
|---|
| 276 | void update_incremental_marker() { _inc_build_state = Active; _inc_part_start = _collection_set_cur_length; } | 
|---|
| 277 | // Stop adding regions to the current collection set increment. | 
|---|
| 278 | void stop_incremental_building() { _inc_build_state = Inactive; } | 
|---|
| 279 |  | 
|---|
| 280 | // Iterate over the current collection set increment applying the given HeapRegionClosure | 
|---|
| 281 | // from a starting position determined by the given worker id. | 
|---|
| 282 | void iterate_incremental_part_from(HeapRegionClosure* cl, uint worker_id, uint total_workers) const; | 
|---|
| 283 |  | 
|---|
| 284 | // Iterate over the entire collection set (all increments calculated so far), applying | 
|---|
| 285 | // the given HeapRegionClosure on all of them. | 
|---|
| 286 | void iterate(HeapRegionClosure* cl) const; | 
|---|
| 287 |  | 
|---|
| 288 | void iterate_optional(HeapRegionClosure* cl) const; | 
|---|
| 289 |  | 
|---|
| 290 | size_t recorded_rs_lengths() { return _recorded_rs_lengths; } | 
|---|
| 291 |  | 
|---|
| 292 | size_t bytes_used_before() const { | 
|---|
| 293 | return _bytes_used_before; | 
|---|
| 294 | } | 
|---|
| 295 |  | 
|---|
| 296 | void reset_bytes_used_before() { | 
|---|
| 297 | _bytes_used_before = 0; | 
|---|
| 298 | } | 
|---|
| 299 |  | 
|---|
| 300 | // Finalize the initial collection set consisting of all young regions potentially a | 
|---|
| 301 | // few old gen regions. | 
|---|
| 302 | void finalize_initial_collection_set(double target_pause_time_ms, G1SurvivorRegions* survivor); | 
|---|
| 303 | // Finalize the next collection set from the set of available optional old gen regions. | 
|---|
| 304 | bool finalize_optional_for_evacuation(double remaining_pause_time); | 
|---|
| 305 | // Abandon (clean up) optional collection set regions that were not evacuated in this | 
|---|
| 306 | // pause. | 
|---|
| 307 | void abandon_optional_collection_set(G1ParScanThreadStateSet* pss); | 
|---|
| 308 |  | 
|---|
| 309 | // Update information about hr in the aggregated information for | 
|---|
| 310 | // the incrementally built collection set. | 
|---|
| 311 | void update_young_region_prediction(HeapRegion* hr, size_t new_rs_length); | 
|---|
| 312 |  | 
|---|
| 313 | // Add eden region to the collection set. | 
|---|
| 314 | void add_eden_region(HeapRegion* hr); | 
|---|
| 315 |  | 
|---|
| 316 | // Add survivor region to the collection set. | 
|---|
| 317 | void add_survivor_regions(HeapRegion* hr); | 
|---|
| 318 |  | 
|---|
| 319 | #ifndef PRODUCT | 
|---|
| 320 | bool verify_young_ages(); | 
|---|
| 321 |  | 
|---|
| 322 | void print(outputStream* st); | 
|---|
| 323 | #endif // !PRODUCT | 
|---|
| 324 | }; | 
|---|
| 325 |  | 
|---|
| 326 | #endif // SHARE_GC_G1_G1COLLECTIONSET_HPP | 
|---|
| 327 |  | 
|---|