Mercurial > hg > graal-compiler
annotate src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp @ 1091:6aa7255741f3
6906727: UseCompressedOops: some card-marking fixes related to object arrays
Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17).
Reviewed-by: kvn, coleenp, jmasa
author | ysr |
---|---|
date | Thu, 03 Dec 2009 15:01:57 -0800 |
parents | bd02caa94611 |
children | c18cbe5936b8 |
rev | line source |
---|---|
0 | 1 /* |
844 | 2 * Copyright 2005-2009 Sun Microsystems, Inc. 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 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 class oopDesc; | |
26 class ParMarkBitMapClosure; | |
27 | |
28 class ParMarkBitMap: public CHeapObj | |
29 { | |
30 public: | |
31 typedef BitMap::idx_t idx_t; | |
32 | |
33 // Values returned by the iterate() methods. | |
34 enum IterationStatus { incomplete, complete, full, would_overflow }; | |
35 | |
36 inline ParMarkBitMap(); | |
37 inline ParMarkBitMap(MemRegion covered_region); | |
38 bool initialize(MemRegion covered_region); | |
39 | |
40 // Atomically mark an object as live. | |
41 bool mark_obj(HeapWord* addr, size_t size); | |
42 inline bool mark_obj(oop obj, int size); | |
43 inline bool mark_obj(oop obj); | |
44 | |
45 // Return whether the specified begin or end bit is set. | |
46 inline bool is_obj_beg(idx_t bit) const; | |
47 inline bool is_obj_end(idx_t bit) const; | |
48 | |
49 // Traditional interface for testing whether an object is marked or not (these | |
50 // test only the begin bits). | |
51 inline bool is_marked(idx_t bit) const; | |
52 inline bool is_marked(HeapWord* addr) const; | |
53 inline bool is_marked(oop obj) const; | |
54 | |
55 inline bool is_unmarked(idx_t bit) const; | |
56 inline bool is_unmarked(HeapWord* addr) const; | |
57 inline bool is_unmarked(oop obj) const; | |
58 | |
59 // Convert sizes from bits to HeapWords and back. An object that is n bits | |
60 // long will be bits_to_words(n) words long. An object that is m words long | |
61 // will take up words_to_bits(m) bits in the bitmap. | |
62 inline static size_t bits_to_words(idx_t bits); | |
63 inline static idx_t words_to_bits(size_t words); | |
64 | |
65 // Return the size in words of an object given a begin bit and an end bit, or | |
66 // the equivalent beg_addr and end_addr. | |
67 inline size_t obj_size(idx_t beg_bit, idx_t end_bit) const; | |
68 inline size_t obj_size(HeapWord* beg_addr, HeapWord* end_addr) const; | |
69 | |
70 // Return the size in words of the object (a search is done for the end bit). | |
71 inline size_t obj_size(idx_t beg_bit) const; | |
72 inline size_t obj_size(HeapWord* addr) const; | |
73 inline size_t obj_size(oop obj) const; | |
74 | |
75 // Synonyms for the above. | |
76 size_t obj_size_in_words(oop obj) const { return obj_size((HeapWord*)obj); } | |
77 size_t obj_size_in_words(HeapWord* addr) const { return obj_size(addr); } | |
78 | |
79 // Apply live_closure to each live object that lies completely within the | |
80 // range [live_range_beg, live_range_end). This is used to iterate over the | |
81 // compacted region of the heap. Return values: | |
82 // | |
83 // incomplete The iteration is not complete. The last object that | |
84 // begins in the range does not end in the range; | |
85 // closure->source() is set to the start of that object. | |
86 // | |
87 // complete The iteration is complete. All objects in the range | |
88 // were processed and the closure is not full; | |
89 // closure->source() is set one past the end of the range. | |
90 // | |
91 // full The closure is full; closure->source() is set to one | |
92 // past the end of the last object processed. | |
93 // | |
94 // would_overflow The next object in the range would overflow the closure; | |
95 // closure->source() is set to the start of that object. | |
96 IterationStatus iterate(ParMarkBitMapClosure* live_closure, | |
97 idx_t range_beg, idx_t range_end) const; | |
98 inline IterationStatus iterate(ParMarkBitMapClosure* live_closure, | |
99 HeapWord* range_beg, | |
100 HeapWord* range_end) const; | |
101 | |
102 // Apply live closure as above and additionally apply dead_closure to all dead | |
103 // space in the range [range_beg, dead_range_end). Note that dead_range_end | |
104 // must be >= range_end. This is used to iterate over the dense prefix. | |
105 // | |
106 // This method assumes that if the first bit in the range (range_beg) is not | |
107 // marked, then dead space begins at that point and the dead_closure is | |
108 // applied. Thus callers must ensure that range_beg is not in the middle of a | |
109 // live object. | |
110 IterationStatus iterate(ParMarkBitMapClosure* live_closure, | |
111 ParMarkBitMapClosure* dead_closure, | |
112 idx_t range_beg, idx_t range_end, | |
113 idx_t dead_range_end) const; | |
114 inline IterationStatus iterate(ParMarkBitMapClosure* live_closure, | |
115 ParMarkBitMapClosure* dead_closure, | |
116 HeapWord* range_beg, | |
117 HeapWord* range_end, | |
118 HeapWord* dead_range_end) const; | |
119 | |
120 // Return the number of live words in the range [beg_addr, end_addr) due to | |
121 // objects that start in the range. If a live object extends onto the range, | |
122 // the caller must detect and account for any live words due to that object. | |
123 // If a live object extends beyond the end of the range, only the words within | |
124 // the range are included in the result. | |
125 size_t live_words_in_range(HeapWord* beg_addr, HeapWord* end_addr) const; | |
126 | |
127 // Same as the above, except the end of the range must be a live object, which | |
128 // is the case when updating pointers. This allows a branch to be removed | |
129 // from inside the loop. | |
130 size_t live_words_in_range(HeapWord* beg_addr, oop end_obj) const; | |
131 | |
132 inline HeapWord* region_start() const; | |
133 inline HeapWord* region_end() const; | |
134 inline size_t region_size() const; | |
135 inline size_t size() const; | |
136 | |
137 // Convert a heap address to/from a bit index. | |
138 inline idx_t addr_to_bit(HeapWord* addr) const; | |
139 inline HeapWord* bit_to_addr(idx_t bit) const; | |
140 | |
141 // Return the bit index of the first marked object that begins (or ends, | |
142 // respectively) in the range [beg, end). If no object is found, return end. | |
143 inline idx_t find_obj_beg(idx_t beg, idx_t end) const; | |
144 inline idx_t find_obj_end(idx_t beg, idx_t end) const; | |
145 | |
146 inline HeapWord* find_obj_beg(HeapWord* beg, HeapWord* end) const; | |
147 inline HeapWord* find_obj_end(HeapWord* beg, HeapWord* end) const; | |
148 | |
149 // Clear a range of bits or the entire bitmap (both begin and end bits are | |
150 // cleared). | |
151 inline void clear_range(idx_t beg, idx_t end); | |
152 inline void clear() { clear_range(0, size()); } | |
153 | |
154 // Return the number of bits required to represent the specified number of | |
155 // HeapWords, or the specified region. | |
156 static inline idx_t bits_required(size_t words); | |
157 static inline idx_t bits_required(MemRegion covered_region); | |
158 static inline idx_t words_required(MemRegion covered_region); | |
159 | |
160 #ifndef PRODUCT | |
161 // CAS statistics. | |
162 size_t cas_tries() { return _cas_tries; } | |
163 size_t cas_retries() { return _cas_retries; } | |
164 size_t cas_by_another() { return _cas_by_another; } | |
165 | |
166 void reset_counters(); | |
167 #endif // #ifndef PRODUCT | |
168 | |
169 #ifdef ASSERT | |
170 void verify_clear() const; | |
171 inline void verify_bit(idx_t bit) const; | |
172 inline void verify_addr(HeapWord* addr) const; | |
173 #endif // #ifdef ASSERT | |
174 | |
175 private: | |
176 // Each bit in the bitmap represents one unit of 'object granularity.' Objects | |
177 // are double-word aligned in 32-bit VMs, but not in 64-bit VMs, so the 32-bit | |
178 // granularity is 2, 64-bit is 1. | |
179 static inline size_t obj_granularity() { return size_t(MinObjAlignment); } | |
808
353ba4575581
6814552: par compact - some compilers fail to optimize bitmap code
jcoomes
parents:
342
diff
changeset
|
180 static inline int obj_granularity_shift() { return LogMinObjAlignment; } |
0 | 181 |
182 HeapWord* _region_start; | |
183 size_t _region_size; | |
184 BitMap _beg_bits; | |
185 BitMap _end_bits; | |
186 PSVirtualSpace* _virtual_space; | |
187 | |
188 #ifndef PRODUCT | |
189 size_t _cas_tries; | |
190 size_t _cas_retries; | |
191 size_t _cas_by_another; | |
192 #endif // #ifndef PRODUCT | |
193 }; | |
194 | |
195 inline ParMarkBitMap::ParMarkBitMap(): | |
342 | 196 _beg_bits(), |
197 _end_bits() | |
0 | 198 { |
199 _region_start = 0; | |
200 _virtual_space = 0; | |
201 } | |
202 | |
203 inline ParMarkBitMap::ParMarkBitMap(MemRegion covered_region): | |
342 | 204 _beg_bits(), |
205 _end_bits() | |
0 | 206 { |
207 initialize(covered_region); | |
208 } | |
209 | |
210 inline void ParMarkBitMap::clear_range(idx_t beg, idx_t end) | |
211 { | |
212 _beg_bits.clear_range(beg, end); | |
213 _end_bits.clear_range(beg, end); | |
214 } | |
215 | |
216 inline ParMarkBitMap::idx_t | |
217 ParMarkBitMap::bits_required(size_t words) | |
218 { | |
219 // Need two bits (one begin bit, one end bit) for each unit of 'object | |
220 // granularity' in the heap. | |
221 return words_to_bits(words * 2); | |
222 } | |
223 | |
224 inline ParMarkBitMap::idx_t | |
225 ParMarkBitMap::bits_required(MemRegion covered_region) | |
226 { | |
227 return bits_required(covered_region.word_size()); | |
228 } | |
229 | |
230 inline ParMarkBitMap::idx_t | |
231 ParMarkBitMap::words_required(MemRegion covered_region) | |
232 { | |
233 return bits_required(covered_region) / BitsPerWord; | |
234 } | |
235 | |
236 inline HeapWord* | |
237 ParMarkBitMap::region_start() const | |
238 { | |
239 return _region_start; | |
240 } | |
241 | |
242 inline HeapWord* | |
243 ParMarkBitMap::region_end() const | |
244 { | |
245 return region_start() + region_size(); | |
246 } | |
247 | |
248 inline size_t | |
249 ParMarkBitMap::region_size() const | |
250 { | |
251 return _region_size; | |
252 } | |
253 | |
254 inline size_t | |
255 ParMarkBitMap::size() const | |
256 { | |
257 return _beg_bits.size(); | |
258 } | |
259 | |
260 inline bool ParMarkBitMap::is_obj_beg(idx_t bit) const | |
261 { | |
262 return _beg_bits.at(bit); | |
263 } | |
264 | |
265 inline bool ParMarkBitMap::is_obj_end(idx_t bit) const | |
266 { | |
267 return _end_bits.at(bit); | |
268 } | |
269 | |
270 inline bool ParMarkBitMap::is_marked(idx_t bit) const | |
271 { | |
272 return is_obj_beg(bit); | |
273 } | |
274 | |
275 inline bool ParMarkBitMap::is_marked(HeapWord* addr) const | |
276 { | |
277 return is_marked(addr_to_bit(addr)); | |
278 } | |
279 | |
280 inline bool ParMarkBitMap::is_marked(oop obj) const | |
281 { | |
282 return is_marked((HeapWord*)obj); | |
283 } | |
284 | |
285 inline bool ParMarkBitMap::is_unmarked(idx_t bit) const | |
286 { | |
287 return !is_marked(bit); | |
288 } | |
289 | |
290 inline bool ParMarkBitMap::is_unmarked(HeapWord* addr) const | |
291 { | |
292 return !is_marked(addr); | |
293 } | |
294 | |
295 inline bool ParMarkBitMap::is_unmarked(oop obj) const | |
296 { | |
297 return !is_marked(obj); | |
298 } | |
299 | |
300 inline size_t | |
301 ParMarkBitMap::bits_to_words(idx_t bits) | |
302 { | |
808
353ba4575581
6814552: par compact - some compilers fail to optimize bitmap code
jcoomes
parents:
342
diff
changeset
|
303 return bits << obj_granularity_shift(); |
0 | 304 } |
305 | |
306 inline ParMarkBitMap::idx_t | |
307 ParMarkBitMap::words_to_bits(size_t words) | |
308 { | |
808
353ba4575581
6814552: par compact - some compilers fail to optimize bitmap code
jcoomes
parents:
342
diff
changeset
|
309 return words >> obj_granularity_shift(); |
0 | 310 } |
311 | |
312 inline size_t ParMarkBitMap::obj_size(idx_t beg_bit, idx_t end_bit) const | |
313 { | |
314 DEBUG_ONLY(verify_bit(beg_bit);) | |
315 DEBUG_ONLY(verify_bit(end_bit);) | |
316 return bits_to_words(end_bit - beg_bit + 1); | |
317 } | |
318 | |
319 inline size_t | |
320 ParMarkBitMap::obj_size(HeapWord* beg_addr, HeapWord* end_addr) const | |
321 { | |
322 DEBUG_ONLY(verify_addr(beg_addr);) | |
323 DEBUG_ONLY(verify_addr(end_addr);) | |
324 return pointer_delta(end_addr, beg_addr) + obj_granularity(); | |
325 } | |
326 | |
327 inline size_t ParMarkBitMap::obj_size(idx_t beg_bit) const | |
328 { | |
342 | 329 const idx_t end_bit = _end_bits.get_next_one_offset_inline(beg_bit, size()); |
0 | 330 assert(is_marked(beg_bit), "obj not marked"); |
331 assert(end_bit < size(), "end bit missing"); | |
332 return obj_size(beg_bit, end_bit); | |
333 } | |
334 | |
335 inline size_t ParMarkBitMap::obj_size(HeapWord* addr) const | |
336 { | |
337 return obj_size(addr_to_bit(addr)); | |
338 } | |
339 | |
340 inline size_t ParMarkBitMap::obj_size(oop obj) const | |
341 { | |
342 return obj_size((HeapWord*)obj); | |
343 } | |
344 | |
345 inline ParMarkBitMap::IterationStatus | |
346 ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure, | |
347 HeapWord* range_beg, | |
348 HeapWord* range_end) const | |
349 { | |
350 return iterate(live_closure, addr_to_bit(range_beg), addr_to_bit(range_end)); | |
351 } | |
352 | |
353 inline ParMarkBitMap::IterationStatus | |
354 ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure, | |
355 ParMarkBitMapClosure* dead_closure, | |
356 HeapWord* range_beg, | |
357 HeapWord* range_end, | |
358 HeapWord* dead_range_end) const | |
359 { | |
360 return iterate(live_closure, dead_closure, | |
361 addr_to_bit(range_beg), addr_to_bit(range_end), | |
362 addr_to_bit(dead_range_end)); | |
363 } | |
364 | |
365 inline bool | |
366 ParMarkBitMap::mark_obj(oop obj, int size) | |
367 { | |
368 return mark_obj((HeapWord*)obj, (size_t)size); | |
369 } | |
370 | |
371 inline BitMap::idx_t | |
372 ParMarkBitMap::addr_to_bit(HeapWord* addr) const | |
373 { | |
374 DEBUG_ONLY(verify_addr(addr);) | |
375 return words_to_bits(pointer_delta(addr, region_start())); | |
376 } | |
377 | |
378 inline HeapWord* | |
379 ParMarkBitMap::bit_to_addr(idx_t bit) const | |
380 { | |
381 DEBUG_ONLY(verify_bit(bit);) | |
382 return region_start() + bits_to_words(bit); | |
383 } | |
384 | |
385 inline ParMarkBitMap::idx_t | |
386 ParMarkBitMap::find_obj_beg(idx_t beg, idx_t end) const | |
387 { | |
342 | 388 return _beg_bits.get_next_one_offset_inline_aligned_right(beg, end); |
0 | 389 } |
390 | |
391 inline ParMarkBitMap::idx_t | |
392 ParMarkBitMap::find_obj_end(idx_t beg, idx_t end) const | |
393 { | |
342 | 394 return _end_bits.get_next_one_offset_inline_aligned_right(beg, end); |
0 | 395 } |
396 | |
397 inline HeapWord* | |
398 ParMarkBitMap::find_obj_beg(HeapWord* beg, HeapWord* end) const | |
399 { | |
400 const idx_t beg_bit = addr_to_bit(beg); | |
401 const idx_t end_bit = addr_to_bit(end); | |
402 const idx_t search_end = BitMap::word_align_up(end_bit); | |
403 const idx_t res_bit = MIN2(find_obj_beg(beg_bit, search_end), end_bit); | |
404 return bit_to_addr(res_bit); | |
405 } | |
406 | |
407 inline HeapWord* | |
408 ParMarkBitMap::find_obj_end(HeapWord* beg, HeapWord* end) const | |
409 { | |
410 const idx_t beg_bit = addr_to_bit(beg); | |
411 const idx_t end_bit = addr_to_bit(end); | |
412 const idx_t search_end = BitMap::word_align_up(end_bit); | |
413 const idx_t res_bit = MIN2(find_obj_end(beg_bit, search_end), end_bit); | |
414 return bit_to_addr(res_bit); | |
415 } | |
416 | |
417 #ifdef ASSERT | |
418 inline void ParMarkBitMap::verify_bit(idx_t bit) const { | |
419 // Allow one past the last valid bit; useful for loop bounds. | |
420 assert(bit <= _beg_bits.size(), "bit out of range"); | |
421 } | |
422 | |
423 inline void ParMarkBitMap::verify_addr(HeapWord* addr) const { | |
424 // Allow one past the last valid address; useful for loop bounds. | |
425 assert(addr >= region_start(), "addr too small"); | |
426 assert(addr <= region_start() + region_size(), "addr too big"); | |
427 } | |
428 #endif // #ifdef ASSERT |