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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
26 #define SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
27
28 #include "gc/g1/g1CollectedHeap.inline.hpp"
29 #include "gc/g1/g1ConcurrentMark.hpp"
30 #include "gc/shared/taskqueue.inline.hpp"
31
32 // Utility routine to set an exclusive range of cards on the given
33 // card liveness bitmap
34 inline void G1ConcurrentMark::set_card_bitmap_range(BitMap* card_bm,
35 BitMap::idx_t start_idx,
36 BitMap::idx_t end_idx,
37 bool is_par) {
38
39 // Set the exclusive bit range [start_idx, end_idx).
40 assert((end_idx - start_idx) > 0, "at least one card");
41 assert(end_idx <= card_bm->size(), "sanity");
42
43 // Silently clip the end index
44 end_idx = MIN2(end_idx, card_bm->size());
45
46 // For small ranges use a simple loop; otherwise use set_range or
47 // use par_at_put_range (if parallel). The range is made up of the
48 // cards that are spanned by an object/mem region so 8 cards will
49 // allow up to object sizes up to 4K to be handled using the loop.
50 if ((end_idx - start_idx) <= 8) {
51 for (BitMap::idx_t i = start_idx; i < end_idx; i += 1) {
52 if (is_par) {
53 card_bm->par_set_bit(i);
54 } else {
55 card_bm->set_bit(i);
56 }
57 }
58 } else {
59 // Note BitMap::par_at_put_range() and BitMap::set_range() are exclusive.
60 if (is_par) {
61 card_bm->par_at_put_range(start_idx, end_idx, true);
62 } else {
63 card_bm->set_range(start_idx, end_idx);
64 }
65 }
66 }
67
68 // Returns the index in the liveness accounting card bitmap
69 // for the given address
70 inline BitMap::idx_t G1ConcurrentMark::card_bitmap_index_for(HeapWord* addr) {
71 // Below, the term "card num" means the result of shifting an address
72 // by the card shift -- address 0 corresponds to card number 0. One
73 // must subtract the card num of the bottom of the heap to obtain a
74 // card table index.
75 intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift);
76 return card_num - heap_bottom_card_num();
77 }
78
79 // Counts the given memory region in the given task/worker
80 // counting data structures.
81 inline void G1ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr,
82 size_t* marked_bytes_array,
83 BitMap* task_card_bm) {
84 G1CollectedHeap* g1h = _g1h;
85 CardTableModRefBS* ct_bs = g1h->g1_barrier_set();
86
87 HeapWord* start = mr.start();
88 HeapWord* end = mr.end();
89 size_t region_size_bytes = mr.byte_size();
90 uint index = hr->hrm_index();
91
92 assert(hr == g1h->heap_region_containing(start), "sanity");
93 assert(marked_bytes_array != NULL, "pre-condition");
94 assert(task_card_bm != NULL, "pre-condition");
95
96 // Add to the task local marked bytes for this region.
97 marked_bytes_array[index] += region_size_bytes;
98
99 BitMap::idx_t start_idx = card_bitmap_index_for(start);
100 BitMap::idx_t end_idx = card_bitmap_index_for(end);
101
102 // Note: if we're looking at the last region in heap - end
103 // could be actually just beyond the end of the heap; end_idx
104 // will then correspond to a (non-existent) card that is also
105 // just beyond the heap.
106 if (g1h->is_in_g1_reserved(end) && !ct_bs->is_card_aligned(end)) {
107 // end of region is not card aligned - increment to cover
108 // all the cards spanned by the region.
109 end_idx += 1;
110 }
111 // The card bitmap is task/worker specific => no need to use
112 // the 'par' BitMap routines.
113 // Set bits in the exclusive bit range [start_idx, end_idx).
114 set_card_bitmap_range(task_card_bm, start_idx, end_idx, false /* is_par */);
115 }
116
117 // Counts the given object in the given task/worker counting data structures.
118 inline void G1ConcurrentMark::count_object(oop obj,
119 HeapRegion* hr,
120 size_t* marked_bytes_array,
121 BitMap* task_card_bm,
122 size_t word_size) {
123 assert(!hr->is_continues_humongous(), "Cannot enter count_object with continues humongous");
124 if (!hr->is_starts_humongous()) {
125 MemRegion mr((HeapWord*)obj, word_size);
126 count_region(mr, hr, marked_bytes_array, task_card_bm);
127 } else {
128 do {
129 MemRegion mr(hr->bottom(), hr->top());
130 count_region(mr, hr, marked_bytes_array, task_card_bm);
131 hr = _g1h->next_region_in_humongous(hr);
132 } while (hr != NULL);
133 }
134 }
135
136 // Attempts to mark the given object and, if successful, counts
137 // the object in the given task/worker counting structures.
138 inline bool G1ConcurrentMark::par_mark_and_count(oop obj,
139 HeapRegion* hr,
140 size_t* marked_bytes_array,
141 BitMap* task_card_bm) {
142 if (_nextMarkBitMap->parMark((HeapWord*)obj)) {
143 // Update the task specific count data for the object.
144 count_object(obj, hr, marked_bytes_array, task_card_bm, obj->size());
145 return true;
146 }
147 return false;
148 }
149
150 // Attempts to mark the given object and, if successful, counts
151 // the object in the task/worker counting structures for the
152 // given worker id.
153 inline bool G1ConcurrentMark::par_mark_and_count(oop obj,
154 size_t word_size,
155 HeapRegion* hr,
156 uint worker_id) {
157 if (_nextMarkBitMap->parMark((HeapWord*)obj)) {
158 size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id);
159 BitMap* task_card_bm = count_card_bitmap_for(worker_id);
160 count_object(obj, hr, marked_bytes_array, task_card_bm, word_size);
161 return true;
162 }
163 return false;
164 }
165
166 inline bool G1CMBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) {
167 HeapWord* start_addr = MAX2(startWord(), mr.start());
168 HeapWord* end_addr = MIN2(endWord(), mr.end());
169
170 if (end_addr > start_addr) {
171 // Right-open interval [start-offset, end-offset).
172 BitMap::idx_t start_offset = heapWordToOffset(start_addr);
173 BitMap::idx_t end_offset = heapWordToOffset(end_addr);
174
175 start_offset = _bm.get_next_one_offset(start_offset, end_offset);
176 while (start_offset < end_offset) {
177 if (!cl->do_bit(start_offset)) {
178 return false;
179 }
180 HeapWord* next_addr = MIN2(nextObject(offsetToHeapWord(start_offset)), end_addr);
181 BitMap::idx_t next_offset = heapWordToOffset(next_addr);
182 start_offset = _bm.get_next_one_offset(next_offset, end_offset);
183 }
277 } // Else check global finger.
278 }
279 // Check global finger.
280 return objAddr < global_finger;
281 }
282
283 template<bool scan>
284 inline void G1CMTask::process_grey_object(oop obj) {
285 assert(scan || obj->is_typeArray(), "Skipping scan of grey non-typeArray");
286 assert(_nextMarkBitMap->isMarked((HeapWord*) obj), "invariant");
287
288 size_t obj_size = obj->size();
289 _words_scanned += obj_size;
290
291 if (scan) {
292 obj->oop_iterate(_cm_oop_closure);
293 }
294 check_limits();
295 }
296
297
298
299 inline void G1CMTask::make_reference_grey(oop obj, HeapRegion* hr) {
300 if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) {
301 // No OrderAccess:store_load() is needed. It is implicit in the
302 // CAS done in G1CMBitMap::parMark() call in the routine above.
303 HeapWord* global_finger = _cm->finger();
304
305 // We only need to push a newly grey object on the mark
306 // stack if it is in a section of memory the mark bitmap
307 // scan has already examined. Mark bitmap scanning
308 // maintains progress "fingers" for determining that.
309 //
310 // Notice that the global finger might be moving forward
311 // concurrently. This is not a problem. In the worst case, we
312 // mark the object while it is above the global finger and, by
313 // the time we read the global finger, it has moved forward
314 // past this object. In this case, the object will probably
315 // be visited when a task is scanning the region and will also
316 // be pushed on the stack. So, some duplicate work, but no
317 // correctness problems.
318 if (is_below_finger(obj, global_finger)) {
319 if (obj->is_typeArray()) {
320 // Immediately process arrays of primitive types, rather
331 } else {
332 push(obj);
333 }
334 }
335 }
336 }
337
338 inline void G1CMTask::deal_with_reference(oop obj) {
339 increment_refs_reached();
340
341 HeapWord* objAddr = (HeapWord*) obj;
342 assert(obj->is_oop_or_null(true /* ignore mark word */), "Expected an oop or NULL at " PTR_FORMAT, p2i(obj));
343 if (_g1h->is_in_g1_reserved(objAddr)) {
344 assert(obj != NULL, "null check is implicit");
345 if (!_nextMarkBitMap->isMarked(objAddr)) {
346 // Only get the containing region if the object is not marked on the
347 // bitmap (otherwise, it's a waste of time since we won't do
348 // anything with it).
349 HeapRegion* hr = _g1h->heap_region_containing(obj);
350 if (!hr->obj_allocated_since_next_marking(obj)) {
351 make_reference_grey(obj, hr);
352 }
353 }
354 }
355 }
356
357 inline void G1ConcurrentMark::markPrev(oop p) {
358 assert(!_prevMarkBitMap->isMarked((HeapWord*) p), "sanity");
359 // Note we are overriding the read-only view of the prev map here, via
360 // the cast.
361 ((G1CMBitMap*)_prevMarkBitMap)->mark((HeapWord*) p);
362 }
363
364 bool G1ConcurrentMark::isPrevMarked(oop p) const {
365 assert(p != NULL && p->is_oop(), "expected an oop");
366 HeapWord* addr = (HeapWord*)p;
367 assert(addr >= _prevMarkBitMap->startWord() ||
368 addr < _prevMarkBitMap->endWord(), "in a region");
369
370 return _prevMarkBitMap->isMarked(addr);
371 }
372
373 inline void G1ConcurrentMark::grayRoot(oop obj, size_t word_size,
374 uint worker_id, HeapRegion* hr) {
375 assert(obj != NULL, "pre-condition");
376 HeapWord* addr = (HeapWord*) obj;
377 if (hr == NULL) {
378 hr = _g1h->heap_region_containing(addr);
379 } else {
380 assert(hr->is_in(addr), "pre-condition");
381 }
382 assert(hr != NULL, "sanity");
383 // Given that we're looking for a region that contains an object
384 // header it's impossible to get back a HC region.
385 assert(!hr->is_continues_humongous(), "sanity");
386
387 if (addr < hr->next_top_at_mark_start()) {
388 if (!_nextMarkBitMap->isMarked(addr)) {
389 par_mark_and_count(obj, word_size, hr, worker_id);
390 }
391 }
392 }
393
394 #endif // SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
|
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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
26 #define SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
27
28 #include "gc/g1/g1CollectedHeap.inline.hpp"
29 #include "gc/g1/g1ConcurrentMark.hpp"
30 #include "gc/shared/taskqueue.inline.hpp"
31
32 inline BitMap::idx_t G1ConcurrentMark::card_live_bitmap_index_for(HeapWord* addr) {
33 // Below, the term "card num" means the result of shifting an address
34 // by the card shift -- address 0 corresponds to card number 0. One
35 // must subtract the card num of the bottom of the heap to obtain a
36 // card table index.
37 intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift);
38 return card_num - heap_bottom_card_num();
39 }
40
41 inline bool G1ConcurrentMark::par_mark(oop obj) {
42 return _nextMarkBitMap->parMark((HeapWord*)obj);
43 }
44
45 inline bool G1CMBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) {
46 HeapWord* start_addr = MAX2(startWord(), mr.start());
47 HeapWord* end_addr = MIN2(endWord(), mr.end());
48
49 if (end_addr > start_addr) {
50 // Right-open interval [start-offset, end-offset).
51 BitMap::idx_t start_offset = heapWordToOffset(start_addr);
52 BitMap::idx_t end_offset = heapWordToOffset(end_addr);
53
54 start_offset = _bm.get_next_one_offset(start_offset, end_offset);
55 while (start_offset < end_offset) {
56 if (!cl->do_bit(start_offset)) {
57 return false;
58 }
59 HeapWord* next_addr = MIN2(nextObject(offsetToHeapWord(start_offset)), end_addr);
60 BitMap::idx_t next_offset = heapWordToOffset(next_addr);
61 start_offset = _bm.get_next_one_offset(next_offset, end_offset);
62 }
156 } // Else check global finger.
157 }
158 // Check global finger.
159 return objAddr < global_finger;
160 }
161
162 template<bool scan>
163 inline void G1CMTask::process_grey_object(oop obj) {
164 assert(scan || obj->is_typeArray(), "Skipping scan of grey non-typeArray");
165 assert(_nextMarkBitMap->isMarked((HeapWord*) obj), "invariant");
166
167 size_t obj_size = obj->size();
168 _words_scanned += obj_size;
169
170 if (scan) {
171 obj->oop_iterate(_cm_oop_closure);
172 }
173 check_limits();
174 }
175
176 inline void G1CMTask::make_reference_grey(oop obj) {
177 if (_cm->par_mark(obj)) {
178 // No OrderAccess:store_load() is needed. It is implicit in the
179 // CAS done in G1CMBitMap::parMark() call in the routine above.
180 HeapWord* global_finger = _cm->finger();
181
182 // We only need to push a newly grey object on the mark
183 // stack if it is in a section of memory the mark bitmap
184 // scan has already examined. Mark bitmap scanning
185 // maintains progress "fingers" for determining that.
186 //
187 // Notice that the global finger might be moving forward
188 // concurrently. This is not a problem. In the worst case, we
189 // mark the object while it is above the global finger and, by
190 // the time we read the global finger, it has moved forward
191 // past this object. In this case, the object will probably
192 // be visited when a task is scanning the region and will also
193 // be pushed on the stack. So, some duplicate work, but no
194 // correctness problems.
195 if (is_below_finger(obj, global_finger)) {
196 if (obj->is_typeArray()) {
197 // Immediately process arrays of primitive types, rather
208 } else {
209 push(obj);
210 }
211 }
212 }
213 }
214
215 inline void G1CMTask::deal_with_reference(oop obj) {
216 increment_refs_reached();
217
218 HeapWord* objAddr = (HeapWord*) obj;
219 assert(obj->is_oop_or_null(true /* ignore mark word */), "Expected an oop or NULL at " PTR_FORMAT, p2i(obj));
220 if (_g1h->is_in_g1_reserved(objAddr)) {
221 assert(obj != NULL, "null check is implicit");
222 if (!_nextMarkBitMap->isMarked(objAddr)) {
223 // Only get the containing region if the object is not marked on the
224 // bitmap (otherwise, it's a waste of time since we won't do
225 // anything with it).
226 HeapRegion* hr = _g1h->heap_region_containing(obj);
227 if (!hr->obj_allocated_since_next_marking(obj)) {
228 make_reference_grey(obj);
229 }
230 }
231 }
232 }
233
234 inline void G1ConcurrentMark::markPrev(oop p) {
235 assert(!_prevMarkBitMap->isMarked((HeapWord*) p), "sanity");
236 // Note we are overriding the read-only view of the prev map here, via
237 // the cast.
238 ((G1CMBitMap*)_prevMarkBitMap)->mark((HeapWord*) p);
239 }
240
241 bool G1ConcurrentMark::isPrevMarked(oop p) const {
242 assert(p != NULL && p->is_oop(), "expected an oop");
243 HeapWord* addr = (HeapWord*)p;
244 assert(addr >= _prevMarkBitMap->startWord() ||
245 addr < _prevMarkBitMap->endWord(), "in a region");
246
247 return _prevMarkBitMap->isMarked(addr);
248 }
249
250 inline void G1ConcurrentMark::grayRoot(oop obj, HeapRegion* hr) {
251 assert(obj != NULL, "pre-condition");
252 HeapWord* addr = (HeapWord*) obj;
253 if (hr == NULL) {
254 hr = _g1h->heap_region_containing(addr);
255 } else {
256 assert(hr->is_in(addr), "pre-condition");
257 }
258 assert(hr != NULL, "sanity");
259 // Given that we're looking for a region that contains an object
260 // header it's impossible to get back a HC region.
261 assert(!hr->is_continues_humongous(), "sanity");
262
263 if (addr < hr->next_top_at_mark_start()) {
264 if (!_nextMarkBitMap->isMarked(addr)) {
265 par_mark(obj);
266 }
267 }
268 }
269
270 #endif // SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
|