Mercurial > hg > graal-jvmci-8
annotate src/share/vm/memory/cardTableModRefBS.hpp @ 12233:40136aa2cdb1
8010722: assert: failed: heap size is too big for compressed oops
Summary: Use conservative assumptions of required alignment for the various garbage collector components into account when determining the maximum heap size that supports compressed oops. Using this conservative value avoids several circular dependencies in the calculation.
Reviewed-by: stefank, dholmes
author | tschatzl |
---|---|
date | Wed, 11 Sep 2013 16:25:02 +0200 |
parents | f9be75d21404 |
children | 836a62f43af9 d55c004e1d4d |
rev | line source |
---|---|
0 | 1 /* |
10271
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10135
diff
changeset
|
2 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. |
0 | 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:
1261
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1261
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:
1261
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_MEMORY_CARDTABLEMODREFBS_HPP |
26 #define SHARE_VM_MEMORY_CARDTABLEMODREFBS_HPP | |
27 | |
28 #include "memory/modRefBarrierSet.hpp" | |
29 #include "oops/oop.hpp" | |
30 #include "oops/oop.inline2.hpp" | |
31 | |
0 | 32 // This kind of "BarrierSet" allows a "CollectedHeap" to detect and |
33 // enumerate ref fields that have been modified (since the last | |
34 // enumeration.) | |
35 | |
36 // As it currently stands, this barrier is *imprecise*: when a ref field in | |
37 // an object "o" is modified, the card table entry for the card containing | |
38 // the head of "o" is dirtied, not necessarily the card containing the | |
39 // modified field itself. For object arrays, however, the barrier *is* | |
40 // precise; only the card containing the modified element is dirtied. | |
41 // Any MemRegionClosures used to scan dirty cards should take these | |
42 // considerations into account. | |
43 | |
44 class Generation; | |
45 class OopsInGenClosure; | |
46 class DirtyCardToOopClosure; | |
3287
c48ad6ab8bdf
7037276: Unnecessary double traversal of dirty card windows
ysr
parents:
3256
diff
changeset
|
47 class ClearNoncleanCardWrapper; |
0 | 48 |
49 class CardTableModRefBS: public ModRefBarrierSet { | |
50 // Some classes get to look at some private stuff. | |
51 friend class BytecodeInterpreter; | |
52 friend class VMStructs; | |
53 friend class CardTableRS; | |
54 friend class CheckForUnmarkedOops; // Needs access to raw card bytes. | |
1692 | 55 friend class SharkBuilder; |
0 | 56 #ifndef PRODUCT |
57 // For debugging. | |
58 friend class GuaranteeNotModClosure; | |
59 #endif | |
60 protected: | |
61 | |
62 enum CardValues { | |
63 clean_card = -1, | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
64 // The mask contains zeros in places for all other values. |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
65 clean_card_mask = clean_card - 31, |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
66 |
0 | 67 dirty_card = 0, |
68 precleaned_card = 1, | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
69 claimed_card = 2, |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
70 deferred_card = 4, |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
71 last_card = 8, |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
72 CT_MR_BS_last_reserved = 16 |
0 | 73 }; |
74 | |
5939
c7a555a9449a
7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents:
4098
diff
changeset
|
75 // a word's worth (row) of clean card values |
c7a555a9449a
7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents:
4098
diff
changeset
|
76 static const intptr_t clean_card_row = (intptr_t)(-1); |
c7a555a9449a
7068625: Testing 8 bytes of card table entries at a time speeds up card-scanning
brutisso
parents:
4098
diff
changeset
|
77 |
0 | 78 // dirty and precleaned are equivalent wrt younger_refs_iter. |
79 static bool card_is_dirty_wrt_gen_iter(jbyte cv) { | |
80 return cv == dirty_card || cv == precleaned_card; | |
81 } | |
82 | |
83 // Returns "true" iff the value "cv" will cause the card containing it | |
84 // to be scanned in the current traversal. May be overridden by | |
85 // subtypes. | |
86 virtual bool card_will_be_scanned(jbyte cv) { | |
87 return CardTableModRefBS::card_is_dirty_wrt_gen_iter(cv); | |
88 } | |
89 | |
90 // Returns "true" iff the value "cv" may have represented a dirty card at | |
91 // some point. | |
92 virtual bool card_may_have_been_dirty(jbyte cv) { | |
93 return card_is_dirty_wrt_gen_iter(cv); | |
94 } | |
95 | |
96 // The declaration order of these const fields is important; see the | |
97 // constructor before changing. | |
98 const MemRegion _whole_heap; // the region covered by the card table | |
99 const size_t _guard_index; // index of very last element in the card | |
100 // table; it is set to a guard value | |
101 // (last_card) and should never be modified | |
102 const size_t _last_valid_index; // index of the last valid element | |
103 const size_t _page_size; // page size used when mapping _byte_map | |
104 const size_t _byte_map_size; // in bytes | |
105 jbyte* _byte_map; // the card marking array | |
106 | |
107 int _cur_covered_regions; | |
108 // The covered regions should be in address order. | |
109 MemRegion* _covered; | |
110 // The committed regions correspond one-to-one to the covered regions. | |
111 // They represent the card-table memory that has been committed to service | |
112 // the corresponding covered region. It may be that committed region for | |
113 // one covered region corresponds to a larger region because of page-size | |
114 // roundings. Thus, a committed region for one covered region may | |
115 // actually extend onto the card-table space for the next covered region. | |
116 MemRegion* _committed; | |
117 | |
118 // The last card is a guard card, and we commit the page for it so | |
119 // we can use the card for verification purposes. We make sure we never | |
120 // uncommit the MemRegion for that page. | |
121 MemRegion _guard_region; | |
122 | |
123 protected: | |
124 // Initialization utilities; covered_words is the size of the covered region | |
125 // in, um, words. | |
126 inline size_t cards_required(size_t covered_words); | |
127 inline size_t compute_byte_map_size(); | |
128 | |
129 // Finds and return the index of the region, if any, to which the given | |
130 // region would be contiguous. If none exists, assign a new region and | |
131 // returns its index. Requires that no more than the maximum number of | |
132 // covered regions defined in the constructor are ever in use. | |
133 int find_covering_region_by_base(HeapWord* base); | |
134 | |
135 // Same as above, but finds the region containing the given address | |
136 // instead of starting at a given base address. | |
137 int find_covering_region_containing(HeapWord* addr); | |
138 | |
139 // Resize one of the regions covered by the remembered set. | |
140 void resize_covered_region(MemRegion new_region); | |
141 | |
142 // Returns the leftmost end of a committed region corresponding to a | |
143 // covered region before covered region "ind", or else "NULL" if "ind" is | |
144 // the first covered region. | |
145 HeapWord* largest_prev_committed_end(int ind) const; | |
146 | |
147 // Returns the part of the region mr that doesn't intersect with | |
148 // any committed region other than self. Used to prevent uncommitting | |
149 // regions that are also committed by other regions. Also protects | |
150 // against uncommitting the guard region. | |
151 MemRegion committed_unique_to_self(int self, MemRegion mr) const; | |
152 | |
153 // Mapping from address to card marking array entry | |
154 jbyte* byte_for(const void* p) const { | |
155 assert(_whole_heap.contains(p), | |
3359
7d64aa23eb96
7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents:
3357
diff
changeset
|
156 err_msg("Attempt to access p = "PTR_FORMAT" out of bounds of " |
7d64aa23eb96
7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents:
3357
diff
changeset
|
157 " card marking array's _whole_heap = ["PTR_FORMAT","PTR_FORMAT")", |
7d64aa23eb96
7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents:
3357
diff
changeset
|
158 p, _whole_heap.start(), _whole_heap.end())); |
0 | 159 jbyte* result = &byte_map_base[uintptr_t(p) >> card_shift]; |
160 assert(result >= _byte_map && result < _byte_map + _byte_map_size, | |
161 "out of bounds accessor for card marking array"); | |
162 return result; | |
163 } | |
164 | |
165 // The card table byte one after the card marking array | |
166 // entry for argument address. Typically used for higher bounds | |
167 // for loops iterating through the card table. | |
168 jbyte* byte_after(const void* p) const { | |
169 return byte_for(p) + 1; | |
170 } | |
171 | |
172 // Iterate over the portion of the card-table which covers the given | |
173 // region mr in the given space and apply cl to any dirty sub-regions | |
3287
c48ad6ab8bdf
7037276: Unnecessary double traversal of dirty card windows
ysr
parents:
3256
diff
changeset
|
174 // of mr. Dirty cards are _not_ cleared by the iterator method itself, |
c48ad6ab8bdf
7037276: Unnecessary double traversal of dirty card windows
ysr
parents:
3256
diff
changeset
|
175 // but closures may arrange to do so on their own should they so wish. |
c48ad6ab8bdf
7037276: Unnecessary double traversal of dirty card windows
ysr
parents:
3256
diff
changeset
|
176 void non_clean_card_iterate_serial(MemRegion mr, MemRegionClosure* cl); |
0 | 177 |
3287
c48ad6ab8bdf
7037276: Unnecessary double traversal of dirty card windows
ysr
parents:
3256
diff
changeset
|
178 // A variant of the above that will operate in a parallel mode if |
c48ad6ab8bdf
7037276: Unnecessary double traversal of dirty card windows
ysr
parents:
3256
diff
changeset
|
179 // worker threads are available, and clear the dirty cards as it |
c48ad6ab8bdf
7037276: Unnecessary double traversal of dirty card windows
ysr
parents:
3256
diff
changeset
|
180 // processes them. |
3357
fc2b798ab316
6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents:
3317
diff
changeset
|
181 // XXX ??? MemRegionClosure above vs OopsInGenClosure below XXX |
fc2b798ab316
6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents:
3317
diff
changeset
|
182 // XXX some new_dcto_cl's take OopClosure's, plus as above there are |
fc2b798ab316
6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents:
3317
diff
changeset
|
183 // some MemRegionClosures. Clean this up everywhere. XXX |
3287
c48ad6ab8bdf
7037276: Unnecessary double traversal of dirty card windows
ysr
parents:
3256
diff
changeset
|
184 void non_clean_card_iterate_possibly_parallel(Space* sp, MemRegion mr, |
3357
fc2b798ab316
6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents:
3317
diff
changeset
|
185 OopsInGenClosure* cl, CardTableRS* ct); |
0 | 186 |
3287
c48ad6ab8bdf
7037276: Unnecessary double traversal of dirty card windows
ysr
parents:
3256
diff
changeset
|
187 private: |
c48ad6ab8bdf
7037276: Unnecessary double traversal of dirty card windows
ysr
parents:
3256
diff
changeset
|
188 // Work method used to implement non_clean_card_iterate_possibly_parallel() |
c48ad6ab8bdf
7037276: Unnecessary double traversal of dirty card windows
ysr
parents:
3256
diff
changeset
|
189 // above in the parallel case. |
c48ad6ab8bdf
7037276: Unnecessary double traversal of dirty card windows
ysr
parents:
3256
diff
changeset
|
190 void non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr, |
3357
fc2b798ab316
6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents:
3317
diff
changeset
|
191 OopsInGenClosure* cl, CardTableRS* ct, |
3287
c48ad6ab8bdf
7037276: Unnecessary double traversal of dirty card windows
ysr
parents:
3256
diff
changeset
|
192 int n_threads); |
0 | 193 |
3287
c48ad6ab8bdf
7037276: Unnecessary double traversal of dirty card windows
ysr
parents:
3256
diff
changeset
|
194 protected: |
0 | 195 // Dirty the bytes corresponding to "mr" (not all of which must be |
196 // covered.) | |
197 void dirty_MemRegion(MemRegion mr); | |
198 | |
199 // Clear (to clean_card) the bytes entirely contained within "mr" (not | |
200 // all of which must be covered.) | |
201 void clear_MemRegion(MemRegion mr); | |
202 | |
203 // *** Support for parallel card scanning. | |
204 | |
205 // This is an array, one element per covered region of the card table. | |
206 // Each entry is itself an array, with one element per chunk in the | |
207 // covered region. Each entry of these arrays is the lowest non-clean | |
208 // card of the corresponding chunk containing part of an object from the | |
209 // previous chunk, or else NULL. | |
210 typedef jbyte* CardPtr; | |
211 typedef CardPtr* CardArr; | |
212 CardArr* _lowest_non_clean; | |
213 size_t* _lowest_non_clean_chunk_size; | |
214 uintptr_t* _lowest_non_clean_base_chunk_index; | |
215 int* _last_LNC_resizing_collection; | |
216 | |
217 // Initializes "lowest_non_clean" to point to the array for the region | |
218 // covering "sp", and "lowest_non_clean_base_chunk_index" to the chunk | |
219 // index of the corresponding to the first element of that array. | |
220 // Ensures that these arrays are of sufficient size, allocating if necessary. | |
221 // May be called by several threads concurrently. | |
222 void get_LNC_array_for_space(Space* sp, | |
223 jbyte**& lowest_non_clean, | |
224 uintptr_t& lowest_non_clean_base_chunk_index, | |
225 size_t& lowest_non_clean_chunk_size); | |
226 | |
227 // Returns the number of chunks necessary to cover "mr". | |
228 size_t chunks_to_cover(MemRegion mr) { | |
229 return (size_t)(addr_to_chunk_index(mr.last()) - | |
230 addr_to_chunk_index(mr.start()) + 1); | |
231 } | |
232 | |
233 // Returns the index of the chunk in a stride which | |
234 // covers the given address. | |
235 uintptr_t addr_to_chunk_index(const void* addr) { | |
236 uintptr_t card = (uintptr_t) byte_for(addr); | |
3357
fc2b798ab316
6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents:
3317
diff
changeset
|
237 return card / ParGCCardsPerStrideChunk; |
0 | 238 } |
239 | |
240 // Apply cl, which must either itself apply dcto_cl or be dcto_cl, | |
241 // to the cards in the stride (of n_strides) within the given space. | |
242 void process_stride(Space* sp, | |
243 MemRegion used, | |
244 jint stride, int n_strides, | |
3357
fc2b798ab316
6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents:
3317
diff
changeset
|
245 OopsInGenClosure* cl, |
fc2b798ab316
6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents:
3317
diff
changeset
|
246 CardTableRS* ct, |
0 | 247 jbyte** lowest_non_clean, |
248 uintptr_t lowest_non_clean_base_chunk_index, | |
249 size_t lowest_non_clean_chunk_size); | |
250 | |
251 // Makes sure that chunk boundaries are handled appropriately, by | |
252 // adjusting the min_done of dcto_cl, and by using a special card-table | |
253 // value to indicate how min_done should be set. | |
254 void process_chunk_boundaries(Space* sp, | |
255 DirtyCardToOopClosure* dcto_cl, | |
256 MemRegion chunk_mr, | |
257 MemRegion used, | |
258 jbyte** lowest_non_clean, | |
259 uintptr_t lowest_non_clean_base_chunk_index, | |
260 size_t lowest_non_clean_chunk_size); | |
261 | |
262 public: | |
263 // Constants | |
264 enum SomePublicConstants { | |
265 card_shift = 9, | |
266 card_size = 1 << card_shift, | |
267 card_size_in_words = card_size / sizeof(HeapWord) | |
268 }; | |
269 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
270 static int clean_card_val() { return clean_card; } |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
271 static int clean_card_mask_val() { return clean_card_mask; } |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
272 static int dirty_card_val() { return dirty_card; } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
273 static int claimed_card_val() { return claimed_card; } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
274 static int precleaned_card_val() { return precleaned_card; } |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
275 static int deferred_card_val() { return deferred_card; } |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
276 |
0 | 277 // For RTTI simulation. |
278 bool is_a(BarrierSet::Name bsn) { | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
279 return bsn == BarrierSet::CardTableModRef || ModRefBarrierSet::is_a(bsn); |
0 | 280 } |
281 | |
282 CardTableModRefBS(MemRegion whole_heap, int max_covered_regions); | |
10271
f9be75d21404
8012902: remove use of global operator new - take 2
minqi
parents:
10135
diff
changeset
|
283 ~CardTableModRefBS(); |
0 | 284 |
285 // *** Barrier set functions. | |
286 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
287 bool has_write_ref_pre_barrier() { return false; } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
288 |
0 | 289 // Record a reference update. Note that these versions are precise! |
290 // The scanning code has to handle the fact that the write barrier may be | |
291 // either precise or imprecise. We make non-virtual inline variants of | |
292 // these functions here for performance. | |
293 protected: | |
294 void write_ref_field_work(oop obj, size_t offset, oop newVal); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
628
diff
changeset
|
295 virtual void write_ref_field_work(void* field, oop newVal); |
0 | 296 public: |
297 | |
298 bool has_write_ref_array_opt() { return true; } | |
299 bool has_write_region_opt() { return true; } | |
300 | |
301 inline void inline_write_region(MemRegion mr) { | |
302 dirty_MemRegion(mr); | |
303 } | |
304 protected: | |
305 void write_region_work(MemRegion mr) { | |
306 inline_write_region(mr); | |
307 } | |
308 public: | |
309 | |
310 inline void inline_write_ref_array(MemRegion mr) { | |
311 dirty_MemRegion(mr); | |
312 } | |
313 protected: | |
314 void write_ref_array_work(MemRegion mr) { | |
315 inline_write_ref_array(mr); | |
316 } | |
317 public: | |
318 | |
319 bool is_aligned(HeapWord* addr) { | |
320 return is_card_aligned(addr); | |
321 } | |
322 | |
323 // *** Card-table-barrier-specific things. | |
324 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
628
diff
changeset
|
325 template <class T> inline void inline_write_ref_field_pre(T* field, oop newVal) {} |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
326 |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
628
diff
changeset
|
327 template <class T> inline void inline_write_ref_field(T* field, oop newVal) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
628
diff
changeset
|
328 jbyte* byte = byte_for((void*)field); |
0 | 329 *byte = dirty_card; |
330 } | |
331 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
332 // These are used by G1, when it uses the card table as a temporary data |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
333 // structure for card claiming. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
334 bool is_card_dirty(size_t card_index) { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
335 return _byte_map[card_index] == dirty_card_val(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
336 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
337 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
338 void mark_card_dirty(size_t card_index) { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
339 _byte_map[card_index] = dirty_card_val(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
340 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
341 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
342 bool is_card_claimed(size_t card_index) { |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
343 jbyte val = _byte_map[card_index]; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
344 return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val(); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
345 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
346 |
1261 | 347 void set_card_claimed(size_t card_index) { |
348 jbyte val = _byte_map[card_index]; | |
349 if (val == clean_card_val()) { | |
350 val = (jbyte)claimed_card_val(); | |
351 } else { | |
352 val |= (jbyte)claimed_card_val(); | |
353 } | |
354 _byte_map[card_index] = val; | |
355 } | |
356 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
357 bool claim_card(size_t card_index); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
358 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
359 bool is_card_clean(size_t card_index) { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
360 return _byte_map[card_index] == clean_card_val(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
361 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
362 |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
363 bool is_card_deferred(size_t card_index) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
364 jbyte val = _byte_map[card_index]; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
365 return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val(); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
366 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
367 |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
368 bool mark_card_deferred(size_t card_index); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
369 |
0 | 370 // Card marking array base (adjusted for heap low boundary) |
371 // This would be the 0th element of _byte_map, if the heap started at 0x0. | |
372 // But since the heap starts at some higher address, this points to somewhere | |
373 // before the beginning of the actual _byte_map. | |
374 jbyte* byte_map_base; | |
375 | |
376 // Return true if "p" is at the start of a card. | |
377 bool is_card_aligned(HeapWord* p) { | |
378 jbyte* pcard = byte_for(p); | |
379 return (addr_for(pcard) == p); | |
380 } | |
381 | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
1972
diff
changeset
|
382 HeapWord* align_to_card_boundary(HeapWord* p) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
1972
diff
changeset
|
383 jbyte* pcard = byte_for(p + card_size_in_words - 1); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
1972
diff
changeset
|
384 return addr_for(pcard); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
1972
diff
changeset
|
385 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
1972
diff
changeset
|
386 |
0 | 387 // The kinds of precision a CardTableModRefBS may offer. |
388 enum PrecisionStyle { | |
389 Precise, | |
390 ObjHeadPreciseArray | |
391 }; | |
392 | |
393 // Tells what style of precision this card table offers. | |
394 PrecisionStyle precision() { | |
395 return ObjHeadPreciseArray; // Only one supported for now. | |
396 } | |
397 | |
398 // ModRefBS functions. | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
399 virtual void invalidate(MemRegion mr, bool whole_heap = false); |
0 | 400 void clear(MemRegion mr); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
401 void dirty(MemRegion mr); |
0 | 402 |
403 // *** Card-table-RemSet-specific things. | |
404 | |
405 // Invoke "cl.do_MemRegion" on a set of MemRegions that collectively | |
406 // includes all the modified cards (expressing each card as a | |
407 // MemRegion). Thus, several modified cards may be lumped into one | |
408 // region. The regions are non-overlapping, and are visited in | |
409 // *decreasing* address order. (This order aids with imprecise card | |
410 // marking, where a dirty card may cause scanning, and summarization | |
411 // marking, of objects that extend onto subsequent cards.) | |
3256
c69b1043dfb1
7036482: clear argument is redundant and unused in cardtable methods
ysr
parents:
2433
diff
changeset
|
412 void mod_card_iterate(MemRegionClosure* cl) { |
3287
c48ad6ab8bdf
7037276: Unnecessary double traversal of dirty card windows
ysr
parents:
3256
diff
changeset
|
413 non_clean_card_iterate_serial(_whole_heap, cl); |
0 | 414 } |
415 | |
416 // Like the "mod_cards_iterate" above, except only invokes the closure | |
417 // for cards within the MemRegion "mr" (which is required to be | |
418 // card-aligned and sized.) | |
3256
c69b1043dfb1
7036482: clear argument is redundant and unused in cardtable methods
ysr
parents:
2433
diff
changeset
|
419 void mod_card_iterate(MemRegion mr, MemRegionClosure* cl) { |
3287
c48ad6ab8bdf
7037276: Unnecessary double traversal of dirty card windows
ysr
parents:
3256
diff
changeset
|
420 non_clean_card_iterate_serial(mr, cl); |
0 | 421 } |
422 | |
423 static uintx ct_max_alignment_constraint(); | |
424 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
425 // Apply closure "cl" to the dirty cards containing some part of |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
426 // MemRegion "mr". |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
427 void dirty_card_iterate(MemRegion mr, MemRegionClosure* cl); |
0 | 428 |
429 // Return the MemRegion corresponding to the first maximal run | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
430 // of dirty cards lying completely within MemRegion mr. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
431 // If reset is "true", then sets those card table entries to the given |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
432 // value. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
433 MemRegion dirty_card_range_after_reset(MemRegion mr, bool reset, |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
434 int reset_val); |
0 | 435 |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
436 // Provide read-only access to the card table array. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
437 const jbyte* byte_for_const(const void* p) const { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
438 return byte_for(p); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
439 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
440 const jbyte* byte_after_const(const void* p) const { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
441 return byte_after(p); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
442 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
443 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
444 // Mapping from card marking array entry to address of first word |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
445 HeapWord* addr_for(const jbyte* p) const { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
446 assert(p >= _byte_map && p < _byte_map + _byte_map_size, |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
447 "out of bounds access to card marking array"); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
448 size_t delta = pointer_delta(p, byte_map_base, sizeof(jbyte)); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
449 HeapWord* result = (HeapWord*) (delta << card_shift); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
450 assert(_whole_heap.contains(result), |
3359
7d64aa23eb96
7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents:
3357
diff
changeset
|
451 err_msg("Returning result = "PTR_FORMAT" out of bounds of " |
7d64aa23eb96
7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents:
3357
diff
changeset
|
452 " card marking array's _whole_heap = ["PTR_FORMAT","PTR_FORMAT")", |
7d64aa23eb96
7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents:
3357
diff
changeset
|
453 result, _whole_heap.start(), _whole_heap.end())); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
454 return result; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
455 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
456 |
0 | 457 // Mapping from address to card marking array index. |
489
2494ab195856
6653214: MemoryPoolMXBean.setUsageThreshold() does not support large heap sizes.
swamyv
parents:
356
diff
changeset
|
458 size_t index_for(void* p) { |
0 | 459 assert(_whole_heap.contains(p), |
3359
7d64aa23eb96
7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents:
3357
diff
changeset
|
460 err_msg("Attempt to access p = "PTR_FORMAT" out of bounds of " |
7d64aa23eb96
7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents:
3357
diff
changeset
|
461 " card marking array's _whole_heap = ["PTR_FORMAT","PTR_FORMAT")", |
7d64aa23eb96
7043891: CMS: assert(_whole_heap.contains(p)) failed: out of bounds access to card marking array
ysr
parents:
3357
diff
changeset
|
462 p, _whole_heap.start(), _whole_heap.end())); |
0 | 463 return byte_for(p) - _byte_map; |
464 } | |
465 | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
466 const jbyte* byte_for_index(const size_t card_index) const { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
467 return _byte_map + card_index; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
468 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
489
diff
changeset
|
469 |
5984 | 470 // Print a description of the memory for the barrier set |
471 virtual void print_on(outputStream* st) const; | |
472 | |
0 | 473 void verify(); |
474 void verify_guard(); | |
475 | |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3287
diff
changeset
|
476 // val_equals -> it will check that all cards covered by mr equal val |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3287
diff
changeset
|
477 // !val_equals -> it will check that all cards covered by mr do not equal val |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3287
diff
changeset
|
478 void verify_region(MemRegion mr, jbyte val, bool val_equals) PRODUCT_RETURN; |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3287
diff
changeset
|
479 void verify_not_dirty_region(MemRegion mr) PRODUCT_RETURN; |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
845
diff
changeset
|
480 void verify_dirty_region(MemRegion mr) PRODUCT_RETURN; |
0 | 481 |
482 static size_t par_chunk_heapword_alignment() { | |
3357
fc2b798ab316
6883834: ParNew: assert(!_g->to()->is_in_reserved(obj),"Scanning field twice?") with LargeObjects tests
ysr
parents:
3317
diff
changeset
|
483 return ParGCCardsPerStrideChunk * card_size_in_words; |
0 | 484 } |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
485 |
0 | 486 }; |
487 | |
488 class CardTableRS; | |
489 | |
490 // A specialization for the CardTableRS gen rem set. | |
491 class CardTableModRefBSForCTRS: public CardTableModRefBS { | |
492 CardTableRS* _rs; | |
493 protected: | |
494 bool card_will_be_scanned(jbyte cv); | |
495 bool card_may_have_been_dirty(jbyte cv); | |
496 public: | |
497 CardTableModRefBSForCTRS(MemRegion whole_heap, | |
498 int max_covered_regions) : | |
499 CardTableModRefBS(whole_heap, max_covered_regions) {} | |
500 | |
501 void set_CTRS(CardTableRS* rs) { _rs = rs; } | |
502 }; | |
1972 | 503 |
3287
c48ad6ab8bdf
7037276: Unnecessary double traversal of dirty card windows
ysr
parents:
3256
diff
changeset
|
504 |
1972 | 505 #endif // SHARE_VM_MEMORY_CARDTABLEMODREFBS_HPP |