< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp

Print this page
rev 59532 : 8246100: Shenandoah: walk roots in more efficient order
Reviewed-by: XXX
rev 59533 : 8246097: Shenandoah: limit parallelism in CLDG root handling
Reviewed-by: XXX


 185 }
 186 
 187 ShenandoahCodeCacheRoots::~ShenandoahCodeCacheRoots() {
 188   nmethod::oops_do_marking_epilogue();
 189 }
 190 
 191 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase) :
 192   _heap(ShenandoahHeap::heap()),
 193   _phase(phase),
 194   _worker_phase(phase) {
 195   assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
 196 }
 197 
 198 ShenandoahRootScanner::ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
 199   ShenandoahRootProcessor(phase),
 200   _serial_roots(phase),
 201   _thread_roots(phase, n_workers > 1),
 202   _code_roots(phase),
 203   _vm_roots(phase),
 204   _dedup_roots(phase),
 205   _cld_roots(phase) {
 206 }
 207 
 208 void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops) {
 209   CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
 210   MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
 211   roots_do(worker_id, oops, &clds_cl, &blobs_cl);
 212 }
 213 
 214 void ShenandoahRootScanner::strong_roots_do(uint worker_id, OopClosure* oops) {
 215   CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
 216   MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
 217   strong_roots_do(worker_id, oops, &clds_cl, &blobs_cl);
 218 }
 219 
 220 void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
 221   assert(!ShenandoahSafepoint::is_at_shenandoah_safepoint() ||
 222          !ShenandoahHeap::heap()->unload_classes(),
 223           "Expect class unloading when Shenandoah cycle is running");
 224   assert(clds != NULL, "Only possible with CLD closure");
 225 
 226   AlwaysTrueClosure always_true;
 227   ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
 228 
 229   ResourceMark rm;
 230 
 231   // Process serial-claiming roots first
 232   _serial_roots.oops_do(oops, worker_id);
 233 
 234    // Process light-weight/limited parallel roots then
 235   _vm_roots.oops_do(oops, worker_id);
 236   _dedup_roots.oops_do(&always_true, oops, worker_id);

 237 
 238   // Process heavy-weight/fully parallel roots the last
 239   _cld_roots.cld_do(clds, worker_id);
 240   _thread_roots.threads_do(&tc_cl, worker_id);
 241 }
 242 
 243 void ShenandoahRootScanner::strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc) {
 244   assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading");
 245   ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
 246 
 247   ResourceMark rm;
 248 
 249   // Process serial-claiming roots first
 250   _serial_roots.oops_do(oops, worker_id);
 251 
 252   // Process light-weight/limited parallel roots then
 253   _vm_roots.oops_do(oops, worker_id);

 254 
 255   // Process heavy-weight/fully parallel roots the last
 256   _cld_roots.always_strong_cld_do(clds, worker_id);
 257   _thread_roots.threads_do(&tc_cl, worker_id);
 258 }
 259 
 260 ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers,
 261                                                  ShenandoahPhaseTimings::Phase phase,
 262                                                  bool stw_roots_processing,
 263                                                  bool stw_class_unloading) :
 264   ShenandoahRootProcessor(phase),
 265   _serial_roots(phase),
 266   _vm_roots(phase),
 267   _cld_roots(phase),
 268   _thread_roots(phase, n_workers > 1),
 269   _serial_weak_roots(phase),
 270   _weak_roots(phase),
 271   _dedup_roots(phase),
 272   _code_roots(phase),
 273   _stw_roots_processing(stw_roots_processing),
 274   _stw_class_unloading(stw_class_unloading) {
 275 }
 276 
 277 void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) {
 278   MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations);
 279   ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
 280   CodeBlobToOopClosure* codes_cl = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
 281                                    static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
 282                                    static_cast<CodeBlobToOopClosure*>(&blobsCl);
 283   AlwaysTrueClosure always_true;
 284 
 285   // Process serial-claiming roots first
 286   _serial_roots.oops_do(oops, worker_id);
 287   _serial_weak_roots.weak_oops_do(oops, worker_id);
 288 
 289   // Process light-weight/limited parallel roots then
 290   if (_stw_roots_processing) {
 291     _vm_roots.oops_do<OopClosure>(oops, worker_id);
 292     _weak_roots.oops_do<OopClosure>(oops, worker_id);
 293     _dedup_roots.oops_do(&always_true, oops, worker_id);
 294   }
 295 
 296   // Process heavy-weight/fully parallel roots the last
 297   if (_stw_class_unloading) {
 298     CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
 299     _cld_roots.cld_do(&clds, worker_id);




 300     _code_roots.code_blobs_do(codes_cl, worker_id);
 301     _thread_roots.oops_do(oops, NULL, worker_id);
 302   } else {
 303     _thread_roots.oops_do(oops, codes_cl, worker_id);
 304   }
 305 }
 306 
 307 ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
 308   ShenandoahRootProcessor(phase),
 309   _serial_roots(phase),
 310   _vm_roots(phase),
 311   _cld_roots(phase),
 312   _thread_roots(phase, n_workers > 1),
 313   _serial_weak_roots(phase),
 314   _weak_roots(phase),
 315   _dedup_roots(phase),
 316   _code_roots(phase) {
 317 }
 318 
 319 ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
 320   ShenandoahRootProcessor(phase),
 321   _serial_roots(phase),
 322   _vm_roots(phase),
 323   _cld_roots(phase),
 324   _thread_roots(phase, n_workers > 1),
 325   _serial_weak_roots(phase),
 326   _weak_roots(phase),
 327   _dedup_roots(phase),
 328   _code_roots(phase) {
 329   assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only");
 330 }
 331 
 332 void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) {
 333   CodeBlobToOopClosure code_blob_cl(oops, CodeBlobToOopClosure::FixRelocations);
 334   ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
 335   CodeBlobToOopClosure* adjust_code_closure = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
 336                                               static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
 337                                               static_cast<CodeBlobToOopClosure*>(&code_blob_cl);
 338   CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong);
 339   AlwaysTrueClosure always_true;
 340 
 341   // Process serial-claiming roots first
 342   _serial_roots.oops_do(oops, worker_id);
 343   _serial_weak_roots.weak_oops_do(oops, worker_id);
 344 
 345   // Process light-weight/limited parallel roots then
 346   _vm_roots.oops_do(oops, worker_id);
 347   _weak_roots.oops_do<OopClosure>(oops, worker_id);
 348   _dedup_roots.oops_do(&always_true, oops, worker_id);

 349 
 350   // Process heavy-weight/fully parallel roots the last
 351   _cld_roots.cld_do(&adjust_cld_closure, worker_id);
 352   _code_roots.code_blobs_do(adjust_code_closure, worker_id);
 353   _thread_roots.oops_do(oops, NULL, worker_id);
 354 }
 355 
 356 ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner() :
 357    ShenandoahRootProcessor(ShenandoahPhaseTimings::heap_iteration_roots),
 358    _serial_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 359    _thread_roots(ShenandoahPhaseTimings::heap_iteration_roots, false /*is par*/),
 360    _vm_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 361    _cld_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 362    _serial_weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 363    _weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 364    _code_roots(ShenandoahPhaseTimings::heap_iteration_roots) {
 365  }
 366 
 367  void ShenandoahHeapIterationRootScanner::roots_do(OopClosure* oops) {
 368    assert(Thread::current()->is_VM_thread(), "Only by VM thread");
 369    // Must use _claim_none to avoid interfering with concurrent CLDG iteration
 370    CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
 371    MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations);
 372    ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL);
 373    AlwaysTrueClosure always_true;
 374 
 375    ResourceMark rm;
 376 
 377    // Process serial-claiming roots first
 378    _serial_roots.oops_do(oops, 0);
 379    _serial_weak_roots.weak_oops_do(oops, 0);
 380 
 381    // Process light-weight/limited parallel roots then
 382    _vm_roots.oops_do(oops, 0);
 383    _weak_roots.oops_do<OopClosure>(oops, 0);
 384    _dedup_roots.oops_do(&always_true, oops, 0);

 385 
 386    // Process heavy-weight/fully parallel roots the last
 387    _cld_roots.cld_do(&clds, 0);
 388    _code_roots.code_blobs_do(&code, 0);
 389    _thread_roots.threads_do(&tc_cl, 0);
 390  }


 185 }
 186 
 187 ShenandoahCodeCacheRoots::~ShenandoahCodeCacheRoots() {
 188   nmethod::oops_do_marking_epilogue();
 189 }
 190 
 191 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase) :
 192   _heap(ShenandoahHeap::heap()),
 193   _phase(phase),
 194   _worker_phase(phase) {
 195   assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
 196 }
 197 
 198 ShenandoahRootScanner::ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
 199   ShenandoahRootProcessor(phase),
 200   _serial_roots(phase),
 201   _thread_roots(phase, n_workers > 1),
 202   _code_roots(phase),
 203   _vm_roots(phase),
 204   _dedup_roots(phase),
 205   _cld_roots(phase, n_workers) {
 206 }
 207 
 208 void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops) {
 209   CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
 210   MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
 211   roots_do(worker_id, oops, &clds_cl, &blobs_cl);
 212 }
 213 
 214 void ShenandoahRootScanner::strong_roots_do(uint worker_id, OopClosure* oops) {
 215   CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
 216   MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
 217   strong_roots_do(worker_id, oops, &clds_cl, &blobs_cl);
 218 }
 219 
 220 void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
 221   assert(!ShenandoahSafepoint::is_at_shenandoah_safepoint() ||
 222          !ShenandoahHeap::heap()->unload_classes(),
 223           "Expect class unloading when Shenandoah cycle is running");
 224   assert(clds != NULL, "Only possible with CLD closure");
 225 
 226   AlwaysTrueClosure always_true;
 227   ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
 228 
 229   ResourceMark rm;
 230 
 231   // Process serial-claiming roots first
 232   _serial_roots.oops_do(oops, worker_id);
 233 
 234    // Process light-weight/limited parallel roots then
 235   _vm_roots.oops_do(oops, worker_id);
 236   _dedup_roots.oops_do(&always_true, oops, worker_id);
 237   _cld_roots.cld_do(clds, worker_id);
 238 
 239   // Process heavy-weight/fully parallel roots the last

 240   _thread_roots.threads_do(&tc_cl, worker_id);
 241 }
 242 
 243 void ShenandoahRootScanner::strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc) {
 244   assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading");
 245   ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
 246 
 247   ResourceMark rm;
 248 
 249   // Process serial-claiming roots first
 250   _serial_roots.oops_do(oops, worker_id);
 251 
 252   // Process light-weight/limited parallel roots then
 253   _vm_roots.oops_do(oops, worker_id);
 254   _cld_roots.always_strong_cld_do(clds, worker_id);
 255 
 256   // Process heavy-weight/fully parallel roots the last

 257   _thread_roots.threads_do(&tc_cl, worker_id);
 258 }
 259 
 260 ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers,
 261                                                  ShenandoahPhaseTimings::Phase phase,
 262                                                  bool stw_roots_processing,
 263                                                  bool stw_class_unloading) :
 264   ShenandoahRootProcessor(phase),
 265   _serial_roots(phase),
 266   _vm_roots(phase),
 267   _cld_roots(phase, n_workers),
 268   _thread_roots(phase, n_workers > 1),
 269   _serial_weak_roots(phase),
 270   _weak_roots(phase),
 271   _dedup_roots(phase),
 272   _code_roots(phase),
 273   _stw_roots_processing(stw_roots_processing),
 274   _stw_class_unloading(stw_class_unloading) {
 275 }
 276 
 277 void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) {
 278   MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations);
 279   ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
 280   CodeBlobToOopClosure* codes_cl = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
 281                                    static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
 282                                    static_cast<CodeBlobToOopClosure*>(&blobsCl);
 283   AlwaysTrueClosure always_true;
 284 
 285   // Process serial-claiming roots first
 286   _serial_roots.oops_do(oops, worker_id);
 287   _serial_weak_roots.weak_oops_do(oops, worker_id);
 288 
 289   // Process light-weight/limited parallel roots then
 290   if (_stw_roots_processing) {
 291     _vm_roots.oops_do<OopClosure>(oops, worker_id);
 292     _weak_roots.oops_do<OopClosure>(oops, worker_id);
 293     _dedup_roots.oops_do(&always_true, oops, worker_id);
 294   }


 295   if (_stw_class_unloading) {
 296     CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
 297     _cld_roots.cld_do(&clds, worker_id);
 298   }
 299 
 300   // Process heavy-weight/fully parallel roots the last
 301   if (_stw_class_unloading) {
 302     _code_roots.code_blobs_do(codes_cl, worker_id);
 303     _thread_roots.oops_do(oops, NULL, worker_id);
 304   } else {
 305     _thread_roots.oops_do(oops, codes_cl, worker_id);
 306   }
 307 }
 308 
 309 ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
 310   ShenandoahRootProcessor(phase),
 311   _serial_roots(phase),
 312   _vm_roots(phase),
 313   _cld_roots(phase, n_workers),
 314   _thread_roots(phase, n_workers > 1),
 315   _serial_weak_roots(phase),
 316   _weak_roots(phase),
 317   _dedup_roots(phase),
 318   _code_roots(phase) {
 319 }
 320 
 321 ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
 322   ShenandoahRootProcessor(phase),
 323   _serial_roots(phase),
 324   _vm_roots(phase),
 325   _cld_roots(phase, n_workers),
 326   _thread_roots(phase, n_workers > 1),
 327   _serial_weak_roots(phase),
 328   _weak_roots(phase),
 329   _dedup_roots(phase),
 330   _code_roots(phase) {
 331   assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only");
 332 }
 333 
 334 void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) {
 335   CodeBlobToOopClosure code_blob_cl(oops, CodeBlobToOopClosure::FixRelocations);
 336   ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
 337   CodeBlobToOopClosure* adjust_code_closure = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
 338                                               static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
 339                                               static_cast<CodeBlobToOopClosure*>(&code_blob_cl);
 340   CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong);
 341   AlwaysTrueClosure always_true;
 342 
 343   // Process serial-claiming roots first
 344   _serial_roots.oops_do(oops, worker_id);
 345   _serial_weak_roots.weak_oops_do(oops, worker_id);
 346 
 347   // Process light-weight/limited parallel roots then
 348   _vm_roots.oops_do(oops, worker_id);
 349   _weak_roots.oops_do<OopClosure>(oops, worker_id);
 350   _dedup_roots.oops_do(&always_true, oops, worker_id);
 351   _cld_roots.cld_do(&adjust_cld_closure, worker_id);
 352 
 353   // Process heavy-weight/fully parallel roots the last

 354   _code_roots.code_blobs_do(adjust_code_closure, worker_id);
 355   _thread_roots.oops_do(oops, NULL, worker_id);
 356 }
 357 
 358 ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner() :
 359    ShenandoahRootProcessor(ShenandoahPhaseTimings::heap_iteration_roots),
 360    _serial_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 361    _thread_roots(ShenandoahPhaseTimings::heap_iteration_roots, false /*is par*/),
 362    _vm_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 363    _cld_roots(ShenandoahPhaseTimings::heap_iteration_roots, 1),
 364    _serial_weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 365    _weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 366    _code_roots(ShenandoahPhaseTimings::heap_iteration_roots) {
 367  }
 368 
 369  void ShenandoahHeapIterationRootScanner::roots_do(OopClosure* oops) {
 370    assert(Thread::current()->is_VM_thread(), "Only by VM thread");
 371    // Must use _claim_none to avoid interfering with concurrent CLDG iteration
 372    CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
 373    MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations);
 374    ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL);
 375    AlwaysTrueClosure always_true;
 376 
 377    ResourceMark rm;
 378 
 379    // Process serial-claiming roots first
 380    _serial_roots.oops_do(oops, 0);
 381    _serial_weak_roots.weak_oops_do(oops, 0);
 382 
 383    // Process light-weight/limited parallel roots then
 384    _vm_roots.oops_do(oops, 0);
 385    _weak_roots.oops_do<OopClosure>(oops, 0);
 386    _dedup_roots.oops_do(&always_true, oops, 0);
 387    _cld_roots.cld_do(&clds, 0);
 388 
 389    // Process heavy-weight/fully parallel roots the last

 390    _code_roots.code_blobs_do(&code, 0);
 391    _thread_roots.threads_do(&tc_cl, 0);
 392  }
< prev index next >