comparison src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp @ 17753:191174b49bec

8035406: Improve data structure for Code Cache remembered sets Summary: Change the code cache remembered sets data structure from a GrowableArray to a chunked list of nmethods. This makes the data structure more amenable to parallelization, and decreases freeing time. Reviewed-by: mgerdin, brutisso
author tschatzl
date Mon, 24 Mar 2014 15:30:14 +0100
parents 55fb97c4c58d
children d7070f371770
comparison
equal deleted inserted replaced
17750:f53edbc2b728 17753:191174b49bec
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.
70 71
71 class OtherRegionsTable VALUE_OBJ_CLASS_SPEC { 72 class OtherRegionsTable VALUE_OBJ_CLASS_SPEC {
72 friend class HeapRegionRemSetIterator; 73 friend class HeapRegionRemSetIterator;
73 74
74 G1CollectedHeap* _g1h; 75 G1CollectedHeap* _g1h;
75 Mutex _m; 76 Mutex* _m;
76 HeapRegion* _hr; 77 HeapRegion* _hr;
77 78
78 // These are protected by "_m". 79 // These are protected by "_m".
79 BitMap _coarse_map; 80 BitMap _coarse_map;
80 size_t _n_coarse_entries; 81 size_t _n_coarse_entries;
127 void link_to_all(PerRegionTable * prt); 128 void link_to_all(PerRegionTable * prt);
128 // unlink/remove the given fine grain remembered set into the "all" list 129 // unlink/remove the given fine grain remembered set into the "all" list
129 void unlink_from_all(PerRegionTable * prt); 130 void unlink_from_all(PerRegionTable * prt);
130 131
131 public: 132 public:
132 OtherRegionsTable(HeapRegion* hr); 133 OtherRegionsTable(HeapRegion* hr, Mutex* m);
133 134
134 HeapRegion* hr() const { return _hr; } 135 HeapRegion* hr() const { return _hr; }
135 136
136 // For now. Could "expand" some tables in the future, so that this made 137 // For now. Could "expand" some tables in the future, so that this made
137 // sense. 138 // sense.
139 140
140 // Removes any entries shown by the given bitmaps to contain only dead 141 // Removes any entries shown by the given bitmaps to contain only dead
141 // objects. 142 // objects.
142 void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm); 143 void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm);
143 144
144 // Not const because it takes a lock.
145 size_t occupied() const; 145 size_t occupied() const;
146 size_t occ_fine() const; 146 size_t occ_fine() const;
147 size_t occ_coarse() const; 147 size_t occ_coarse() const;
148 size_t occ_sparse() const; 148 size_t occ_sparse() const;
149 149
190 190
191 private: 191 private:
192 G1BlockOffsetSharedArray* _bosa; 192 G1BlockOffsetSharedArray* _bosa;
193 G1BlockOffsetSharedArray* bosa() const { return _bosa; } 193 G1BlockOffsetSharedArray* bosa() const { return _bosa; }
194 194
195 // A list of code blobs (nmethods) whose code contains pointers into 195 // A set of code blobs (nmethods) whose code contains pointers into
196 // the region that owns this RSet. 196 // the region that owns this RSet.
197 GrowableArray<nmethod*>* _strong_code_roots_list; 197 G1CodeRootSet _code_roots;
198
199 Mutex _m;
198 200
199 OtherRegionsTable _other_regions; 201 OtherRegionsTable _other_regions;
200 202
201 enum ParIterState { Unclaimed, Claimed, Complete }; 203 enum ParIterState { Unclaimed, Claimed, Complete };
202 volatile ParIterState _iter_state; 204 volatile ParIterState _iter_state;
216 static int _n_recorded_events; 218 static int _n_recorded_events;
217 219
218 static void print_event(outputStream* str, Event evnt); 220 static void print_event(outputStream* str, Event evnt);
219 221
220 public: 222 public:
221 HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, 223 HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, HeapRegion* hr);
222 HeapRegion* hr);
223 224
224 static int num_par_rem_sets(); 225 static int num_par_rem_sets();
225 static void setup_remset_size(); 226 static void setup_remset_size();
226 227
227 HeapRegion* hr() const { 228 HeapRegion* hr() const {
228 return _other_regions.hr(); 229 return _other_regions.hr();
229 } 230 }
230 231
231 size_t occupied() const { 232 size_t occupied() {
233 MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag);
234 return occupied_locked();
235 }
236 size_t occupied_locked() {
232 return _other_regions.occupied(); 237 return _other_regions.occupied();
233 } 238 }
234 size_t occ_fine() const { 239 size_t occ_fine() const {
235 return _other_regions.occ_fine(); 240 return _other_regions.occ_fine();
236 } 241 }
258 void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm); 263 void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm);
259 264
260 // The region is being reclaimed; clear its remset, and any mention of 265 // The region is being reclaimed; clear its remset, and any mention of
261 // entries for this region in other remsets. 266 // entries for this region in other remsets.
262 void clear(); 267 void clear();
268 void clear_locked();
263 269
264 // Attempt to claim the region. Returns true iff this call caused an 270 // Attempt to claim the region. Returns true iff this call caused an
265 // atomic transition from Unclaimed to Claimed. 271 // atomic transition from Unclaimed to Claimed.
266 bool claim_iter(); 272 bool claim_iter();
267 // Sets the iteration state to "complete". 273 // Sets the iteration state to "complete".
287 } 293 }
288 294
289 // The actual # of bytes this hr_remset takes up. 295 // The actual # of bytes this hr_remset takes up.
290 // Note also includes the strong code root set. 296 // Note also includes the strong code root set.
291 size_t mem_size() { 297 size_t mem_size() {
298 MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag);
292 return _other_regions.mem_size() 299 return _other_regions.mem_size()
293 // This correction is necessary because the above includes the second 300 // This correction is necessary because the above includes the second
294 // part. 301 // part.
295 + (sizeof(this) - sizeof(OtherRegionsTable)) 302 + (sizeof(this) - sizeof(OtherRegionsTable))
296 + strong_code_roots_mem_size(); 303 + strong_code_roots_mem_size();
297 } 304 }
298 305
299 // Returns the memory occupancy of all static data structures associated 306 // Returns the memory occupancy of all static data structures associated
300 // with remembered sets. 307 // with remembered sets.
301 static size_t static_mem_size() { 308 static size_t static_mem_size() {
302 return OtherRegionsTable::static_mem_size(); 309 return OtherRegionsTable::static_mem_size() + G1CodeRootSet::static_mem_size();
303 } 310 }
304 311
305 // Returns the memory occupancy of all free_list data structures associated 312 // Returns the memory occupancy of all free_list data structures associated
306 // with remembered sets. 313 // with remembered sets.
307 static size_t fl_mem_size() { 314 static size_t fl_mem_size() {
308 return OtherRegionsTable::fl_mem_size(); 315 return OtherRegionsTable::fl_mem_size() + G1CodeRootSet::fl_mem_size();
309 } 316 }
310 317
311 bool contains_reference(OopOrNarrowOopStar from) const { 318 bool contains_reference(OopOrNarrowOopStar from) const {
312 return _other_regions.contains_reference(from); 319 return _other_regions.contains_reference(from);
313 } 320 }
326 // Applies blk->do_code_blob() to each of the entries in 333 // Applies blk->do_code_blob() to each of the entries in
327 // the strong code roots list 334 // the strong code roots list
328 void strong_code_roots_do(CodeBlobClosure* blk) const; 335 void strong_code_roots_do(CodeBlobClosure* blk) const;
329 336
330 // Returns the number of elements in the strong code roots list 337 // Returns the number of elements in the strong code roots list
331 int strong_code_roots_list_length() { 338 size_t strong_code_roots_list_length() {
332 return _strong_code_roots_list->length(); 339 return _code_roots.length();
333 } 340 }
334 341
335 // Returns true if the strong code roots contains the given 342 // Returns true if the strong code roots contains the given
336 // nmethod. 343 // nmethod.
337 bool strong_code_roots_list_contains(nmethod* nm) { 344 bool strong_code_roots_list_contains(nmethod* nm) {
338 return _strong_code_roots_list->contains(nm); 345 return _code_roots.contains(nm);
339 } 346 }
340 347
341 // Returns the amount of memory, in bytes, currently 348 // Returns the amount of memory, in bytes, currently
342 // consumed by the strong code roots. 349 // consumed by the strong code roots.
343 size_t strong_code_roots_mem_size(); 350 size_t strong_code_roots_mem_size();
344 351
345 void print() const; 352 void print() PRODUCT_RETURN;
346 353
347 // Called during a stop-world phase to perform any deferred cleanups. 354 // Called during a stop-world phase to perform any deferred cleanups.
348 static void cleanup(); 355 static void cleanup();
349 356
350 // Declare the heap size (in # of regions) to the HeapRegionRemSet(s). 357 // Declare the heap size (in # of regions) to the HeapRegionRemSet(s).
351 // (Uses it to initialize from_card_cache). 358 // (Uses it to initialize from_card_cache).
352 static void init_heap(uint max_regions) { 359 static void init_heap(uint max_regions) {
360 G1CodeRootSet::initialize();
353 OtherRegionsTable::init_from_card_cache((size_t) max_regions); 361 OtherRegionsTable::init_from_card_cache((size_t) max_regions);
354 } 362 }
355 363
356 // Declares that only regions i s.t. 0 <= i < new_n_regs are in use. 364 // Declares that only regions i s.t. 0 <= i < new_n_regs are in use.
357 static void shrink_heap(uint new_n_regs) { 365 static void shrink_heap(uint new_n_regs) {
382 }; 390 };
383 391
384 class HeapRegionRemSetIterator : public StackObj { 392 class HeapRegionRemSetIterator : public StackObj {
385 393
386 // The region RSet over which we're iterating. 394 // The region RSet over which we're iterating.
387 const HeapRegionRemSet* _hrrs; 395 HeapRegionRemSet* _hrrs;
388 396
389 // Local caching of HRRS fields. 397 // Local caching of HRRS fields.
390 const BitMap* _coarse_map; 398 const BitMap* _coarse_map;
391 PerRegionTable** _fine_grain_regions; 399 PerRegionTable** _fine_grain_regions;
392 400
439 bool fine_has_next(size_t& card_index); 447 bool fine_has_next(size_t& card_index);
440 448
441 public: 449 public:
442 // We require an iterator to be initialized before use, so the 450 // We require an iterator to be initialized before use, so the
443 // constructor does little. 451 // constructor does little.
444 HeapRegionRemSetIterator(const HeapRegionRemSet* hrrs); 452 HeapRegionRemSetIterator(HeapRegionRemSet* hrrs);
445 453
446 // If there remains one or more cards to be yielded, returns true and 454 // 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 455 // sets "card_index" to one of those cards (which is then considered
448 // yielded.) Otherwise, returns false (and leaves "card_index" 456 // yielded.) Otherwise, returns false (and leaves "card_index"
449 // undefined.) 457 // undefined.)