Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/g1/g1RemSet.cpp @ 12080:5888334c9c24
7145569: G1: optimize nmethods scanning
Summary: Add a list of nmethods to the RSet for a region that contain references into the region. Skip scanning the code cache during root scanning and scan the nmethod lists during RSet scanning instead.
Reviewed-by: tschatzl, brutisso, mgerdin, twisti, kvn
author | johnc |
---|---|
date | Thu, 15 Aug 2013 10:52:18 +0200 |
parents | 3a4805ad0005 |
children | c319b188c7b2 |
comparison
equal
deleted
inserted
replaced
12033:bd902affe102 | 12080:5888334c9c24 |
---|---|
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 |