112 |
112 |
113 G1BlockOffsetSharedArray* _bot_shared; |
113 G1BlockOffsetSharedArray* _bot_shared; |
114 G1SATBCardTableModRefBS *_ct_bs; |
114 G1SATBCardTableModRefBS *_ct_bs; |
115 |
115 |
116 double _strong_code_root_scan_time_sec; |
116 double _strong_code_root_scan_time_sec; |
117 int _worker_i; |
117 uint _worker_i; |
118 int _block_size; |
118 int _block_size; |
119 bool _try_claimed; |
119 bool _try_claimed; |
120 |
120 |
121 public: |
121 public: |
122 ScanRSClosure(OopsInHeapRegionClosure* oc, |
122 ScanRSClosure(OopsInHeapRegionClosure* oc, |
123 CodeBlobToOopClosure* code_root_cl, |
123 CodeBlobToOopClosure* code_root_cl, |
124 int worker_i) : |
124 uint worker_i) : |
125 _oc(oc), |
125 _oc(oc), |
126 _code_root_cl(code_root_cl), |
126 _code_root_cl(code_root_cl), |
127 _strong_code_root_scan_time_sec(0.0), |
127 _strong_code_root_scan_time_sec(0.0), |
128 _cards(0), |
128 _cards(0), |
129 _cards_done(0), |
129 _cards_done(0), |
161 } |
161 } |
162 } |
162 } |
163 |
163 |
164 void printCard(HeapRegion* card_region, size_t card_index, |
164 void printCard(HeapRegion* card_region, size_t card_index, |
165 HeapWord* card_start) { |
165 HeapWord* card_start) { |
166 gclog_or_tty->print_cr("T %d Region [" PTR_FORMAT ", " PTR_FORMAT ") " |
166 gclog_or_tty->print_cr("T " UINT32_FORMAT " Region [" PTR_FORMAT ", " PTR_FORMAT ") " |
167 "RS names card %p: " |
167 "RS names card %p: " |
168 "[" PTR_FORMAT ", " PTR_FORMAT ")", |
168 "[" PTR_FORMAT ", " PTR_FORMAT ")", |
169 _worker_i, |
169 _worker_i, |
170 card_region->bottom(), card_region->end(), |
170 card_region->bottom(), card_region->end(), |
171 card_index, |
171 card_index, |
240 size_t cards_looked_up() { return _cards;} |
240 size_t cards_looked_up() { return _cards;} |
241 }; |
241 }; |
242 |
242 |
243 void G1RemSet::scanRS(OopsInHeapRegionClosure* oc, |
243 void G1RemSet::scanRS(OopsInHeapRegionClosure* oc, |
244 CodeBlobToOopClosure* code_root_cl, |
244 CodeBlobToOopClosure* code_root_cl, |
245 int worker_i) { |
245 uint worker_i) { |
246 double rs_time_start = os::elapsedTime(); |
246 double rs_time_start = os::elapsedTime(); |
247 HeapRegion *startRegion = _g1->start_cset_region_for_worker(worker_i); |
247 HeapRegion *startRegion = _g1->start_cset_region_for_worker(worker_i); |
248 |
248 |
249 ScanRSClosure scanRScl(oc, code_root_cl, worker_i); |
249 ScanRSClosure scanRScl(oc, code_root_cl, worker_i); |
250 |
250 |
273 public: |
273 public: |
274 RefineRecordRefsIntoCSCardTableEntryClosure(G1CollectedHeap* g1h, |
274 RefineRecordRefsIntoCSCardTableEntryClosure(G1CollectedHeap* g1h, |
275 DirtyCardQueue* into_cset_dcq) : |
275 DirtyCardQueue* into_cset_dcq) : |
276 _g1rs(g1h->g1_rem_set()), _into_cset_dcq(into_cset_dcq) |
276 _g1rs(g1h->g1_rem_set()), _into_cset_dcq(into_cset_dcq) |
277 {} |
277 {} |
278 bool do_card_ptr(jbyte* card_ptr, int worker_i) { |
278 bool do_card_ptr(jbyte* card_ptr, uint worker_i) { |
279 // The only time we care about recording cards that |
279 // The only time we care about recording cards that |
280 // contain references that point into the collection set |
280 // contain references that point into the collection set |
281 // is during RSet updating within an evacuation pause. |
281 // is during RSet updating within an evacuation pause. |
282 // In this case worker_i should be the id of a GC worker thread. |
282 // In this case worker_i should be the id of a GC worker thread. |
283 assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause"); |
283 assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause"); |
284 assert(worker_i < (int) (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "should be a GC worker"); |
284 assert(worker_i < (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "should be a GC worker"); |
285 |
285 |
286 if (_g1rs->refine_card(card_ptr, worker_i, true)) { |
286 if (_g1rs->refine_card(card_ptr, worker_i, true)) { |
287 // 'card_ptr' contains references that point into the collection |
287 // 'card_ptr' contains references that point into the collection |
288 // set. We need to record the card in the DCQS |
288 // set. We need to record the card in the DCQS |
289 // (G1CollectedHeap::into_cset_dirty_card_queue_set()) |
289 // (G1CollectedHeap::into_cset_dirty_card_queue_set()) |
294 } |
294 } |
295 return true; |
295 return true; |
296 } |
296 } |
297 }; |
297 }; |
298 |
298 |
299 void G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, int worker_i) { |
299 void G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, uint worker_i) { |
300 double start = os::elapsedTime(); |
300 double start = os::elapsedTime(); |
301 // Apply the given closure to all remaining log entries. |
301 // Apply the given closure to all remaining log entries. |
302 RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, into_cset_dcq); |
302 RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, into_cset_dcq); |
303 |
303 |
304 _g1->iterate_dirty_card_closure(&into_cset_update_rs_cl, into_cset_dcq, false, worker_i); |
304 _g1->iterate_dirty_card_closure(&into_cset_update_rs_cl, into_cset_dcq, false, worker_i); |
319 HeapRegionRemSet::cleanup(); |
319 HeapRegionRemSet::cleanup(); |
320 } |
320 } |
321 |
321 |
322 void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc, |
322 void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc, |
323 CodeBlobToOopClosure* code_root_cl, |
323 CodeBlobToOopClosure* code_root_cl, |
324 int worker_i) { |
324 uint worker_i) { |
325 #if CARD_REPEAT_HISTO |
325 #if CARD_REPEAT_HISTO |
326 ct_freq_update_histo_and_reset(); |
326 ct_freq_update_histo_and_reset(); |
327 #endif |
327 #endif |
328 |
328 |
329 // We cache the value of 'oc' closure into the appropriate slot in the |
329 // We cache the value of 'oc' closure into the appropriate slot in the |
330 // _cset_rs_update_cl for this worker |
330 // _cset_rs_update_cl for this worker |
331 assert(worker_i < (int)n_workers(), "sanity"); |
331 assert(worker_i < n_workers(), "sanity"); |
332 _cset_rs_update_cl[worker_i] = oc; |
332 _cset_rs_update_cl[worker_i] = oc; |
333 |
333 |
334 // A DirtyCardQueue that is used to hold cards containing references |
334 // A DirtyCardQueue that is used to hold cards containing references |
335 // that point into the collection set. This DCQ is associated with a |
335 // that point into the collection set. This DCQ is associated with a |
336 // special DirtyCardQueueSet (see g1CollectedHeap.hpp). Under normal |
336 // special DirtyCardQueueSet (see g1CollectedHeap.hpp). Under normal |
398 UpdateRSetCardTableEntryIntoCSetClosure(G1CollectedHeap* g1, |
398 UpdateRSetCardTableEntryIntoCSetClosure(G1CollectedHeap* g1, |
399 CardTableModRefBS* bs): |
399 CardTableModRefBS* bs): |
400 _g1(g1), _ct_bs(bs) |
400 _g1(g1), _ct_bs(bs) |
401 { } |
401 { } |
402 |
402 |
403 bool do_card_ptr(jbyte* card_ptr, int worker_i) { |
403 bool do_card_ptr(jbyte* card_ptr, uint worker_i) { |
404 // Construct the region representing the card. |
404 // Construct the region representing the card. |
405 HeapWord* start = _ct_bs->addr_for(card_ptr); |
405 HeapWord* start = _ct_bs->addr_for(card_ptr); |
406 // And find the region containing it. |
406 // And find the region containing it. |
407 HeapRegion* r = _g1->heap_region_containing(start); |
407 HeapRegion* r = _g1->heap_region_containing(start); |
408 assert(r != NULL, "unexpected null"); |
408 assert(r != NULL, "unexpected null"); |
542 G1UpdateRSOrPushRefOopClosure:: |
542 G1UpdateRSOrPushRefOopClosure:: |
543 G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h, |
543 G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h, |
544 G1RemSet* rs, |
544 G1RemSet* rs, |
545 OopsInHeapRegionClosure* push_ref_cl, |
545 OopsInHeapRegionClosure* push_ref_cl, |
546 bool record_refs_into_cset, |
546 bool record_refs_into_cset, |
547 int worker_i) : |
547 uint worker_i) : |
548 _g1(g1h), _g1_rem_set(rs), _from(NULL), |
548 _g1(g1h), _g1_rem_set(rs), _from(NULL), |
549 _record_refs_into_cset(record_refs_into_cset), |
549 _record_refs_into_cset(record_refs_into_cset), |
550 _push_ref_cl(push_ref_cl), _worker_i(worker_i) { } |
550 _push_ref_cl(push_ref_cl), _worker_i(worker_i) { } |
551 |
551 |
552 // Returns true if the given card contains references that point |
552 // Returns true if the given card contains references that point |
553 // into the collection set, if we're checking for such references; |
553 // into the collection set, if we're checking for such references; |
554 // false otherwise. |
554 // false otherwise. |
555 |
555 |
556 bool G1RemSet::refine_card(jbyte* card_ptr, int worker_i, |
556 bool G1RemSet::refine_card(jbyte* card_ptr, uint worker_i, |
557 bool check_for_refs_into_cset) { |
557 bool check_for_refs_into_cset) { |
558 |
558 |
559 // If the card is no longer dirty, nothing to do. |
559 // If the card is no longer dirty, nothing to do. |
560 if (*card_ptr != CardTableModRefBS::dirty_card_val()) { |
560 if (*card_ptr != CardTableModRefBS::dirty_card_val()) { |
561 // No need to return that this card contains refs that point |
561 // No need to return that this card contains refs that point |