Mercurial > hg > graal-compiler
annotate src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp @ 3919:4f41766176cf
7084509: G1: fix inconsistencies and mistakes in the young list target length calculations
Summary: Fixed inconsistencies and mistakes in the young list target length calculations so that a) the calculated target length is optimal (before, it was not), b) other parameters like max survivor size and max gc locker eden expansion are always consistent with the calculated target length (before, they were not always), and c) the resulting target length was always bound by desired min and max values (before, it was not).
Reviewed-by: brutisso, johnc
author | tonyp |
---|---|
date | Thu, 08 Sep 2011 05:16:49 -0400 |
parents | e8b0b0392037 |
children | 65a8ff39a6da |
rev | line source |
---|---|
342 | 1 /* |
2173 | 2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. |
342 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1390
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1390
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1390
diff
changeset
|
21 * questions. |
342 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONREMSET_HPP |
26 #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONREMSET_HPP | |
27 | |
28 #include "gc_implementation/g1/sparsePRT.hpp" | |
29 | |
342 | 30 // Remembered set for a heap region. Represent a set of "cards" that |
31 // contain pointers into the owner heap region. Cards are defined somewhat | |
32 // abstractly, in terms of what the "BlockOffsetTable" in use can parse. | |
33 | |
34 class G1CollectedHeap; | |
35 class G1BlockOffsetSharedArray; | |
36 class HeapRegion; | |
37 class HeapRegionRemSetIterator; | |
38 class PosParPRT; | |
39 class SparsePRT; | |
40 | |
2173 | 41 // Essentially a wrapper around SparsePRTCleanupTask. See |
42 // sparsePRT.hpp for more details. | |
43 class HRRSCleanupTask : public SparsePRTCleanupTask { | |
44 }; | |
342 | 45 |
46 // The "_coarse_map" is a bitmap with one bit for each region, where set | |
47 // bits indicate that the corresponding region may contain some pointer | |
48 // into the owning region. | |
49 | |
50 // The "_fine_grain_entries" array is an open hash table of PerRegionTables | |
51 // (PRTs), indicating regions for which we're keeping the RS as a set of | |
52 // cards. The strategy is to cap the size of the fine-grain table, | |
53 // deleting an entry and setting the corresponding coarse-grained bit when | |
54 // we would overflow this cap. | |
55 | |
56 // We use a mixture of locking and lock-free techniques here. We allow | |
57 // threads to locate PRTs without locking, but threads attempting to alter | |
58 // a bucket list obtain a lock. This means that any failing attempt to | |
59 // find a PRT must be retried with the lock. It might seem dangerous that | |
60 // a read can find a PRT that is concurrently deleted. This is all right, | |
61 // because: | |
62 // | |
63 // 1) We only actually free PRT's at safe points (though we reuse them at | |
64 // other times). | |
65 // 2) We find PRT's in an attempt to add entries. If a PRT is deleted, | |
66 // it's _coarse_map bit is set, so the that we were attempting to add | |
67 // is represented. If a deleted PRT is re-used, a thread adding a bit, | |
68 // thinking the PRT is for a different region, does no harm. | |
69 | |
549
fe3d7c11b4b7
6700941: G1: allocation spec missing for some G1 classes
apetrusenko
parents:
342
diff
changeset
|
70 class OtherRegionsTable VALUE_OBJ_CLASS_SPEC { |
342 | 71 friend class HeapRegionRemSetIterator; |
72 | |
73 G1CollectedHeap* _g1h; | |
74 Mutex _m; | |
75 HeapRegion* _hr; | |
76 | |
77 // These are protected by "_m". | |
78 BitMap _coarse_map; | |
79 size_t _n_coarse_entries; | |
80 static jint _n_coarsenings; | |
81 | |
82 PosParPRT** _fine_grain_regions; | |
83 size_t _n_fine_entries; | |
84 | |
85 #define SAMPLE_FOR_EVICTION 1 | |
86 #if SAMPLE_FOR_EVICTION | |
87 size_t _fine_eviction_start; | |
88 static size_t _fine_eviction_stride; | |
89 static size_t _fine_eviction_sample_size; | |
90 #endif | |
91 | |
92 SparsePRT _sparse_table; | |
93 | |
94 // These are static after init. | |
95 static size_t _max_fine_entries; | |
96 static size_t _mod_max_fine_entries_mask; | |
97 | |
98 // Requires "prt" to be the first element of the bucket list appropriate | |
99 // for "hr". If this list contains an entry for "hr", return it, | |
100 // otherwise return "NULL". | |
101 PosParPRT* find_region_table(size_t ind, HeapRegion* hr) const; | |
102 | |
103 // Find, delete, and return a candidate PosParPRT, if any exists, | |
104 // adding the deleted region to the coarse bitmap. Requires the caller | |
105 // to hold _m, and the fine-grain table to be full. | |
106 PosParPRT* delete_region_table(); | |
107 | |
108 // If a PRT for "hr" is in the bucket list indicated by "ind" (which must | |
109 // be the correct index for "hr"), delete it and return true; else return | |
110 // false. | |
111 bool del_single_region_table(size_t ind, HeapRegion* hr); | |
112 | |
113 static jint _cache_probes; | |
114 static jint _cache_hits; | |
115 | |
116 // Indexed by thread X heap region, to minimize thread contention. | |
117 static int** _from_card_cache; | |
118 static size_t _from_card_cache_max_regions; | |
119 static size_t _from_card_cache_mem_size; | |
120 | |
121 public: | |
122 OtherRegionsTable(HeapRegion* hr); | |
123 | |
124 HeapRegion* hr() const { return _hr; } | |
125 | |
126 // For now. Could "expand" some tables in the future, so that this made | |
127 // sense. | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
794
diff
changeset
|
128 void add_reference(OopOrNarrowOopStar from, int tid); |
342 | 129 |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
794
diff
changeset
|
130 void add_reference(OopOrNarrowOopStar from) { |
342 | 131 return add_reference(from, 0); |
132 } | |
133 | |
134 // Removes any entries shown by the given bitmaps to contain only dead | |
135 // objects. | |
136 void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm); | |
137 | |
138 // Not const because it takes a lock. | |
139 size_t occupied() const; | |
140 size_t occ_fine() const; | |
141 size_t occ_coarse() const; | |
142 size_t occ_sparse() const; | |
143 | |
144 static jint n_coarsenings() { return _n_coarsenings; } | |
145 | |
146 // Returns size in bytes. | |
147 // Not const because it takes a lock. | |
148 size_t mem_size() const; | |
149 static size_t static_mem_size(); | |
150 static size_t fl_mem_size(); | |
151 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
794
diff
changeset
|
152 bool contains_reference(OopOrNarrowOopStar from) const; |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
794
diff
changeset
|
153 bool contains_reference_locked(OopOrNarrowOopStar from) const; |
342 | 154 |
155 void clear(); | |
156 | |
157 // Specifically clear the from_card_cache. | |
158 void clear_fcc(); | |
159 | |
160 // "from_hr" is being cleared; remove any entries from it. | |
161 void clear_incoming_entry(HeapRegion* from_hr); | |
162 | |
2173 | 163 void do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task); |
164 | |
342 | 165 // Declare the heap size (in # of regions) to the OtherRegionsTable. |
166 // (Uses it to initialize from_card_cache). | |
167 static void init_from_card_cache(size_t max_regions); | |
168 | |
169 // Declares that only regions i s.t. 0 <= i < new_n_regs are in use. | |
170 // Make sure any entries for higher regions are invalid. | |
171 static void shrink_from_card_cache(size_t new_n_regs); | |
172 | |
173 static void print_from_card_cache(); | |
174 }; | |
175 | |
176 class HeapRegionRemSet : public CHeapObj { | |
177 friend class VMStructs; | |
178 friend class HeapRegionRemSetIterator; | |
179 | |
180 public: | |
181 enum Event { | |
182 Event_EvacStart, Event_EvacEnd, Event_RSUpdateEnd | |
183 }; | |
184 | |
185 private: | |
186 G1BlockOffsetSharedArray* _bosa; | |
187 G1BlockOffsetSharedArray* bosa() const { return _bosa; } | |
188 | |
189 OtherRegionsTable _other_regions; | |
190 | |
191 enum ParIterState { Unclaimed, Claimed, Complete }; | |
1261 | 192 volatile ParIterState _iter_state; |
193 volatile jlong _iter_claimed; | |
342 | 194 |
195 // Unused unless G1RecordHRRSOops is true. | |
196 | |
197 static const int MaxRecorded = 1000000; | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
794
diff
changeset
|
198 static OopOrNarrowOopStar* _recorded_oops; |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
794
diff
changeset
|
199 static HeapWord** _recorded_cards; |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
794
diff
changeset
|
200 static HeapRegion** _recorded_regions; |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
794
diff
changeset
|
201 static int _n_recorded; |
342 | 202 |
203 static const int MaxRecordedEvents = 1000; | |
204 static Event* _recorded_events; | |
205 static int* _recorded_event_index; | |
206 static int _n_recorded_events; | |
207 | |
208 static void print_event(outputStream* str, Event evnt); | |
209 | |
210 public: | |
211 HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, | |
212 HeapRegion* hr); | |
213 | |
214 static int num_par_rem_sets(); | |
1261 | 215 static void setup_remset_size(); |
342 | 216 |
217 HeapRegion* hr() const { | |
218 return _other_regions.hr(); | |
219 } | |
220 | |
221 size_t occupied() const { | |
222 return _other_regions.occupied(); | |
223 } | |
224 size_t occ_fine() const { | |
225 return _other_regions.occ_fine(); | |
226 } | |
227 size_t occ_coarse() const { | |
228 return _other_regions.occ_coarse(); | |
229 } | |
230 size_t occ_sparse() const { | |
231 return _other_regions.occ_sparse(); | |
232 } | |
233 | |
234 static jint n_coarsenings() { return OtherRegionsTable::n_coarsenings(); } | |
235 | |
236 /* Used in the sequential case. Returns "true" iff this addition causes | |
237 the size limit to be reached. */ | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
794
diff
changeset
|
238 void add_reference(OopOrNarrowOopStar from) { |
342 | 239 _other_regions.add_reference(from); |
240 } | |
241 | |
242 /* Used in the parallel case. Returns "true" iff this addition causes | |
243 the size limit to be reached. */ | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
794
diff
changeset
|
244 void add_reference(OopOrNarrowOopStar from, int tid) { |
342 | 245 _other_regions.add_reference(from, tid); |
246 } | |
247 | |
248 // Removes any entries shown by the given bitmaps to contain only dead | |
249 // objects. | |
250 void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm); | |
251 | |
252 // The region is being reclaimed; clear its remset, and any mention of | |
253 // entries for this region in other remsets. | |
254 void clear(); | |
255 | |
256 // Forget any entries due to pointers from "from_hr". | |
257 void clear_incoming_entry(HeapRegion* from_hr) { | |
258 _other_regions.clear_incoming_entry(from_hr); | |
259 } | |
260 | |
261 #if 0 | |
262 virtual void cleanup() = 0; | |
263 #endif | |
264 | |
265 // Attempt to claim the region. Returns true iff this call caused an | |
266 // atomic transition from Unclaimed to Claimed. | |
267 bool claim_iter(); | |
268 // Sets the iteration state to "complete". | |
269 void set_iter_complete(); | |
270 // Returns "true" iff the region's iteration is complete. | |
271 bool iter_is_complete(); | |
272 | |
1261 | 273 // Support for claiming blocks of cards during iteration |
274 size_t iter_claimed() const { return (size_t)_iter_claimed; } | |
275 // Claim the next block of cards | |
276 size_t iter_claimed_next(size_t step) { | |
277 size_t current, next; | |
278 do { | |
279 current = iter_claimed(); | |
280 next = current + step; | |
281 } while (Atomic::cmpxchg((jlong)next, &_iter_claimed, (jlong)current) != (jlong)current); | |
282 return current; | |
283 } | |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
2173
diff
changeset
|
284 void reset_for_par_iteration(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
2173
diff
changeset
|
285 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
2173
diff
changeset
|
286 bool verify_ready_for_par_iteration() { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
2173
diff
changeset
|
287 return (_iter_state == Unclaimed) && (_iter_claimed == 0); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
2173
diff
changeset
|
288 } |
1261 | 289 |
342 | 290 // Initialize the given iterator to iterate over this rem set. |
291 void init_iterator(HeapRegionRemSetIterator* iter) const; | |
292 | |
293 #if 0 | |
294 // Apply the "do_card" method to the start address of every card in the | |
295 // rem set. Returns false if some application of the closure aborted. | |
296 virtual bool card_iterate(CardClosure* iter) = 0; | |
297 #endif | |
298 | |
299 // The actual # of bytes this hr_remset takes up. | |
300 size_t mem_size() { | |
301 return _other_regions.mem_size() | |
302 // This correction is necessary because the above includes the second | |
303 // part. | |
304 + sizeof(this) - sizeof(OtherRegionsTable); | |
305 } | |
306 | |
307 // Returns the memory occupancy of all static data structures associated | |
308 // with remembered sets. | |
309 static size_t static_mem_size() { | |
310 return OtherRegionsTable::static_mem_size(); | |
311 } | |
312 | |
313 // Returns the memory occupancy of all free_list data structures associated | |
314 // with remembered sets. | |
315 static size_t fl_mem_size() { | |
316 return OtherRegionsTable::fl_mem_size(); | |
317 } | |
318 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
794
diff
changeset
|
319 bool contains_reference(OopOrNarrowOopStar from) const { |
342 | 320 return _other_regions.contains_reference(from); |
321 } | |
322 void print() const; | |
323 | |
324 // Called during a stop-world phase to perform any deferred cleanups. | |
325 // The second version may be called by parallel threads after then finish | |
326 // collection work. | |
327 static void cleanup(); | |
328 static void par_cleanup(); | |
329 | |
330 // Declare the heap size (in # of regions) to the HeapRegionRemSet(s). | |
331 // (Uses it to initialize from_card_cache). | |
332 static void init_heap(size_t max_regions) { | |
333 OtherRegionsTable::init_from_card_cache(max_regions); | |
334 } | |
335 | |
336 // Declares that only regions i s.t. 0 <= i < new_n_regs are in use. | |
337 static void shrink_heap(size_t new_n_regs) { | |
338 OtherRegionsTable::shrink_from_card_cache(new_n_regs); | |
339 } | |
340 | |
341 #ifndef PRODUCT | |
342 static void print_from_card_cache() { | |
343 OtherRegionsTable::print_from_card_cache(); | |
344 } | |
345 #endif | |
346 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
794
diff
changeset
|
347 static void record(HeapRegion* hr, OopOrNarrowOopStar f); |
342 | 348 static void print_recorded(); |
349 static void record_event(Event evnt); | |
350 | |
2173 | 351 // These are wrappers for the similarly-named methods on |
352 // SparsePRT. Look at sparsePRT.hpp for more details. | |
353 static void reset_for_cleanup_tasks(); | |
354 void do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task); | |
355 static void finish_cleanup_task(HRRSCleanupTask* hrrs_cleanup_task); | |
356 | |
342 | 357 // Run unit tests. |
358 #ifndef PRODUCT | |
359 static void test(); | |
360 #endif | |
361 }; | |
362 | |
363 class HeapRegionRemSetIterator : public CHeapObj { | |
364 | |
365 // The region over which we're iterating. | |
366 const HeapRegionRemSet* _hrrs; | |
367 | |
368 // Local caching of HRRS fields. | |
369 const BitMap* _coarse_map; | |
370 PosParPRT** _fine_grain_regions; | |
371 | |
372 G1BlockOffsetSharedArray* _bosa; | |
373 G1CollectedHeap* _g1h; | |
374 | |
375 // The number yielded since initialization. | |
376 size_t _n_yielded_fine; | |
377 size_t _n_yielded_coarse; | |
378 size_t _n_yielded_sparse; | |
379 | |
380 // If true we're iterating over the coarse table; if false the fine | |
381 // table. | |
382 enum IterState { | |
383 Sparse, | |
384 Fine, | |
385 Coarse | |
386 }; | |
387 IterState _is; | |
388 | |
389 // In both kinds of iteration, heap offset of first card of current | |
390 // region. | |
391 size_t _cur_region_card_offset; | |
392 // Card offset within cur region. | |
393 size_t _cur_region_cur_card; | |
394 | |
395 // Coarse table iteration fields: | |
396 | |
397 // Current region index; | |
398 int _coarse_cur_region_index; | |
399 int _coarse_cur_region_cur_card; | |
400 | |
401 bool coarse_has_next(size_t& card_index); | |
402 | |
403 // Fine table iteration fields: | |
404 | |
405 // Index of bucket-list we're working on. | |
406 int _fine_array_index; | |
407 // Per Region Table we're doing within current bucket list. | |
408 PosParPRT* _fine_cur_prt; | |
409 | |
410 /* SparsePRT::*/ SparsePRTIter _sparse_iter; | |
411 | |
412 void fine_find_next_non_null_prt(); | |
413 | |
414 bool fine_has_next(); | |
415 bool fine_has_next(size_t& card_index); | |
416 | |
417 public: | |
418 // We require an iterator to be initialized before use, so the | |
419 // constructor does little. | |
420 HeapRegionRemSetIterator(); | |
421 | |
422 void initialize(const HeapRegionRemSet* hrrs); | |
423 | |
424 // If there remains one or more cards to be yielded, returns true and | |
425 // sets "card_index" to one of those cards (which is then considered | |
426 // yielded.) Otherwise, returns false (and leaves "card_index" | |
427 // undefined.) | |
428 bool has_next(size_t& card_index); | |
429 | |
430 size_t n_yielded_fine() { return _n_yielded_fine; } | |
431 size_t n_yielded_coarse() { return _n_yielded_coarse; } | |
432 size_t n_yielded_sparse() { return _n_yielded_sparse; } | |
433 size_t n_yielded() { | |
434 return n_yielded_fine() + n_yielded_coarse() + n_yielded_sparse(); | |
435 } | |
436 }; | |
437 | |
438 #if 0 | |
439 class CardClosure: public Closure { | |
440 public: | |
441 virtual void do_card(HeapWord* card_start) = 0; | |
442 }; | |
443 | |
444 #endif | |
1972 | 445 |
446 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONREMSET_HPP |