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