Mercurial > hg > graal-compiler
comparison src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp @ 18041:52b4284cb496
Merge with jdk8u20-b26
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Wed, 15 Oct 2014 16:02:50 +0200 |
parents | 89152779163c ae7336d6337e |
children | 7848fc12602b |
comparison
equal
deleted
inserted
replaced
17606:45d7b2c7029d | 18041:52b4284cb496 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 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 | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
23 */ | 23 */ |
24 | 24 |
25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONREMSET_HPP | 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONREMSET_HPP |
26 #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONREMSET_HPP | 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONREMSET_HPP |
27 | 27 |
28 #include "gc_implementation/g1/g1CodeCacheRemSet.hpp" | |
28 #include "gc_implementation/g1/sparsePRT.hpp" | 29 #include "gc_implementation/g1/sparsePRT.hpp" |
29 | 30 |
30 // Remembered set for a heap region. Represent a set of "cards" that | 31 // 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 // contain pointers into the owner heap region. Cards are defined somewhat |
32 // abstractly, in terms of what the "BlockOffsetTable" in use can parse. | 33 // abstractly, in terms of what the "BlockOffsetTable" in use can parse. |
40 class nmethod; | 41 class nmethod; |
41 | 42 |
42 // Essentially a wrapper around SparsePRTCleanupTask. See | 43 // Essentially a wrapper around SparsePRTCleanupTask. See |
43 // sparsePRT.hpp for more details. | 44 // sparsePRT.hpp for more details. |
44 class HRRSCleanupTask : public SparsePRTCleanupTask { | 45 class HRRSCleanupTask : public SparsePRTCleanupTask { |
46 }; | |
47 | |
48 // The FromCardCache remembers the most recently processed card on the heap on | |
49 // a per-region and per-thread basis. | |
50 class FromCardCache : public AllStatic { | |
51 private: | |
52 // Array of card indices. Indexed by thread X and heap region to minimize | |
53 // thread contention. | |
54 static int** _cache; | |
55 static uint _max_regions; | |
56 static size_t _static_mem_size; | |
57 | |
58 public: | |
59 enum { | |
60 InvalidCard = -1 // Card value of an invalid card, i.e. a card index not otherwise used. | |
61 }; | |
62 | |
63 static void clear(uint region_idx); | |
64 | |
65 // Returns true if the given card is in the cache at the given location, or | |
66 // replaces the card at that location and returns false. | |
67 static bool contains_or_replace(uint worker_id, uint region_idx, int card) { | |
68 int card_in_cache = at(worker_id, region_idx); | |
69 if (card_in_cache == card) { | |
70 return true; | |
71 } else { | |
72 set(worker_id, region_idx, card); | |
73 return false; | |
74 } | |
75 } | |
76 | |
77 static int at(uint worker_id, uint region_idx) { | |
78 return _cache[worker_id][region_idx]; | |
79 } | |
80 | |
81 static void set(uint worker_id, uint region_idx, int val) { | |
82 _cache[worker_id][region_idx] = val; | |
83 } | |
84 | |
85 static void initialize(uint n_par_rs, uint max_num_regions); | |
86 | |
87 static void shrink(uint new_num_regions); | |
88 | |
89 static void print(outputStream* out = gclog_or_tty) PRODUCT_RETURN; | |
90 | |
91 static size_t static_mem_size() { | |
92 return _static_mem_size; | |
93 } | |
45 }; | 94 }; |
46 | 95 |
47 // The "_coarse_map" is a bitmap with one bit for each region, where set | 96 // The "_coarse_map" is a bitmap with one bit for each region, where set |
48 // bits indicate that the corresponding region may contain some pointer | 97 // bits indicate that the corresponding region may contain some pointer |
49 // into the owning region. | 98 // into the owning region. |
70 | 119 |
71 class OtherRegionsTable VALUE_OBJ_CLASS_SPEC { | 120 class OtherRegionsTable VALUE_OBJ_CLASS_SPEC { |
72 friend class HeapRegionRemSetIterator; | 121 friend class HeapRegionRemSetIterator; |
73 | 122 |
74 G1CollectedHeap* _g1h; | 123 G1CollectedHeap* _g1h; |
75 Mutex _m; | 124 Mutex* _m; |
76 HeapRegion* _hr; | 125 HeapRegion* _hr; |
77 | 126 |
78 // These are protected by "_m". | 127 // These are protected by "_m". |
79 BitMap _coarse_map; | 128 BitMap _coarse_map; |
80 size_t _n_coarse_entries; | 129 size_t _n_coarse_entries; |
116 // If a PRT for "hr" is in the bucket list indicated by "ind" (which must | 165 // If a PRT for "hr" is in the bucket list indicated by "ind" (which must |
117 // be the correct index for "hr"), delete it and return true; else return | 166 // be the correct index for "hr"), delete it and return true; else return |
118 // false. | 167 // false. |
119 bool del_single_region_table(size_t ind, HeapRegion* hr); | 168 bool del_single_region_table(size_t ind, HeapRegion* hr); |
120 | 169 |
121 // Indexed by thread X heap region, to minimize thread contention. | |
122 static int** _from_card_cache; | |
123 static size_t _from_card_cache_max_regions; | |
124 static size_t _from_card_cache_mem_size; | |
125 | |
126 // link/add the given fine grain remembered set into the "all" list | 170 // link/add the given fine grain remembered set into the "all" list |
127 void link_to_all(PerRegionTable * prt); | 171 void link_to_all(PerRegionTable * prt); |
128 // unlink/remove the given fine grain remembered set into the "all" list | 172 // unlink/remove the given fine grain remembered set into the "all" list |
129 void unlink_from_all(PerRegionTable * prt); | 173 void unlink_from_all(PerRegionTable * prt); |
130 | 174 |
131 public: | 175 public: |
132 OtherRegionsTable(HeapRegion* hr); | 176 OtherRegionsTable(HeapRegion* hr, Mutex* m); |
133 | 177 |
134 HeapRegion* hr() const { return _hr; } | 178 HeapRegion* hr() const { return _hr; } |
135 | 179 |
136 // For now. Could "expand" some tables in the future, so that this made | 180 // For now. Could "expand" some tables in the future, so that this made |
137 // sense. | 181 // sense. |
139 | 183 |
140 // Removes any entries shown by the given bitmaps to contain only dead | 184 // Removes any entries shown by the given bitmaps to contain only dead |
141 // objects. | 185 // objects. |
142 void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm); | 186 void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm); |
143 | 187 |
144 // Not const because it takes a lock. | |
145 size_t occupied() const; | 188 size_t occupied() const; |
146 size_t occ_fine() const; | 189 size_t occ_fine() const; |
147 size_t occ_coarse() const; | 190 size_t occ_coarse() const; |
148 size_t occ_sparse() const; | 191 size_t occ_sparse() const; |
149 | 192 |
168 | 211 |
169 void do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task); | 212 void do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task); |
170 | 213 |
171 // Declare the heap size (in # of regions) to the OtherRegionsTable. | 214 // Declare the heap size (in # of regions) to the OtherRegionsTable. |
172 // (Uses it to initialize from_card_cache). | 215 // (Uses it to initialize from_card_cache). |
173 static void init_from_card_cache(size_t max_regions); | 216 static void init_from_card_cache(uint max_regions); |
174 | 217 |
175 // Declares that only regions i s.t. 0 <= i < new_n_regs are in use. | 218 // Declares that only regions i s.t. 0 <= i < new_n_regs are in use. |
176 // Make sure any entries for higher regions are invalid. | 219 // Make sure any entries for higher regions are invalid. |
177 static void shrink_from_card_cache(size_t new_n_regs); | 220 static void shrink_from_card_cache(uint new_num_regions); |
178 | 221 |
179 static void print_from_card_cache(); | 222 static void print_from_card_cache(); |
180 }; | 223 }; |
181 | 224 |
182 class HeapRegionRemSet : public CHeapObj<mtGC> { | 225 class HeapRegionRemSet : public CHeapObj<mtGC> { |
190 | 233 |
191 private: | 234 private: |
192 G1BlockOffsetSharedArray* _bosa; | 235 G1BlockOffsetSharedArray* _bosa; |
193 G1BlockOffsetSharedArray* bosa() const { return _bosa; } | 236 G1BlockOffsetSharedArray* bosa() const { return _bosa; } |
194 | 237 |
195 // A list of code blobs (nmethods) whose code contains pointers into | 238 // A set of code blobs (nmethods) whose code contains pointers into |
196 // the region that owns this RSet. | 239 // the region that owns this RSet. |
197 GrowableArray<nmethod*>* _strong_code_roots_list; | 240 G1CodeRootSet _code_roots; |
241 | |
242 Mutex _m; | |
198 | 243 |
199 OtherRegionsTable _other_regions; | 244 OtherRegionsTable _other_regions; |
200 | 245 |
201 enum ParIterState { Unclaimed, Claimed, Complete }; | 246 enum ParIterState { Unclaimed, Claimed, Complete }; |
202 volatile ParIterState _iter_state; | 247 volatile ParIterState _iter_state; |
216 static int _n_recorded_events; | 261 static int _n_recorded_events; |
217 | 262 |
218 static void print_event(outputStream* str, Event evnt); | 263 static void print_event(outputStream* str, Event evnt); |
219 | 264 |
220 public: | 265 public: |
221 HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, | 266 HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, HeapRegion* hr); |
222 HeapRegion* hr); | 267 |
223 | 268 static uint num_par_rem_sets(); |
224 static int num_par_rem_sets(); | |
225 static void setup_remset_size(); | 269 static void setup_remset_size(); |
226 | 270 |
227 HeapRegion* hr() const { | 271 HeapRegion* hr() const { |
228 return _other_regions.hr(); | 272 return _other_regions.hr(); |
229 } | 273 } |
230 | 274 |
231 size_t occupied() const { | 275 size_t occupied() { |
276 MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag); | |
277 return occupied_locked(); | |
278 } | |
279 size_t occupied_locked() { | |
232 return _other_regions.occupied(); | 280 return _other_regions.occupied(); |
233 } | 281 } |
234 size_t occ_fine() const { | 282 size_t occ_fine() const { |
235 return _other_regions.occ_fine(); | 283 return _other_regions.occ_fine(); |
236 } | 284 } |
258 void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm); | 306 void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm); |
259 | 307 |
260 // The region is being reclaimed; clear its remset, and any mention of | 308 // The region is being reclaimed; clear its remset, and any mention of |
261 // entries for this region in other remsets. | 309 // entries for this region in other remsets. |
262 void clear(); | 310 void clear(); |
311 void clear_locked(); | |
263 | 312 |
264 // Attempt to claim the region. Returns true iff this call caused an | 313 // Attempt to claim the region. Returns true iff this call caused an |
265 // atomic transition from Unclaimed to Claimed. | 314 // atomic transition from Unclaimed to Claimed. |
266 bool claim_iter(); | 315 bool claim_iter(); |
267 // Sets the iteration state to "complete". | 316 // Sets the iteration state to "complete". |
287 } | 336 } |
288 | 337 |
289 // The actual # of bytes this hr_remset takes up. | 338 // The actual # of bytes this hr_remset takes up. |
290 // Note also includes the strong code root set. | 339 // Note also includes the strong code root set. |
291 size_t mem_size() { | 340 size_t mem_size() { |
341 MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag); | |
292 return _other_regions.mem_size() | 342 return _other_regions.mem_size() |
293 // This correction is necessary because the above includes the second | 343 // This correction is necessary because the above includes the second |
294 // part. | 344 // part. |
295 + (sizeof(this) - sizeof(OtherRegionsTable)) | 345 + (sizeof(this) - sizeof(OtherRegionsTable)) |
296 + strong_code_roots_mem_size(); | 346 + strong_code_roots_mem_size(); |
297 } | 347 } |
298 | 348 |
299 // Returns the memory occupancy of all static data structures associated | 349 // Returns the memory occupancy of all static data structures associated |
300 // with remembered sets. | 350 // with remembered sets. |
301 static size_t static_mem_size() { | 351 static size_t static_mem_size() { |
302 return OtherRegionsTable::static_mem_size(); | 352 return OtherRegionsTable::static_mem_size() + G1CodeRootSet::static_mem_size(); |
303 } | 353 } |
304 | 354 |
305 // Returns the memory occupancy of all free_list data structures associated | 355 // Returns the memory occupancy of all free_list data structures associated |
306 // with remembered sets. | 356 // with remembered sets. |
307 static size_t fl_mem_size() { | 357 static size_t fl_mem_size() { |
308 return OtherRegionsTable::fl_mem_size(); | 358 return OtherRegionsTable::fl_mem_size() + G1CodeRootSet::fl_mem_size(); |
309 } | 359 } |
310 | 360 |
311 bool contains_reference(OopOrNarrowOopStar from) const { | 361 bool contains_reference(OopOrNarrowOopStar from) const { |
312 return _other_regions.contains_reference(from); | 362 return _other_regions.contains_reference(from); |
313 } | 363 } |
326 // Applies blk->do_code_blob() to each of the entries in | 376 // Applies blk->do_code_blob() to each of the entries in |
327 // the strong code roots list | 377 // the strong code roots list |
328 void strong_code_roots_do(CodeBlobClosure* blk) const; | 378 void strong_code_roots_do(CodeBlobClosure* blk) const; |
329 | 379 |
330 // Returns the number of elements in the strong code roots list | 380 // Returns the number of elements in the strong code roots list |
331 int strong_code_roots_list_length() { | 381 size_t strong_code_roots_list_length() { |
332 return _strong_code_roots_list->length(); | 382 return _code_roots.length(); |
333 } | 383 } |
334 | 384 |
335 // Returns true if the strong code roots contains the given | 385 // Returns true if the strong code roots contains the given |
336 // nmethod. | 386 // nmethod. |
337 bool strong_code_roots_list_contains(nmethod* nm) { | 387 bool strong_code_roots_list_contains(nmethod* nm) { |
338 return _strong_code_roots_list->contains(nm); | 388 return _code_roots.contains(nm); |
339 } | 389 } |
340 | 390 |
341 // Returns the amount of memory, in bytes, currently | 391 // Returns the amount of memory, in bytes, currently |
342 // consumed by the strong code roots. | 392 // consumed by the strong code roots. |
343 size_t strong_code_roots_mem_size(); | 393 size_t strong_code_roots_mem_size(); |
344 | 394 |
345 void print() const; | 395 void print() PRODUCT_RETURN; |
346 | 396 |
347 // Called during a stop-world phase to perform any deferred cleanups. | 397 // Called during a stop-world phase to perform any deferred cleanups. |
348 static void cleanup(); | 398 static void cleanup(); |
349 | 399 |
350 // Declare the heap size (in # of regions) to the HeapRegionRemSet(s). | 400 // Declare the heap size (in # of regions) to the HeapRegionRemSet(s). |
351 // (Uses it to initialize from_card_cache). | 401 // (Uses it to initialize from_card_cache). |
352 static void init_heap(uint max_regions) { | 402 static void init_heap(uint max_regions) { |
353 OtherRegionsTable::init_from_card_cache((size_t) max_regions); | 403 G1CodeRootSet::initialize(); |
404 OtherRegionsTable::init_from_card_cache(max_regions); | |
354 } | 405 } |
355 | 406 |
356 // Declares that only regions i s.t. 0 <= i < new_n_regs are in use. | 407 // Declares that only regions i s.t. 0 <= i < new_n_regs are in use. |
357 static void shrink_heap(uint new_n_regs) { | 408 static void shrink_heap(uint new_n_regs) { |
358 OtherRegionsTable::shrink_from_card_cache((size_t) new_n_regs); | 409 OtherRegionsTable::shrink_from_card_cache(new_n_regs); |
359 } | 410 } |
360 | 411 |
361 #ifndef PRODUCT | 412 #ifndef PRODUCT |
362 static void print_from_card_cache() { | 413 static void print_from_card_cache() { |
363 OtherRegionsTable::print_from_card_cache(); | 414 OtherRegionsTable::print_from_card_cache(); |
382 }; | 433 }; |
383 | 434 |
384 class HeapRegionRemSetIterator : public StackObj { | 435 class HeapRegionRemSetIterator : public StackObj { |
385 | 436 |
386 // The region RSet over which we're iterating. | 437 // The region RSet over which we're iterating. |
387 const HeapRegionRemSet* _hrrs; | 438 HeapRegionRemSet* _hrrs; |
388 | 439 |
389 // Local caching of HRRS fields. | 440 // Local caching of HRRS fields. |
390 const BitMap* _coarse_map; | 441 const BitMap* _coarse_map; |
391 PerRegionTable** _fine_grain_regions; | 442 PerRegionTable** _fine_grain_regions; |
392 | 443 |
439 bool fine_has_next(size_t& card_index); | 490 bool fine_has_next(size_t& card_index); |
440 | 491 |
441 public: | 492 public: |
442 // We require an iterator to be initialized before use, so the | 493 // We require an iterator to be initialized before use, so the |
443 // constructor does little. | 494 // constructor does little. |
444 HeapRegionRemSetIterator(const HeapRegionRemSet* hrrs); | 495 HeapRegionRemSetIterator(HeapRegionRemSet* hrrs); |
445 | 496 |
446 // If there remains one or more cards to be yielded, returns true and | 497 // If there remains one or more cards to be yielded, returns true and |
447 // sets "card_index" to one of those cards (which is then considered | 498 // sets "card_index" to one of those cards (which is then considered |
448 // yielded.) Otherwise, returns false (and leaves "card_index" | 499 // yielded.) Otherwise, returns false (and leaves "card_index" |
449 // undefined.) | 500 // undefined.) |