25 #ifndef SHARE_VM_GC_G1_HEAPREGIONREMSET_HPP
26 #define SHARE_VM_GC_G1_HEAPREGIONREMSET_HPP
27
28 #include "gc/g1/g1CodeCacheRemSet.hpp"
29 #include "gc/g1/g1FromCardCache.hpp"
30 #include "gc/g1/sparsePRT.hpp"
31
32 // Remembered set for a heap region. Represent a set of "cards" that
33 // contain pointers into the owner heap region. Cards are defined somewhat
34 // abstractly, in terms of what the "BlockOffsetTable" in use can parse.
35
36 class G1CollectedHeap;
37 class G1BlockOffsetTable;
38 class G1CardLiveData;
39 class HeapRegion;
40 class HeapRegionRemSetIterator;
41 class PerRegionTable;
42 class SparsePRT;
43 class nmethod;
44
45 // Essentially a wrapper around SparsePRTCleanupTask. See
46 // sparsePRT.hpp for more details.
47 class HRRSCleanupTask : public SparsePRTCleanupTask {
48 };
49
50 // The "_coarse_map" is a bitmap with one bit for each region, where set
51 // bits indicate that the corresponding region may contain some pointer
52 // into the owning region.
53
54 // The "_fine_grain_entries" array is an open hash table of PerRegionTables
55 // (PRTs), indicating regions for which we're keeping the RS as a set of
56 // cards. The strategy is to cap the size of the fine-grain table,
57 // deleting an entry and setting the corresponding coarse-grained bit when
58 // we would overflow this cap.
59
60 // We use a mixture of locking and lock-free techniques here. We allow
61 // threads to locate PRTs without locking, but threads attempting to alter
62 // a bucket list obtain a lock. This means that any failing attempt to
63 // find a PRT must be retried with the lock. It might seem dangerous that
64 // a read can find a PRT that is concurrently deleted. This is all right,
65 // because:
66 //
67 // 1) We only actually free PRT's at safe points (though we reuse them at
68 // other times).
69 // 2) We find PRT's in an attempt to add entries. If a PRT is deleted,
105 static size_t _max_fine_entries;
106 static size_t _mod_max_fine_entries_mask;
107
108 // Requires "prt" to be the first element of the bucket list appropriate
109 // for "hr". If this list contains an entry for "hr", return it,
110 // otherwise return "NULL".
111 PerRegionTable* find_region_table(size_t ind, HeapRegion* hr) const;
112
113 // Find, delete, and return a candidate PerRegionTable, if any exists,
114 // adding the deleted region to the coarse bitmap. Requires the caller
115 // to hold _m, and the fine-grain table to be full.
116 PerRegionTable* delete_region_table();
117
118 // link/add the given fine grain remembered set into the "all" list
119 void link_to_all(PerRegionTable * prt);
120 // unlink/remove the given fine grain remembered set into the "all" list
121 void unlink_from_all(PerRegionTable * prt);
122
123 bool contains_reference_locked(OopOrNarrowOopStar from) const;
124
125 public:
126 // Create a new remembered set. The given mutex is used to ensure consistency.
127 OtherRegionsTable(Mutex* m);
128
129 // Returns the card index of the given within_region pointer relative to the bottom
130 // of the given heap region.
131 static CardIdx_t card_within_region(OopOrNarrowOopStar within_region, HeapRegion* hr);
132 // Adds the reference from "from to this remembered set.
133 void add_reference(OopOrNarrowOopStar from, uint tid);
134
135 // Returns whether the remembered set contains the given reference.
136 bool contains_reference(OopOrNarrowOopStar from) const;
137
138 // Returns whether this remembered set (and all sub-sets) have an occupancy
139 // that is less or equal than the given occupancy.
140 bool occupancy_less_or_equal_than(size_t limit) const;
141
142 // Returns whether this remembered set (and all sub-sets) does not contain any entry.
143 bool is_empty() const;
144
145 // Returns the number of cards contained in this remembered set.
146 size_t occupied() const;
147 size_t occ_fine() const;
148 size_t occ_coarse() const;
149 size_t occ_sparse() const;
150
151 static jint n_coarsenings() { return _n_coarsenings; }
152
153 // Returns size of the actual remembered set containers in bytes.
154 size_t mem_size() const;
155 // Returns the size of static data in bytes.
156 static size_t static_mem_size();
157 // Returns the size of the free list content in bytes.
158 static size_t fl_mem_size();
159
160 // Clear the entire contents of this remembered set.
161 void clear();
162
163 void do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task);
164 };
165
166 class HeapRegionRemSet : public CHeapObj<mtGC> {
167 friend class VMStructs;
168 friend class HeapRegionRemSetIterator;
169
170 private:
171 G1BlockOffsetTable* _bot;
172
173 // A set of code blobs (nmethods) whose code contains pointers into
174 // the region that owns this RSet.
175 G1CodeRootSet _code_roots;
176
177 Mutex _m;
178
179 OtherRegionsTable _other_regions;
180
181 HeapRegion* _hr;
182
183 void clear_fcc();
189
190 bool cardset_is_empty() const {
191 return _other_regions.is_empty();
192 }
193
194 bool is_empty() const {
195 return (strong_code_roots_list_length() == 0) && cardset_is_empty();
196 }
197
198 bool occupancy_less_or_equal_than(size_t occ) const {
199 return (strong_code_roots_list_length() == 0) && _other_regions.occupancy_less_or_equal_than(occ);
200 }
201
202 size_t occupied() {
203 MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag);
204 return occupied_locked();
205 }
206 size_t occupied_locked() {
207 return _other_regions.occupied();
208 }
209 size_t occ_fine() const {
210 return _other_regions.occ_fine();
211 }
212 size_t occ_coarse() const {
213 return _other_regions.occ_coarse();
214 }
215 size_t occ_sparse() const {
216 return _other_regions.occ_sparse();
217 }
218
219 static jint n_coarsenings() { return OtherRegionsTable::n_coarsenings(); }
220
221 private:
222 enum RemSetState {
223 Untracked,
224 Updating,
225 Complete
226 };
227
228 RemSetState _state;
229
230 static const char* _state_strings[];
231 static const char* _short_state_strings[];
232 public:
233
234 const char* get_state_str() const { return _state_strings[_state]; }
235 const char* get_short_state_str() const { return _short_state_strings[_state]; }
236
237 bool is_tracked() { return _state != Untracked; }
323 // the strong code roots list
324 void strong_code_roots_do(CodeBlobClosure* blk) const;
325
326 void clean_strong_code_roots(HeapRegion* hr);
327
328 // Returns the number of elements in the strong code roots list
329 size_t strong_code_roots_list_length() const {
330 return _code_roots.length();
331 }
332
333 // Returns true if the strong code roots contains the given
334 // nmethod.
335 bool strong_code_roots_list_contains(nmethod* nm) {
336 return _code_roots.contains(nm);
337 }
338
339 // Returns the amount of memory, in bytes, currently
340 // consumed by the strong code roots.
341 size_t strong_code_roots_mem_size();
342
343 // Called during a stop-world phase to perform any deferred cleanups.
344 static void cleanup();
345
346 static void invalidate_from_card_cache(uint start_idx, size_t num_regions) {
347 G1FromCardCache::invalidate(start_idx, num_regions);
348 }
349
350 #ifndef PRODUCT
351 static void print_from_card_cache() {
352 G1FromCardCache::print();
353 }
354 #endif
355
356 // These are wrappers for the similarly-named methods on
357 // SparsePRT. Look at sparsePRT.hpp for more details.
358 static void reset_for_cleanup_tasks();
359 void do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task);
360 static void finish_cleanup_task(HRRSCleanupTask* hrrs_cleanup_task);
361
362 // Run unit tests.
363 #ifndef PRODUCT
364 static void test();
365 #endif
366 };
367
368 class HeapRegionRemSetIterator : public StackObj {
369 private:
370 // The region RSet over which we are iterating.
371 HeapRegionRemSet* _hrrs;
372
373 // Local caching of HRRS fields.
374 const BitMap* _coarse_map;
375
376 G1BlockOffsetTable* _bot;
377 G1CollectedHeap* _g1h;
378
379 // The number of cards yielded since initialization.
380 size_t _n_yielded_fine;
381 size_t _n_yielded_coarse;
382 size_t _n_yielded_sparse;
383
|
25 #ifndef SHARE_VM_GC_G1_HEAPREGIONREMSET_HPP
26 #define SHARE_VM_GC_G1_HEAPREGIONREMSET_HPP
27
28 #include "gc/g1/g1CodeCacheRemSet.hpp"
29 #include "gc/g1/g1FromCardCache.hpp"
30 #include "gc/g1/sparsePRT.hpp"
31
32 // Remembered set for a heap region. Represent a set of "cards" that
33 // contain pointers into the owner heap region. Cards are defined somewhat
34 // abstractly, in terms of what the "BlockOffsetTable" in use can parse.
35
36 class G1CollectedHeap;
37 class G1BlockOffsetTable;
38 class G1CardLiveData;
39 class HeapRegion;
40 class HeapRegionRemSetIterator;
41 class PerRegionTable;
42 class SparsePRT;
43 class nmethod;
44
45 // The "_coarse_map" is a bitmap with one bit for each region, where set
46 // bits indicate that the corresponding region may contain some pointer
47 // into the owning region.
48
49 // The "_fine_grain_entries" array is an open hash table of PerRegionTables
50 // (PRTs), indicating regions for which we're keeping the RS as a set of
51 // cards. The strategy is to cap the size of the fine-grain table,
52 // deleting an entry and setting the corresponding coarse-grained bit when
53 // we would overflow this cap.
54
55 // We use a mixture of locking and lock-free techniques here. We allow
56 // threads to locate PRTs without locking, but threads attempting to alter
57 // a bucket list obtain a lock. This means that any failing attempt to
58 // find a PRT must be retried with the lock. It might seem dangerous that
59 // a read can find a PRT that is concurrently deleted. This is all right,
60 // because:
61 //
62 // 1) We only actually free PRT's at safe points (though we reuse them at
63 // other times).
64 // 2) We find PRT's in an attempt to add entries. If a PRT is deleted,
100 static size_t _max_fine_entries;
101 static size_t _mod_max_fine_entries_mask;
102
103 // Requires "prt" to be the first element of the bucket list appropriate
104 // for "hr". If this list contains an entry for "hr", return it,
105 // otherwise return "NULL".
106 PerRegionTable* find_region_table(size_t ind, HeapRegion* hr) const;
107
108 // Find, delete, and return a candidate PerRegionTable, if any exists,
109 // adding the deleted region to the coarse bitmap. Requires the caller
110 // to hold _m, and the fine-grain table to be full.
111 PerRegionTable* delete_region_table();
112
113 // link/add the given fine grain remembered set into the "all" list
114 void link_to_all(PerRegionTable * prt);
115 // unlink/remove the given fine grain remembered set into the "all" list
116 void unlink_from_all(PerRegionTable * prt);
117
118 bool contains_reference_locked(OopOrNarrowOopStar from) const;
119
120 size_t occ_fine() const;
121 size_t occ_coarse() const;
122 size_t occ_sparse() const;
123
124 public:
125 // Create a new remembered set. The given mutex is used to ensure consistency.
126 OtherRegionsTable(Mutex* m);
127
128 // Returns the card index of the given within_region pointer relative to the bottom
129 // of the given heap region.
130 static CardIdx_t card_within_region(OopOrNarrowOopStar within_region, HeapRegion* hr);
131 // Adds the reference from "from to this remembered set.
132 void add_reference(OopOrNarrowOopStar from, uint tid);
133
134 // Returns whether the remembered set contains the given reference.
135 bool contains_reference(OopOrNarrowOopStar from) const;
136
137 // Returns whether this remembered set (and all sub-sets) have an occupancy
138 // that is less or equal than the given occupancy.
139 bool occupancy_less_or_equal_than(size_t limit) const;
140
141 // Returns whether this remembered set (and all sub-sets) does not contain any entry.
142 bool is_empty() const;
143
144 // Returns the number of cards contained in this remembered set.
145 size_t occupied() const;
146
147 static jint n_coarsenings() { return _n_coarsenings; }
148
149 // Returns size of the actual remembered set containers in bytes.
150 size_t mem_size() const;
151 // Returns the size of static data in bytes.
152 static size_t static_mem_size();
153 // Returns the size of the free list content in bytes.
154 static size_t fl_mem_size();
155
156 // Clear the entire contents of this remembered set.
157 void clear();
158 };
159
160 class HeapRegionRemSet : public CHeapObj<mtGC> {
161 friend class VMStructs;
162 friend class HeapRegionRemSetIterator;
163
164 private:
165 G1BlockOffsetTable* _bot;
166
167 // A set of code blobs (nmethods) whose code contains pointers into
168 // the region that owns this RSet.
169 G1CodeRootSet _code_roots;
170
171 Mutex _m;
172
173 OtherRegionsTable _other_regions;
174
175 HeapRegion* _hr;
176
177 void clear_fcc();
183
184 bool cardset_is_empty() const {
185 return _other_regions.is_empty();
186 }
187
188 bool is_empty() const {
189 return (strong_code_roots_list_length() == 0) && cardset_is_empty();
190 }
191
192 bool occupancy_less_or_equal_than(size_t occ) const {
193 return (strong_code_roots_list_length() == 0) && _other_regions.occupancy_less_or_equal_than(occ);
194 }
195
196 size_t occupied() {
197 MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag);
198 return occupied_locked();
199 }
200 size_t occupied_locked() {
201 return _other_regions.occupied();
202 }
203
204 static jint n_coarsenings() { return OtherRegionsTable::n_coarsenings(); }
205
206 private:
207 enum RemSetState {
208 Untracked,
209 Updating,
210 Complete
211 };
212
213 RemSetState _state;
214
215 static const char* _state_strings[];
216 static const char* _short_state_strings[];
217 public:
218
219 const char* get_state_str() const { return _state_strings[_state]; }
220 const char* get_short_state_str() const { return _short_state_strings[_state]; }
221
222 bool is_tracked() { return _state != Untracked; }
308 // the strong code roots list
309 void strong_code_roots_do(CodeBlobClosure* blk) const;
310
311 void clean_strong_code_roots(HeapRegion* hr);
312
313 // Returns the number of elements in the strong code roots list
314 size_t strong_code_roots_list_length() const {
315 return _code_roots.length();
316 }
317
318 // Returns true if the strong code roots contains the given
319 // nmethod.
320 bool strong_code_roots_list_contains(nmethod* nm) {
321 return _code_roots.contains(nm);
322 }
323
324 // Returns the amount of memory, in bytes, currently
325 // consumed by the strong code roots.
326 size_t strong_code_roots_mem_size();
327
328 static void invalidate_from_card_cache(uint start_idx, size_t num_regions) {
329 G1FromCardCache::invalidate(start_idx, num_regions);
330 }
331
332 #ifndef PRODUCT
333 static void print_from_card_cache() {
334 G1FromCardCache::print();
335 }
336
337 static void test();
338 #endif
339 };
340
341 class HeapRegionRemSetIterator : public StackObj {
342 private:
343 // The region RSet over which we are iterating.
344 HeapRegionRemSet* _hrrs;
345
346 // Local caching of HRRS fields.
347 const BitMap* _coarse_map;
348
349 G1BlockOffsetTable* _bot;
350 G1CollectedHeap* _g1h;
351
352 // The number of cards yielded since initialization.
353 size_t _n_yielded_fine;
354 size_t _n_yielded_coarse;
355 size_t _n_yielded_sparse;
356
|