80
81 uint G1RemSet::num_par_rem_sets() {
82 return MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads);
83 }
84
85 void G1RemSet::initialize(uint max_regions) {
86 G1FromCardCache::initialize(num_par_rem_sets(), max_regions);
87 }
88
89 ScanRSClosure::ScanRSClosure(G1ParPushHeapRSClosure* oc,
90 CodeBlobClosure* code_root_cl,
91 uint worker_i) :
92 _oc(oc),
93 _code_root_cl(code_root_cl),
94 _strong_code_root_scan_time_sec(0.0),
95 _cards(0),
96 _cards_done(0),
97 _worker_i(worker_i),
98 _try_claimed(false) {
99 _g1h = G1CollectedHeap::heap();
100 _bot_shared = _g1h->bot_shared();
101 _ct_bs = _g1h->g1_barrier_set();
102 _block_size = MAX2<size_t>(G1RSetScanBlockSize, 1);
103 }
104
105 void ScanRSClosure::scanCard(size_t index, HeapRegion *r) {
106 // Stack allocate the DirtyCardToOopClosure instance
107 HeapRegionDCTOC cl(_g1h, r, _oc,
108 CardTableModRefBS::Precise);
109
110 // Set the "from" region in the closure.
111 _oc->set_region(r);
112 MemRegion card_region(_bot_shared->address_for_index(index), G1BlockOffsetSharedArray::N_words);
113 MemRegion pre_gc_allocated(r->bottom(), r->scan_top());
114 MemRegion mr = pre_gc_allocated.intersection(card_region);
115 if (!mr.is_empty() && !_ct_bs->is_card_claimed(index)) {
116 // We make the card as "claimed" lazily (so races are possible
117 // but they're benign), which reduces the number of duplicate
118 // scans (the rsets of the regions in the cset can intersect).
119 _ct_bs->set_card_claimed(index);
120 _cards_done++;
121 cl.do_MemRegion(mr);
122 }
123 }
124
125 void ScanRSClosure::scan_strong_code_roots(HeapRegion* r) {
126 double scan_start = os::elapsedTime();
127 r->strong_code_roots_do(_code_root_cl);
128 _strong_code_root_scan_time_sec += (os::elapsedTime() - scan_start);
129 }
130
131 bool ScanRSClosure::doHeapRegion(HeapRegion* r) {
132 assert(r->in_collection_set(), "should only be called on elements of CS.");
136 // If we ever free the collection set concurrently, we should also
137 // clear the card table concurrently therefore we won't need to
138 // add regions of the collection set to the dirty cards region.
139 _g1h->push_dirty_cards_region(r);
140 // If we didn't return above, then
141 // _try_claimed || r->claim_iter()
142 // is true: either we're supposed to work on claimed-but-not-complete
143 // regions, or we successfully claimed the region.
144
145 HeapRegionRemSetIterator iter(hrrs);
146 size_t card_index;
147
148 // We claim cards in block so as to reduce the contention. The block size is determined by
149 // the G1RSetScanBlockSize parameter.
150 size_t jump_to_card = hrrs->iter_claimed_next(_block_size);
151 for (size_t current_card = 0; iter.has_next(card_index); current_card++) {
152 if (current_card >= jump_to_card + _block_size) {
153 jump_to_card = hrrs->iter_claimed_next(_block_size);
154 }
155 if (current_card < jump_to_card) continue;
156 HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index);
157
158 HeapRegion* card_region = _g1h->heap_region_containing(card_start);
159 _cards++;
160
161 if (!card_region->is_on_dirty_cards_region_list()) {
162 _g1h->push_dirty_cards_region(card_region);
163 }
164
165 // If the card is dirty, then we will scan it during updateRS.
166 if (!card_region->in_collection_set() &&
167 !_ct_bs->is_card_dirty(card_index)) {
168 scanCard(card_index, card_region);
169 }
170 }
171 if (!_try_claimed) {
172 // Scan the strong code root list attached to the current region
173 scan_strong_code_roots(r);
174
175 hrrs->set_iter_complete();
176 }
|
80
81 uint G1RemSet::num_par_rem_sets() {
82 return MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads);
83 }
84
85 void G1RemSet::initialize(uint max_regions) {
86 G1FromCardCache::initialize(num_par_rem_sets(), max_regions);
87 }
88
89 ScanRSClosure::ScanRSClosure(G1ParPushHeapRSClosure* oc,
90 CodeBlobClosure* code_root_cl,
91 uint worker_i) :
92 _oc(oc),
93 _code_root_cl(code_root_cl),
94 _strong_code_root_scan_time_sec(0.0),
95 _cards(0),
96 _cards_done(0),
97 _worker_i(worker_i),
98 _try_claimed(false) {
99 _g1h = G1CollectedHeap::heap();
100 _bot = _g1h->bot();
101 _ct_bs = _g1h->g1_barrier_set();
102 _block_size = MAX2<size_t>(G1RSetScanBlockSize, 1);
103 }
104
105 void ScanRSClosure::scanCard(size_t index, HeapRegion *r) {
106 // Stack allocate the DirtyCardToOopClosure instance
107 HeapRegionDCTOC cl(_g1h, r, _oc,
108 CardTableModRefBS::Precise);
109
110 // Set the "from" region in the closure.
111 _oc->set_region(r);
112 MemRegion card_region(_bot->address_for_index(index), G1BlockOffsetTable::N_words);
113 MemRegion pre_gc_allocated(r->bottom(), r->scan_top());
114 MemRegion mr = pre_gc_allocated.intersection(card_region);
115 if (!mr.is_empty() && !_ct_bs->is_card_claimed(index)) {
116 // We make the card as "claimed" lazily (so races are possible
117 // but they're benign), which reduces the number of duplicate
118 // scans (the rsets of the regions in the cset can intersect).
119 _ct_bs->set_card_claimed(index);
120 _cards_done++;
121 cl.do_MemRegion(mr);
122 }
123 }
124
125 void ScanRSClosure::scan_strong_code_roots(HeapRegion* r) {
126 double scan_start = os::elapsedTime();
127 r->strong_code_roots_do(_code_root_cl);
128 _strong_code_root_scan_time_sec += (os::elapsedTime() - scan_start);
129 }
130
131 bool ScanRSClosure::doHeapRegion(HeapRegion* r) {
132 assert(r->in_collection_set(), "should only be called on elements of CS.");
136 // If we ever free the collection set concurrently, we should also
137 // clear the card table concurrently therefore we won't need to
138 // add regions of the collection set to the dirty cards region.
139 _g1h->push_dirty_cards_region(r);
140 // If we didn't return above, then
141 // _try_claimed || r->claim_iter()
142 // is true: either we're supposed to work on claimed-but-not-complete
143 // regions, or we successfully claimed the region.
144
145 HeapRegionRemSetIterator iter(hrrs);
146 size_t card_index;
147
148 // We claim cards in block so as to reduce the contention. The block size is determined by
149 // the G1RSetScanBlockSize parameter.
150 size_t jump_to_card = hrrs->iter_claimed_next(_block_size);
151 for (size_t current_card = 0; iter.has_next(card_index); current_card++) {
152 if (current_card >= jump_to_card + _block_size) {
153 jump_to_card = hrrs->iter_claimed_next(_block_size);
154 }
155 if (current_card < jump_to_card) continue;
156 HeapWord* card_start = _g1h->bot()->address_for_index(card_index);
157
158 HeapRegion* card_region = _g1h->heap_region_containing(card_start);
159 _cards++;
160
161 if (!card_region->is_on_dirty_cards_region_list()) {
162 _g1h->push_dirty_cards_region(card_region);
163 }
164
165 // If the card is dirty, then we will scan it during updateRS.
166 if (!card_region->in_collection_set() &&
167 !_ct_bs->is_card_dirty(card_index)) {
168 scanCard(card_index, card_region);
169 }
170 }
171 if (!_try_claimed) {
172 // Scan the strong code root list attached to the current region
173 scan_strong_code_roots(r);
174
175 hrrs->set_iter_complete();
176 }
|