src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp

Sat, 06 Oct 2012 01:17:44 -0700

author
johnc
date
Sat, 06 Oct 2012 01:17:44 -0700
changeset 4173
8a5ea0a9ccc4
parent 3956
db823a892a55
child 5014
5c93c1f61226
permissions
-rw-r--r--

7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>

ysr@777 1 /*
johnc@3891 2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
ysr@777 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ysr@777 4 *
ysr@777 5 * This code is free software; you can redistribute it and/or modify it
ysr@777 6 * under the terms of the GNU General Public License version 2 only, as
ysr@777 7 * published by the Free Software Foundation.
ysr@777 8 *
ysr@777 9 * This code is distributed in the hope that it will be useful, but WITHOUT
ysr@777 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ysr@777 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ysr@777 12 * version 2 for more details (a copy is included in the LICENSE file that
ysr@777 13 * accompanied this code).
ysr@777 14 *
ysr@777 15 * You should have received a copy of the GNU General Public License version
ysr@777 16 * 2 along with this work; if not, write to the Free Software Foundation,
ysr@777 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ysr@777 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
ysr@777 22 *
ysr@777 23 */
ysr@777 24
stefank@2314 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONREMSET_HPP
stefank@2314 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONREMSET_HPP
stefank@2314 27
stefank@2314 28 #include "gc_implementation/g1/sparsePRT.hpp"
stefank@2314 29
ysr@777 30 // Remembered set for a heap region. Represent a set of "cards" that
ysr@777 31 // contain pointers into the owner heap region. Cards are defined somewhat
ysr@777 32 // abstractly, in terms of what the "BlockOffsetTable" in use can parse.
ysr@777 33
ysr@777 34 class G1CollectedHeap;
ysr@777 35 class G1BlockOffsetSharedArray;
ysr@777 36 class HeapRegion;
ysr@777 37 class HeapRegionRemSetIterator;
johnc@3891 38 class PerRegionTable;
ysr@777 39 class SparsePRT;
ysr@777 40
tonyp@2493 41 // Essentially a wrapper around SparsePRTCleanupTask. See
tonyp@2493 42 // sparsePRT.hpp for more details.
tonyp@2493 43 class HRRSCleanupTask : public SparsePRTCleanupTask {
tonyp@2493 44 };
ysr@777 45
ysr@777 46 // The "_coarse_map" is a bitmap with one bit for each region, where set
ysr@777 47 // bits indicate that the corresponding region may contain some pointer
ysr@777 48 // into the owning region.
ysr@777 49
ysr@777 50 // The "_fine_grain_entries" array is an open hash table of PerRegionTables
ysr@777 51 // (PRTs), indicating regions for which we're keeping the RS as a set of
ysr@777 52 // cards. The strategy is to cap the size of the fine-grain table,
ysr@777 53 // deleting an entry and setting the corresponding coarse-grained bit when
ysr@777 54 // we would overflow this cap.
ysr@777 55
ysr@777 56 // We use a mixture of locking and lock-free techniques here. We allow
ysr@777 57 // threads to locate PRTs without locking, but threads attempting to alter
ysr@777 58 // a bucket list obtain a lock. This means that any failing attempt to
ysr@777 59 // find a PRT must be retried with the lock. It might seem dangerous that
ysr@777 60 // a read can find a PRT that is concurrently deleted. This is all right,
ysr@777 61 // because:
ysr@777 62 //
ysr@777 63 // 1) We only actually free PRT's at safe points (though we reuse them at
ysr@777 64 // other times).
ysr@777 65 // 2) We find PRT's in an attempt to add entries. If a PRT is deleted,
ysr@777 66 // it's _coarse_map bit is set, so the that we were attempting to add
ysr@777 67 // is represented. If a deleted PRT is re-used, a thread adding a bit,
ysr@777 68 // thinking the PRT is for a different region, does no harm.
ysr@777 69
apetrusenko@984 70 class OtherRegionsTable VALUE_OBJ_CLASS_SPEC {
ysr@777 71 friend class HeapRegionRemSetIterator;
ysr@777 72
ysr@777 73 G1CollectedHeap* _g1h;
ysr@777 74 Mutex _m;
ysr@777 75 HeapRegion* _hr;
ysr@777 76
ysr@777 77 // These are protected by "_m".
ysr@777 78 BitMap _coarse_map;
ysr@777 79 size_t _n_coarse_entries;
ysr@777 80 static jint _n_coarsenings;
ysr@777 81
johnc@3891 82 PerRegionTable** _fine_grain_regions;
johnc@3891 83 size_t _n_fine_entries;
ysr@777 84
johnc@3956 85 // The fine grain remembered sets are doubly linked together using
johnc@3956 86 // their 'next' and 'prev' fields.
johnc@3956 87 // This allows fast bulk freeing of all the fine grain remembered
johnc@3956 88 // set entries, and fast finding of all of them without iterating
johnc@3956 89 // over the _fine_grain_regions table.
johnc@3956 90 PerRegionTable * _first_all_fine_prts;
johnc@3956 91 PerRegionTable * _last_all_fine_prts;
johnc@3956 92
johnc@3891 93 // Used to sample a subset of the fine grain PRTs to determine which
johnc@3891 94 // PRT to evict and coarsen.
ysr@777 95 size_t _fine_eviction_start;
ysr@777 96 static size_t _fine_eviction_stride;
ysr@777 97 static size_t _fine_eviction_sample_size;
ysr@777 98
ysr@777 99 SparsePRT _sparse_table;
ysr@777 100
ysr@777 101 // These are static after init.
ysr@777 102 static size_t _max_fine_entries;
ysr@777 103 static size_t _mod_max_fine_entries_mask;
ysr@777 104
ysr@777 105 // Requires "prt" to be the first element of the bucket list appropriate
ysr@777 106 // for "hr". If this list contains an entry for "hr", return it,
ysr@777 107 // otherwise return "NULL".
johnc@3891 108 PerRegionTable* find_region_table(size_t ind, HeapRegion* hr) const;
ysr@777 109
johnc@3891 110 // Find, delete, and return a candidate PerRegionTable, if any exists,
ysr@777 111 // adding the deleted region to the coarse bitmap. Requires the caller
ysr@777 112 // to hold _m, and the fine-grain table to be full.
johnc@3891 113 PerRegionTable* delete_region_table();
ysr@777 114
ysr@777 115 // If a PRT for "hr" is in the bucket list indicated by "ind" (which must
ysr@777 116 // be the correct index for "hr"), delete it and return true; else return
ysr@777 117 // false.
ysr@777 118 bool del_single_region_table(size_t ind, HeapRegion* hr);
ysr@777 119
ysr@777 120 // Indexed by thread X heap region, to minimize thread contention.
ysr@777 121 static int** _from_card_cache;
ysr@777 122 static size_t _from_card_cache_max_regions;
ysr@777 123 static size_t _from_card_cache_mem_size;
ysr@777 124
johnc@3956 125 // link/add the given fine grain remembered set into the "all" list
johnc@3956 126 void link_to_all(PerRegionTable * prt);
johnc@3956 127 // unlink/remove the given fine grain remembered set into the "all" list
johnc@3956 128 void unlink_from_all(PerRegionTable * prt);
johnc@3956 129
ysr@777 130 public:
ysr@777 131 OtherRegionsTable(HeapRegion* hr);
ysr@777 132
ysr@777 133 HeapRegion* hr() const { return _hr; }
ysr@777 134
ysr@777 135 // For now. Could "expand" some tables in the future, so that this made
ysr@777 136 // sense.
ysr@1280 137 void add_reference(OopOrNarrowOopStar from, int tid);
ysr@777 138
ysr@777 139 // Removes any entries shown by the given bitmaps to contain only dead
ysr@777 140 // objects.
ysr@777 141 void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm);
ysr@777 142
ysr@777 143 // Not const because it takes a lock.
ysr@777 144 size_t occupied() const;
ysr@777 145 size_t occ_fine() const;
ysr@777 146 size_t occ_coarse() const;
ysr@777 147 size_t occ_sparse() const;
ysr@777 148
ysr@777 149 static jint n_coarsenings() { return _n_coarsenings; }
ysr@777 150
ysr@777 151 // Returns size in bytes.
ysr@777 152 // Not const because it takes a lock.
ysr@777 153 size_t mem_size() const;
ysr@777 154 static size_t static_mem_size();
ysr@777 155 static size_t fl_mem_size();
ysr@777 156
ysr@1280 157 bool contains_reference(OopOrNarrowOopStar from) const;
ysr@1280 158 bool contains_reference_locked(OopOrNarrowOopStar from) const;
ysr@777 159
ysr@777 160 void clear();
ysr@777 161
ysr@777 162 // Specifically clear the from_card_cache.
ysr@777 163 void clear_fcc();
ysr@777 164
ysr@777 165 // "from_hr" is being cleared; remove any entries from it.
ysr@777 166 void clear_incoming_entry(HeapRegion* from_hr);
ysr@777 167
tonyp@2493 168 void do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task);
tonyp@2493 169
ysr@777 170 // Declare the heap size (in # of regions) to the OtherRegionsTable.
ysr@777 171 // (Uses it to initialize from_card_cache).
ysr@777 172 static void init_from_card_cache(size_t max_regions);
ysr@777 173
ysr@777 174 // Declares that only regions i s.t. 0 <= i < new_n_regs are in use.
ysr@777 175 // Make sure any entries for higher regions are invalid.
ysr@777 176 static void shrink_from_card_cache(size_t new_n_regs);
ysr@777 177
ysr@777 178 static void print_from_card_cache();
ysr@777 179 };
ysr@777 180
zgu@3900 181 class HeapRegionRemSet : public CHeapObj<mtGC> {
ysr@777 182 friend class VMStructs;
ysr@777 183 friend class HeapRegionRemSetIterator;
ysr@777 184
ysr@777 185 public:
ysr@777 186 enum Event {
ysr@777 187 Event_EvacStart, Event_EvacEnd, Event_RSUpdateEnd
ysr@777 188 };
ysr@777 189
ysr@777 190 private:
ysr@777 191 G1BlockOffsetSharedArray* _bosa;
ysr@777 192 G1BlockOffsetSharedArray* bosa() const { return _bosa; }
ysr@777 193
ysr@777 194 OtherRegionsTable _other_regions;
ysr@777 195
ysr@777 196 enum ParIterState { Unclaimed, Claimed, Complete };
iveresov@1696 197 volatile ParIterState _iter_state;
iveresov@1696 198 volatile jlong _iter_claimed;
ysr@777 199
ysr@777 200 // Unused unless G1RecordHRRSOops is true.
ysr@777 201
ysr@777 202 static const int MaxRecorded = 1000000;
ysr@1280 203 static OopOrNarrowOopStar* _recorded_oops;
ysr@1280 204 static HeapWord** _recorded_cards;
ysr@1280 205 static HeapRegion** _recorded_regions;
ysr@1280 206 static int _n_recorded;
ysr@777 207
ysr@777 208 static const int MaxRecordedEvents = 1000;
ysr@777 209 static Event* _recorded_events;
ysr@777 210 static int* _recorded_event_index;
ysr@777 211 static int _n_recorded_events;
ysr@777 212
ysr@777 213 static void print_event(outputStream* str, Event evnt);
ysr@777 214
ysr@777 215 public:
ysr@777 216 HeapRegionRemSet(G1BlockOffsetSharedArray* bosa,
ysr@777 217 HeapRegion* hr);
ysr@777 218
ysr@777 219 static int num_par_rem_sets();
iveresov@1696 220 static void setup_remset_size();
ysr@777 221
ysr@777 222 HeapRegion* hr() const {
ysr@777 223 return _other_regions.hr();
ysr@777 224 }
ysr@777 225
ysr@777 226 size_t occupied() const {
ysr@777 227 return _other_regions.occupied();
ysr@777 228 }
ysr@777 229 size_t occ_fine() const {
ysr@777 230 return _other_regions.occ_fine();
ysr@777 231 }
ysr@777 232 size_t occ_coarse() const {
ysr@777 233 return _other_regions.occ_coarse();
ysr@777 234 }
ysr@777 235 size_t occ_sparse() const {
ysr@777 236 return _other_regions.occ_sparse();
ysr@777 237 }
ysr@777 238
ysr@777 239 static jint n_coarsenings() { return OtherRegionsTable::n_coarsenings(); }
ysr@777 240
johnc@3891 241 // Used in the sequential case.
ysr@1280 242 void add_reference(OopOrNarrowOopStar from) {
johnc@3891 243 _other_regions.add_reference(from, 0);
ysr@777 244 }
ysr@777 245
johnc@3891 246 // Used in the parallel case.
ysr@1280 247 void add_reference(OopOrNarrowOopStar from, int tid) {
ysr@777 248 _other_regions.add_reference(from, tid);
ysr@777 249 }
ysr@777 250
ysr@777 251 // Removes any entries shown by the given bitmaps to contain only dead
ysr@777 252 // objects.
ysr@777 253 void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm);
ysr@777 254
ysr@777 255 // The region is being reclaimed; clear its remset, and any mention of
ysr@777 256 // entries for this region in other remsets.
ysr@777 257 void clear();
ysr@777 258
ysr@777 259 // Attempt to claim the region. Returns true iff this call caused an
ysr@777 260 // atomic transition from Unclaimed to Claimed.
ysr@777 261 bool claim_iter();
ysr@777 262 // Sets the iteration state to "complete".
ysr@777 263 void set_iter_complete();
ysr@777 264 // Returns "true" iff the region's iteration is complete.
ysr@777 265 bool iter_is_complete();
ysr@777 266
iveresov@1696 267 // Support for claiming blocks of cards during iteration
iveresov@1696 268 size_t iter_claimed() const { return (size_t)_iter_claimed; }
iveresov@1696 269 // Claim the next block of cards
iveresov@1696 270 size_t iter_claimed_next(size_t step) {
iveresov@1696 271 size_t current, next;
iveresov@1696 272 do {
iveresov@1696 273 current = iter_claimed();
iveresov@1696 274 next = current + step;
iveresov@1696 275 } while (Atomic::cmpxchg((jlong)next, &_iter_claimed, (jlong)current) != (jlong)current);
iveresov@1696 276 return current;
iveresov@1696 277 }
tonyp@2974 278 void reset_for_par_iteration();
tonyp@2974 279
tonyp@2974 280 bool verify_ready_for_par_iteration() {
tonyp@2974 281 return (_iter_state == Unclaimed) && (_iter_claimed == 0);
tonyp@2974 282 }
iveresov@1696 283
ysr@777 284 // Initialize the given iterator to iterate over this rem set.
ysr@777 285 void init_iterator(HeapRegionRemSetIterator* iter) const;
ysr@777 286
ysr@777 287 // The actual # of bytes this hr_remset takes up.
ysr@777 288 size_t mem_size() {
ysr@777 289 return _other_regions.mem_size()
ysr@777 290 // This correction is necessary because the above includes the second
ysr@777 291 // part.
ysr@777 292 + sizeof(this) - sizeof(OtherRegionsTable);
ysr@777 293 }
ysr@777 294
ysr@777 295 // Returns the memory occupancy of all static data structures associated
ysr@777 296 // with remembered sets.
ysr@777 297 static size_t static_mem_size() {
ysr@777 298 return OtherRegionsTable::static_mem_size();
ysr@777 299 }
ysr@777 300
ysr@777 301 // Returns the memory occupancy of all free_list data structures associated
ysr@777 302 // with remembered sets.
ysr@777 303 static size_t fl_mem_size() {
ysr@777 304 return OtherRegionsTable::fl_mem_size();
ysr@777 305 }
ysr@777 306
ysr@1280 307 bool contains_reference(OopOrNarrowOopStar from) const {
ysr@777 308 return _other_regions.contains_reference(from);
ysr@777 309 }
ysr@777 310 void print() const;
ysr@777 311
ysr@777 312 // Called during a stop-world phase to perform any deferred cleanups.
ysr@777 313 static void cleanup();
ysr@777 314
ysr@777 315 // Declare the heap size (in # of regions) to the HeapRegionRemSet(s).
ysr@777 316 // (Uses it to initialize from_card_cache).
tonyp@3713 317 static void init_heap(uint max_regions) {
tonyp@3713 318 OtherRegionsTable::init_from_card_cache((size_t) max_regions);
ysr@777 319 }
ysr@777 320
ysr@777 321 // Declares that only regions i s.t. 0 <= i < new_n_regs are in use.
tonyp@3713 322 static void shrink_heap(uint new_n_regs) {
tonyp@3713 323 OtherRegionsTable::shrink_from_card_cache((size_t) new_n_regs);
ysr@777 324 }
ysr@777 325
ysr@777 326 #ifndef PRODUCT
ysr@777 327 static void print_from_card_cache() {
ysr@777 328 OtherRegionsTable::print_from_card_cache();
ysr@777 329 }
ysr@777 330 #endif
ysr@777 331
ysr@1280 332 static void record(HeapRegion* hr, OopOrNarrowOopStar f);
ysr@777 333 static void print_recorded();
ysr@777 334 static void record_event(Event evnt);
ysr@777 335
tonyp@2493 336 // These are wrappers for the similarly-named methods on
tonyp@2493 337 // SparsePRT. Look at sparsePRT.hpp for more details.
tonyp@2493 338 static void reset_for_cleanup_tasks();
tonyp@2493 339 void do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task);
tonyp@2493 340 static void finish_cleanup_task(HRRSCleanupTask* hrrs_cleanup_task);
tonyp@2493 341
ysr@777 342 // Run unit tests.
ysr@777 343 #ifndef PRODUCT
ysr@777 344 static void test();
ysr@777 345 #endif
ysr@777 346 };
ysr@777 347
zgu@3900 348 class HeapRegionRemSetIterator : public CHeapObj<mtGC> {
ysr@777 349
ysr@777 350 // The region over which we're iterating.
ysr@777 351 const HeapRegionRemSet* _hrrs;
ysr@777 352
ysr@777 353 // Local caching of HRRS fields.
ysr@777 354 const BitMap* _coarse_map;
johnc@3891 355 PerRegionTable** _fine_grain_regions;
ysr@777 356
ysr@777 357 G1BlockOffsetSharedArray* _bosa;
ysr@777 358 G1CollectedHeap* _g1h;
ysr@777 359
ysr@777 360 // The number yielded since initialization.
ysr@777 361 size_t _n_yielded_fine;
ysr@777 362 size_t _n_yielded_coarse;
ysr@777 363 size_t _n_yielded_sparse;
ysr@777 364
ysr@777 365 // If true we're iterating over the coarse table; if false the fine
ysr@777 366 // table.
ysr@777 367 enum IterState {
ysr@777 368 Sparse,
ysr@777 369 Fine,
ysr@777 370 Coarse
ysr@777 371 };
ysr@777 372 IterState _is;
ysr@777 373
ysr@777 374 // In both kinds of iteration, heap offset of first card of current
ysr@777 375 // region.
ysr@777 376 size_t _cur_region_card_offset;
ysr@777 377 // Card offset within cur region.
ysr@777 378 size_t _cur_region_cur_card;
ysr@777 379
ysr@777 380 // Coarse table iteration fields:
ysr@777 381
ysr@777 382 // Current region index;
johnc@3182 383 int _coarse_cur_region_index;
johnc@3182 384 size_t _coarse_cur_region_cur_card;
ysr@777 385
ysr@777 386 bool coarse_has_next(size_t& card_index);
ysr@777 387
ysr@777 388 // Fine table iteration fields:
ysr@777 389
ysr@777 390 // Index of bucket-list we're working on.
ysr@777 391 int _fine_array_index;
johnc@3891 392
ysr@777 393 // Per Region Table we're doing within current bucket list.
johnc@3891 394 PerRegionTable* _fine_cur_prt;
ysr@777 395
ysr@777 396 /* SparsePRT::*/ SparsePRTIter _sparse_iter;
ysr@777 397
ysr@777 398 void fine_find_next_non_null_prt();
ysr@777 399
ysr@777 400 bool fine_has_next();
ysr@777 401 bool fine_has_next(size_t& card_index);
ysr@777 402
ysr@777 403 public:
ysr@777 404 // We require an iterator to be initialized before use, so the
ysr@777 405 // constructor does little.
ysr@777 406 HeapRegionRemSetIterator();
ysr@777 407
ysr@777 408 void initialize(const HeapRegionRemSet* hrrs);
ysr@777 409
ysr@777 410 // If there remains one or more cards to be yielded, returns true and
ysr@777 411 // sets "card_index" to one of those cards (which is then considered
ysr@777 412 // yielded.) Otherwise, returns false (and leaves "card_index"
ysr@777 413 // undefined.)
ysr@777 414 bool has_next(size_t& card_index);
ysr@777 415
ysr@777 416 size_t n_yielded_fine() { return _n_yielded_fine; }
ysr@777 417 size_t n_yielded_coarse() { return _n_yielded_coarse; }
ysr@777 418 size_t n_yielded_sparse() { return _n_yielded_sparse; }
ysr@777 419 size_t n_yielded() {
ysr@777 420 return n_yielded_fine() + n_yielded_coarse() + n_yielded_sparse();
ysr@777 421 }
ysr@777 422 };
ysr@777 423
stefank@2314 424 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONREMSET_HPP

mercurial