< prev index next >

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

Print this page
rev 59271 : 8240870: Shenandoah: merge evac and update phases
Reviewed-by: XXX


 296     }
 297     os::naked_short_sleep(sleep);
 298   }
 299 
 300   // Wait for the actual stop(), can't leave run_service() earlier.
 301   while (!should_terminate()) {
 302     os::naked_short_sleep(ShenandoahControlIntervalMin);
 303   }
 304 }
 305 
 306 void ShenandoahControlThread::service_concurrent_normal_cycle(GCCause::Cause cause) {
 307   // Normal cycle goes via all concurrent phases. If allocation failure (af) happens during
 308   // any of the concurrent phases, it first degrades to Degenerated GC and completes GC there.
 309   // If second allocation failure happens during Degenerated GC cycle (for example, when GC
 310   // tries to evac something and no memory is available), cycle degrades to Full GC.
 311   //
 312   // There are also a shortcut through the normal cycle: immediate garbage shortcut, when
 313   // heuristics says there are no regions to compact, and all the collection comes from immediately
 314   // reclaimable regions.
 315   //
 316   // ................................................................................................
 317   //
 318   //                                    (immediate garbage shortcut)                Concurrent GC
 319   //                             /-------------------------------------------\
 320   //                             |                                           |
 321   //                             |                                           |
 322   //                             |                                           |
 323   //                             |                                           v
 324   // [START] ----> Conc Mark ----o----> Conc Evac --o--> Conc Update-Refs ---o----> [END]
 325   //                   |                    |                 |              ^
 326   //                   | (af)               | (af)            | (af)         |
 327   // ..................|....................|.................|..............|.......................
 328   //                   |                    |                 |              |
 329   //                   |                    |                 |              |      Degenerated GC
 330   //                   v                    v                 v              |
 331   //               STW Mark ----------> STW Evac ----> STW Update-Refs ----->o
 332   //                   |                    |                 |              ^
 333   //                   | (af)               | (af)            | (af)         |
 334   // ..................|....................|.................|..............|.......................
 335   //                   |                    |                 |              |
 336   //                   |                    v                 |              |      Full GC
 337   //                   \------------------->o<----------------/              |
 338   //                                        |                                |
 339   //                                        v                                |
 340   //                                      Full GC  --------------------------/
 341   //
 342   ShenandoahHeap* heap = ShenandoahHeap::heap();
 343 
 344   if (check_cancellation_or_degen(ShenandoahHeap::_degenerated_outside_cycle)) return;
 345 
 346   GCIdMark gc_id_mark;
 347   ShenandoahGCSession session(cause);
 348 
 349   TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
 350 
 351   // Reset for upcoming marking
 352   heap->entry_reset();
 353 
 354   // Start initial mark under STW
 355   heap->vmop_entry_init_mark();
 356 
 357   // Continue concurrent mark
 358   heap->entry_mark();
 359   if (check_cancellation_or_degen(ShenandoahHeap::_degenerated_mark)) return;
 360 


 377     ShenandoahHeapLocker locker(heap->lock());
 378     heap->free_set()->log_status();
 379   }
 380 
 381   // Perform concurrent class unloading
 382   if (heap->is_concurrent_weak_root_in_progress()) {
 383     heap->entry_class_unloading();
 384   }
 385 
 386   // Processing strong roots
 387   // This may be skipped if there is nothing to update/evacuate.
 388   // If so, strong_root_in_progress would be unset.
 389   if (heap->is_concurrent_strong_root_in_progress()) {
 390     heap->entry_strong_roots();
 391   }
 392 
 393   // Continue the cycle with evacuation and optional update-refs.
 394   // This may be skipped if there is nothing to evacuate.
 395   // If so, evac_in_progress would be unset by collection set preparation code.
 396   if (heap->is_evacuation_in_progress()) {
 397     // Concurrently evacuate
 398     heap->entry_evac();
 399     if (check_cancellation_or_degen(ShenandoahHeap::_degenerated_evac)) return;
 400 
 401     // Perform update-refs phase.
 402     heap->vmop_entry_init_updaterefs();
 403     heap->entry_updaterefs();
 404     if (check_cancellation_or_degen(ShenandoahHeap::_degenerated_updaterefs)) return;
 405 
 406     heap->vmop_entry_final_updaterefs();




 407 
 408     // Update references freed up collection set, kick the cleanup to reclaim the space.
 409     heap->entry_cleanup_complete();
 410   }
 411 
 412   // Cycle is complete
 413   heap->heuristics()->record_success_concurrent();
 414   heap->shenandoah_policy()->record_success_concurrent();
 415 }
 416 
 417 bool ShenandoahControlThread::check_cancellation_or_degen(ShenandoahHeap::ShenandoahDegenPoint point) {
 418   ShenandoahHeap* heap = ShenandoahHeap::heap();
 419   if (heap->cancelled_gc()) {
 420     assert (is_alloc_failure_gc() || in_graceful_shutdown(), "Cancel GC either for alloc failure GC, or gracefully exiting");
 421     if (!in_graceful_shutdown()) {
 422       assert (_degen_point == ShenandoahHeap::_degenerated_outside_cycle,
 423               "Should not be set yet: %s", ShenandoahHeap::degen_point_to_string(_degen_point));
 424       _degen_point = point;
 425     }
 426     return true;




 296     }
 297     os::naked_short_sleep(sleep);
 298   }
 299 
 300   // Wait for the actual stop(), can't leave run_service() earlier.
 301   while (!should_terminate()) {
 302     os::naked_short_sleep(ShenandoahControlIntervalMin);
 303   }
 304 }
 305 
 306 void ShenandoahControlThread::service_concurrent_normal_cycle(GCCause::Cause cause) {
 307   // Normal cycle goes via all concurrent phases. If allocation failure (af) happens during
 308   // any of the concurrent phases, it first degrades to Degenerated GC and completes GC there.
 309   // If second allocation failure happens during Degenerated GC cycle (for example, when GC
 310   // tries to evac something and no memory is available), cycle degrades to Full GC.
 311   //
 312   // There are also a shortcut through the normal cycle: immediate garbage shortcut, when
 313   // heuristics says there are no regions to compact, and all the collection comes from immediately
 314   // reclaimable regions.
 315   //
 316   // ........................................................................................
 317   //
 318   //                                (immediate garbage shortcut)            Concurrent GC
 319   //                             /-----------------------------------\
 320   //                             |                                   |
 321   //                             |                                   |
 322   //                             |                                   |
 323   //                             |                                   v
 324   // [START] ----> Conc Mark ----o---> Conc Evac-Update ---------> [END]
 325   //                   |                     |                       ^
 326   //                   | (af)                | (af)                  |
 327   // ..................|.....................|.......................|.......................
 328   //                   |                     |                       |
 329   //                   |                     |                       |      Degenerated GC
 330   //                   v                     v                       |
 331   //               STW Mark ---------> STW Evac-Update ------------->o
 332   //                   |                     |                       ^
 333   //                   | (af)                | (af)                  |
 334   // ..................|.....................|.......................|.......................
 335   //                   |                     |                       |
 336   //                   |                     v                       |      Full GC
 337   //                   \-------------------->o                       |
 338   //                                         |                       |
 339   //                                         v                       |
 340   //                                      Full GC  ------------------/
 341   //
 342   ShenandoahHeap* heap = ShenandoahHeap::heap();
 343 
 344   if (check_cancellation_or_degen(ShenandoahHeap::_degenerated_outside_cycle)) return;
 345 
 346   GCIdMark gc_id_mark;
 347   ShenandoahGCSession session(cause);
 348 
 349   TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
 350 
 351   // Reset for upcoming marking
 352   heap->entry_reset();
 353 
 354   // Start initial mark under STW
 355   heap->vmop_entry_init_mark();
 356 
 357   // Continue concurrent mark
 358   heap->entry_mark();
 359   if (check_cancellation_or_degen(ShenandoahHeap::_degenerated_mark)) return;
 360 


 377     ShenandoahHeapLocker locker(heap->lock());
 378     heap->free_set()->log_status();
 379   }
 380 
 381   // Perform concurrent class unloading
 382   if (heap->is_concurrent_weak_root_in_progress()) {
 383     heap->entry_class_unloading();
 384   }
 385 
 386   // Processing strong roots
 387   // This may be skipped if there is nothing to update/evacuate.
 388   // If so, strong_root_in_progress would be unset.
 389   if (heap->is_concurrent_strong_root_in_progress()) {
 390     heap->entry_strong_roots();
 391   }
 392 
 393   // Continue the cycle with evacuation and optional update-refs.
 394   // This may be skipped if there is nothing to evacuate.
 395   // If so, evac_in_progress would be unset by collection set preparation code.
 396   if (heap->is_evacuation_in_progress()) {
 397     heap->vmop_entry_init_evac_update();







 398 
 399     // Concurrently evacuate and update the refs
 400     heap->entry_evac_update();
 401     if (check_cancellation_or_degen(ShenandoahHeap::_degenerated_evac_update)) return;
 402 
 403     heap->vmop_entry_final_evac_update();
 404 
 405     // Update references freed up collection set, kick the cleanup to reclaim the space.
 406     heap->entry_cleanup_complete();
 407   }
 408 
 409   // Cycle is complete
 410   heap->heuristics()->record_success_concurrent();
 411   heap->shenandoah_policy()->record_success_concurrent();
 412 }
 413 
 414 bool ShenandoahControlThread::check_cancellation_or_degen(ShenandoahHeap::ShenandoahDegenPoint point) {
 415   ShenandoahHeap* heap = ShenandoahHeap::heap();
 416   if (heap->cancelled_gc()) {
 417     assert (is_alloc_failure_gc() || in_graceful_shutdown(), "Cancel GC either for alloc failure GC, or gracefully exiting");
 418     if (!in_graceful_shutdown()) {
 419       assert (_degen_point == ShenandoahHeap::_degenerated_outside_cycle,
 420               "Should not be set yet: %s", ShenandoahHeap::degen_point_to_string(_degen_point));
 421       _degen_point = point;
 422     }
 423     return true;


< prev index next >