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