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 | |