102 } |
102 } |
103 |
103 |
104 class ScanRSClosure : public HeapRegionClosure { |
104 class ScanRSClosure : public HeapRegionClosure { |
105 size_t _cards_done, _cards; |
105 size_t _cards_done, _cards; |
106 G1CollectedHeap* _g1h; |
106 G1CollectedHeap* _g1h; |
|
107 |
107 OopsInHeapRegionClosure* _oc; |
108 OopsInHeapRegionClosure* _oc; |
|
109 CodeBlobToOopClosure* _code_root_cl; |
|
110 |
108 G1BlockOffsetSharedArray* _bot_shared; |
111 G1BlockOffsetSharedArray* _bot_shared; |
109 CardTableModRefBS *_ct_bs; |
112 CardTableModRefBS *_ct_bs; |
110 int _worker_i; |
113 |
111 int _block_size; |
114 double _strong_code_root_scan_time_sec; |
112 bool _try_claimed; |
115 int _worker_i; |
|
116 int _block_size; |
|
117 bool _try_claimed; |
|
118 |
113 public: |
119 public: |
114 ScanRSClosure(OopsInHeapRegionClosure* oc, int worker_i) : |
120 ScanRSClosure(OopsInHeapRegionClosure* oc, |
|
121 CodeBlobToOopClosure* code_root_cl, |
|
122 int worker_i) : |
115 _oc(oc), |
123 _oc(oc), |
|
124 _code_root_cl(code_root_cl), |
|
125 _strong_code_root_scan_time_sec(0.0), |
116 _cards(0), |
126 _cards(0), |
117 _cards_done(0), |
127 _cards_done(0), |
118 _worker_i(worker_i), |
128 _worker_i(worker_i), |
119 _try_claimed(false) |
129 _try_claimed(false) |
120 { |
130 { |
158 card_region->bottom(), card_region->end(), |
168 card_region->bottom(), card_region->end(), |
159 card_index, |
169 card_index, |
160 card_start, card_start + G1BlockOffsetSharedArray::N_words); |
170 card_start, card_start + G1BlockOffsetSharedArray::N_words); |
161 } |
171 } |
162 |
172 |
|
173 void scan_strong_code_roots(HeapRegion* r) { |
|
174 double scan_start = os::elapsedTime(); |
|
175 r->strong_code_roots_do(_code_root_cl); |
|
176 _strong_code_root_scan_time_sec += (os::elapsedTime() - scan_start); |
|
177 } |
|
178 |
163 bool doHeapRegion(HeapRegion* r) { |
179 bool doHeapRegion(HeapRegion* r) { |
164 assert(r->in_collection_set(), "should only be called on elements of CS."); |
180 assert(r->in_collection_set(), "should only be called on elements of CS."); |
165 HeapRegionRemSet* hrrs = r->rem_set(); |
181 HeapRegionRemSet* hrrs = r->rem_set(); |
166 if (hrrs->iter_is_complete()) return false; // All done. |
182 if (hrrs->iter_is_complete()) return false; // All done. |
167 if (!_try_claimed && !hrrs->claim_iter()) return false; |
183 if (!_try_claimed && !hrrs->claim_iter()) return false; |
171 _g1h->push_dirty_cards_region(r); |
187 _g1h->push_dirty_cards_region(r); |
172 // If we didn't return above, then |
188 // If we didn't return above, then |
173 // _try_claimed || r->claim_iter() |
189 // _try_claimed || r->claim_iter() |
174 // is true: either we're supposed to work on claimed-but-not-complete |
190 // is true: either we're supposed to work on claimed-but-not-complete |
175 // regions, or we successfully claimed the region. |
191 // regions, or we successfully claimed the region. |
|
192 |
176 HeapRegionRemSetIterator iter(hrrs); |
193 HeapRegionRemSetIterator iter(hrrs); |
177 size_t card_index; |
194 size_t card_index; |
178 |
195 |
179 // We claim cards in block so as to recude the contention. The block size is determined by |
196 // We claim cards in block so as to recude the contention. The block size is determined by |
180 // the G1RSetScanBlockSize parameter. |
197 // the G1RSetScanBlockSize parameter. |
203 !_ct_bs->is_card_dirty(card_index)) { |
220 !_ct_bs->is_card_dirty(card_index)) { |
204 scanCard(card_index, card_region); |
221 scanCard(card_index, card_region); |
205 } |
222 } |
206 } |
223 } |
207 if (!_try_claimed) { |
224 if (!_try_claimed) { |
|
225 // Scan the strong code root list attached to the current region |
|
226 scan_strong_code_roots(r); |
|
227 |
208 hrrs->set_iter_complete(); |
228 hrrs->set_iter_complete(); |
209 } |
229 } |
210 return false; |
230 return false; |
211 } |
231 } |
|
232 |
|
233 double strong_code_root_scan_time_sec() { |
|
234 return _strong_code_root_scan_time_sec; |
|
235 } |
|
236 |
212 size_t cards_done() { return _cards_done;} |
237 size_t cards_done() { return _cards_done;} |
213 size_t cards_looked_up() { return _cards;} |
238 size_t cards_looked_up() { return _cards;} |
214 }; |
239 }; |
215 |
240 |
216 void G1RemSet::scanRS(OopsInHeapRegionClosure* oc, int worker_i) { |
241 void G1RemSet::scanRS(OopsInHeapRegionClosure* oc, |
|
242 CodeBlobToOopClosure* code_root_cl, |
|
243 int worker_i) { |
217 double rs_time_start = os::elapsedTime(); |
244 double rs_time_start = os::elapsedTime(); |
218 HeapRegion *startRegion = _g1->start_cset_region_for_worker(worker_i); |
245 HeapRegion *startRegion = _g1->start_cset_region_for_worker(worker_i); |
219 |
246 |
220 ScanRSClosure scanRScl(oc, worker_i); |
247 ScanRSClosure scanRScl(oc, code_root_cl, worker_i); |
221 |
248 |
222 _g1->collection_set_iterate_from(startRegion, &scanRScl); |
249 _g1->collection_set_iterate_from(startRegion, &scanRScl); |
223 scanRScl.set_try_claimed(); |
250 scanRScl.set_try_claimed(); |
224 _g1->collection_set_iterate_from(startRegion, &scanRScl); |
251 _g1->collection_set_iterate_from(startRegion, &scanRScl); |
225 |
252 |
226 double scan_rs_time_sec = os::elapsedTime() - rs_time_start; |
253 double scan_rs_time_sec = (os::elapsedTime() - rs_time_start) |
227 |
254 - scanRScl.strong_code_root_scan_time_sec(); |
228 assert( _cards_scanned != NULL, "invariant" ); |
255 |
|
256 assert(_cards_scanned != NULL, "invariant"); |
229 _cards_scanned[worker_i] = scanRScl.cards_done(); |
257 _cards_scanned[worker_i] = scanRScl.cards_done(); |
230 |
258 |
231 _g1p->phase_times()->record_scan_rs_time(worker_i, scan_rs_time_sec * 1000.0); |
259 _g1p->phase_times()->record_scan_rs_time(worker_i, scan_rs_time_sec * 1000.0); |
|
260 _g1p->phase_times()->record_strong_code_root_scan_time(worker_i, |
|
261 scanRScl.strong_code_root_scan_time_sec() * 1000.0); |
232 } |
262 } |
233 |
263 |
234 // Closure used for updating RSets and recording references that |
264 // Closure used for updating RSets and recording references that |
235 // point into the collection set. Only called during an |
265 // point into the collection set. Only called during an |
236 // evacuation pause. |
266 // evacuation pause. |
286 void G1RemSet::cleanupHRRS() { |
316 void G1RemSet::cleanupHRRS() { |
287 HeapRegionRemSet::cleanup(); |
317 HeapRegionRemSet::cleanup(); |
288 } |
318 } |
289 |
319 |
290 void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc, |
320 void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc, |
291 int worker_i) { |
321 CodeBlobToOopClosure* code_root_cl, |
|
322 int worker_i) { |
292 #if CARD_REPEAT_HISTO |
323 #if CARD_REPEAT_HISTO |
293 ct_freq_update_histo_and_reset(); |
324 ct_freq_update_histo_and_reset(); |
294 #endif |
325 #endif |
295 |
326 |
296 // We cache the value of 'oc' closure into the appropriate slot in the |
327 // We cache the value of 'oc' closure into the appropriate slot in the |
326 } else { |
357 } else { |
327 _g1p->phase_times()->record_update_rs_processed_buffers(worker_i, 0); |
358 _g1p->phase_times()->record_update_rs_processed_buffers(worker_i, 0); |
328 _g1p->phase_times()->record_update_rs_time(worker_i, 0.0); |
359 _g1p->phase_times()->record_update_rs_time(worker_i, 0.0); |
329 } |
360 } |
330 if (G1UseParallelRSetScanning || (worker_i == 0)) { |
361 if (G1UseParallelRSetScanning || (worker_i == 0)) { |
331 scanRS(oc, worker_i); |
362 scanRS(oc, code_root_cl, worker_i); |
332 } else { |
363 } else { |
333 _g1p->phase_times()->record_scan_rs_time(worker_i, 0.0); |
364 _g1p->phase_times()->record_scan_rs_time(worker_i, 0.0); |
334 } |
365 } |
335 |
366 |
336 // We now clear the cached values of _cset_rs_update_cl for this worker |
367 // We now clear the cached values of _cset_rs_update_cl for this worker |