< prev index next >

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

Print this page
rev 55538 : 8226757: Shenandoah: Make Traversal a separate mode


  33 #include "gc/shared/plab.hpp"
  34 
  35 #include "gc/shenandoah/shenandoahAllocTracker.hpp"
  36 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
  37 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
  38 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
  39 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
  40 #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp"
  41 #include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
  42 #include "gc/shenandoah/shenandoahControlThread.hpp"
  43 #include "gc/shenandoah/shenandoahFreeSet.hpp"
  44 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
  45 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
  46 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
  47 #include "gc/shenandoah/shenandoahHeapRegionSet.hpp"
  48 #include "gc/shenandoah/shenandoahMarkCompact.hpp"
  49 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
  50 #include "gc/shenandoah/shenandoahMemoryPool.hpp"
  51 #include "gc/shenandoah/shenandoahMetrics.hpp"
  52 #include "gc/shenandoah/shenandoahMonitoringSupport.hpp"

  53 #include "gc/shenandoah/shenandoahOopClosures.inline.hpp"
  54 #include "gc/shenandoah/shenandoahPacer.inline.hpp"

  55 #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp"
  56 #include "gc/shenandoah/shenandoahStringDedup.hpp"
  57 #include "gc/shenandoah/shenandoahTaskqueue.hpp"

  58 #include "gc/shenandoah/shenandoahUtils.hpp"
  59 #include "gc/shenandoah/shenandoahVerifier.hpp"
  60 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
  61 #include "gc/shenandoah/shenandoahVMOperations.hpp"
  62 #include "gc/shenandoah/shenandoahWorkGroup.hpp"
  63 #include "gc/shenandoah/shenandoahWorkerPolicy.hpp"
  64 #include "gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp"
  65 #include "gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp"
  66 #include "gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp"
  67 #include "gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp"
  68 #include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp"
  69 #include "gc/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp"
  70 #if INCLUDE_JFR
  71 #include "gc/shenandoah/shenandoahJfrSupport.hpp"
  72 #endif
  73 
  74 #include "memory/metaspace.hpp"
  75 #include "oops/compressedOops.inline.hpp"
  76 #include "runtime/globals.hpp"
  77 #include "runtime/interfaceSupport.inline.hpp"
  78 #include "runtime/safepointMechanism.hpp"
  79 #include "runtime/vmThread.hpp"
  80 #include "services/mallocTracker.hpp"
  81 
  82 #ifdef ASSERT
  83 template <class T>
  84 void ShenandoahAssertToSpaceClosure::do_oop_work(T* p) {
  85   T o = RawAccess<>::oop_load(p);
  86   if (! CompressedOops::is_null(o)) {
  87     oop obj = CompressedOops::decode_not_null(o);
  88     shenandoah_assert_not_forwarded(p, obj);
  89   }


 350   ShenandoahBarrierSet::satb_mark_queue_set().initialize(this,
 351                                                          20 /* G1SATBProcessCompletedThreshold */,
 352                                                          60 /* G1SATBBufferEnqueueingThresholdPercent */);
 353 
 354   _monitoring_support = new ShenandoahMonitoringSupport(this);
 355   _phase_timings = new ShenandoahPhaseTimings();
 356   ShenandoahStringDedup::initialize();
 357   ShenandoahCodeRoots::initialize();
 358 
 359   if (ShenandoahAllocationTrace) {
 360     _alloc_tracker = new ShenandoahAllocTracker();
 361   }
 362 
 363   if (ShenandoahPacing) {
 364     _pacer = new ShenandoahPacer(this);
 365     _pacer->setup_for_idle();
 366   } else {
 367     _pacer = NULL;
 368   }
 369 
 370   _traversal_gc = heuristics()->can_do_traversal_gc() ?
 371                   new ShenandoahTraversalGC(this, _num_regions) :
 372                   NULL;
 373 
 374   _control_thread = new ShenandoahControlThread();
 375 
 376   log_info(gc, init)("Initialize Shenandoah heap: " SIZE_FORMAT "%s initial, " SIZE_FORMAT "%s min, " SIZE_FORMAT "%s max",
 377                      byte_size_in_proper_unit(_initial_size),  proper_unit_for_byte_size(_initial_size),
 378                      byte_size_in_proper_unit(_minimum_size),  proper_unit_for_byte_size(_minimum_size),
 379                      byte_size_in_proper_unit(max_capacity()), proper_unit_for_byte_size(max_capacity())
 380   );
 381 
 382   log_info(gc, init)("Safepointing mechanism: %s",
 383                      SafepointMechanism::uses_thread_local_poll() ? "thread-local poll" :
 384                      (SafepointMechanism::uses_global_page_poll() ? "global-page poll" : "unknown"));
 385 
 386   return JNI_OK;
 387 }
 388 
 389 void ShenandoahHeap::initialize_heuristics() {
 390   if (ShenandoahGCHeuristics != NULL) {
 391     if (strcmp(ShenandoahGCHeuristics, "aggressive") == 0) {
 392       _heuristics = new ShenandoahAggressiveHeuristics();
 393     } else if (strcmp(ShenandoahGCHeuristics, "static") == 0) {
 394       _heuristics = new ShenandoahStaticHeuristics();
 395     } else if (strcmp(ShenandoahGCHeuristics, "adaptive") == 0) {
 396       _heuristics = new ShenandoahAdaptiveHeuristics();
 397     } else if (strcmp(ShenandoahGCHeuristics, "passive") == 0) {
 398       _heuristics = new ShenandoahPassiveHeuristics();
 399     } else if (strcmp(ShenandoahGCHeuristics, "compact") == 0) {
 400       _heuristics = new ShenandoahCompactHeuristics();
 401     } else if (strcmp(ShenandoahGCHeuristics, "traversal") == 0) {
 402       _heuristics = new ShenandoahTraversalHeuristics();
 403     } else {
 404       vm_exit_during_initialization("Unknown -XX:ShenandoahGCHeuristics option");
 405     }





 406 
 407     if (_heuristics->is_diagnostic() && !UnlockDiagnosticVMOptions) {
 408       vm_exit_during_initialization(
 409               err_msg("Heuristics \"%s\" is diagnostic, and must be enabled via -XX:+UnlockDiagnosticVMOptions.",
 410                       _heuristics->name()));
 411     }
 412     if (_heuristics->is_experimental() && !UnlockExperimentalVMOptions) {
 413       vm_exit_during_initialization(
 414               err_msg("Heuristics \"%s\" is experimental, and must be enabled via -XX:+UnlockExperimentalVMOptions.",
 415                       _heuristics->name()));
 416     }
 417     log_info(gc, init)("Shenandoah heuristics: %s",
 418                        _heuristics->name());
 419   } else {
 420       ShouldNotReachHere();
 421   }
 422 
 423 }
 424 
 425 #ifdef _MSC_VER
 426 #pragma warning( push )
 427 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
 428 #endif
 429 
 430 ShenandoahHeap::ShenandoahHeap(ShenandoahCollectorPolicy* policy) :
 431   CollectedHeap(),
 432   _initial_size(0),
 433   _used(0),
 434   _committed(0),
 435   _bytes_allocated_since_gc_start(0),
 436   _max_workers(MAX2(ConcGCThreads, ParallelGCThreads)),
 437   _workers(NULL),
 438   _safepoint_workers(NULL),
 439   _heap_region_special(false),
 440   _num_regions(0),
 441   _regions(NULL),
 442   _update_refs_iterator(this),


1687       op_final_traversal();
1688       op_cleanup();
1689       return;
1690 
1691     // The cases below form the Duff's-like device: it describes the actual GC cycle,
1692     // but enters it at different points, depending on which concurrent phase had
1693     // degenerated.
1694 
1695     case _degenerated_outside_cycle:
1696       // We have degenerated from outside the cycle, which means something is bad with
1697       // the heap, most probably heavy humongous fragmentation, or we are very low on free
1698       // space. It makes little sense to wait for Full GC to reclaim as much as it can, when
1699       // we can do the most aggressive degen cycle, which includes processing references and
1700       // class unloading, unless those features are explicitly disabled.
1701       //
1702       // Note that we can only do this for "outside-cycle" degens, otherwise we would risk
1703       // changing the cycle parameters mid-cycle during concurrent -> degenerated handover.
1704       set_process_references(heuristics()->can_process_references());
1705       set_unload_classes(heuristics()->can_unload_classes());
1706 
1707       if (heuristics()->can_do_traversal_gc()) {
1708         // Not possible to degenerate from here, upgrade to Full GC right away.
1709         cancel_gc(GCCause::_shenandoah_upgrade_to_full_gc);
1710         op_degenerated_fail();
1711         return;
1712       }
1713 
1714       op_reset();
1715 
1716       op_init_mark();
1717       if (cancelled_gc()) {
1718         op_degenerated_fail();
1719         return;
1720       }
1721 
1722     case _degenerated_mark:
1723       op_final_mark();
1724       if (cancelled_gc()) {
1725         op_degenerated_fail();
1726         return;
1727       }




  33 #include "gc/shared/plab.hpp"
  34 
  35 #include "gc/shenandoah/shenandoahAllocTracker.hpp"
  36 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
  37 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
  38 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
  39 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
  40 #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp"
  41 #include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
  42 #include "gc/shenandoah/shenandoahControlThread.hpp"
  43 #include "gc/shenandoah/shenandoahFreeSet.hpp"
  44 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
  45 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
  46 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
  47 #include "gc/shenandoah/shenandoahHeapRegionSet.hpp"
  48 #include "gc/shenandoah/shenandoahMarkCompact.hpp"
  49 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
  50 #include "gc/shenandoah/shenandoahMemoryPool.hpp"
  51 #include "gc/shenandoah/shenandoahMetrics.hpp"
  52 #include "gc/shenandoah/shenandoahMonitoringSupport.hpp"
  53 #include "gc/shenandoah/shenandoahNormalMode.hpp"
  54 #include "gc/shenandoah/shenandoahOopClosures.inline.hpp"
  55 #include "gc/shenandoah/shenandoahPacer.inline.hpp"
  56 #include "gc/shenandoah/shenandoahPassiveMode.hpp"
  57 #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp"
  58 #include "gc/shenandoah/shenandoahStringDedup.hpp"
  59 #include "gc/shenandoah/shenandoahTaskqueue.hpp"
  60 #include "gc/shenandoah/shenandoahTraversalMode.hpp"
  61 #include "gc/shenandoah/shenandoahUtils.hpp"
  62 #include "gc/shenandoah/shenandoahVerifier.hpp"
  63 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
  64 #include "gc/shenandoah/shenandoahVMOperations.hpp"
  65 #include "gc/shenandoah/shenandoahWorkGroup.hpp"
  66 #include "gc/shenandoah/shenandoahWorkerPolicy.hpp"






  67 #if INCLUDE_JFR
  68 #include "gc/shenandoah/shenandoahJfrSupport.hpp"
  69 #endif
  70 
  71 #include "memory/metaspace.hpp"
  72 #include "oops/compressedOops.inline.hpp"
  73 #include "runtime/globals.hpp"
  74 #include "runtime/interfaceSupport.inline.hpp"
  75 #include "runtime/safepointMechanism.hpp"
  76 #include "runtime/vmThread.hpp"
  77 #include "services/mallocTracker.hpp"
  78 
  79 #ifdef ASSERT
  80 template <class T>
  81 void ShenandoahAssertToSpaceClosure::do_oop_work(T* p) {
  82   T o = RawAccess<>::oop_load(p);
  83   if (! CompressedOops::is_null(o)) {
  84     oop obj = CompressedOops::decode_not_null(o);
  85     shenandoah_assert_not_forwarded(p, obj);
  86   }


 347   ShenandoahBarrierSet::satb_mark_queue_set().initialize(this,
 348                                                          20 /* G1SATBProcessCompletedThreshold */,
 349                                                          60 /* G1SATBBufferEnqueueingThresholdPercent */);
 350 
 351   _monitoring_support = new ShenandoahMonitoringSupport(this);
 352   _phase_timings = new ShenandoahPhaseTimings();
 353   ShenandoahStringDedup::initialize();
 354   ShenandoahCodeRoots::initialize();
 355 
 356   if (ShenandoahAllocationTrace) {
 357     _alloc_tracker = new ShenandoahAllocTracker();
 358   }
 359 
 360   if (ShenandoahPacing) {
 361     _pacer = new ShenandoahPacer(this);
 362     _pacer->setup_for_idle();
 363   } else {
 364     _pacer = NULL;
 365   }
 366 
 367   _traversal_gc = strcmp(ShenandoahGCMode, "traversal") == 0 ?
 368                   new ShenandoahTraversalGC(this, _num_regions) :
 369                   NULL;
 370 
 371   _control_thread = new ShenandoahControlThread();
 372 
 373   log_info(gc, init)("Initialize Shenandoah heap: " SIZE_FORMAT "%s initial, " SIZE_FORMAT "%s min, " SIZE_FORMAT "%s max",
 374                      byte_size_in_proper_unit(_initial_size),  proper_unit_for_byte_size(_initial_size),
 375                      byte_size_in_proper_unit(_minimum_size),  proper_unit_for_byte_size(_minimum_size),
 376                      byte_size_in_proper_unit(max_capacity()), proper_unit_for_byte_size(max_capacity())
 377   );
 378 
 379   log_info(gc, init)("Safepointing mechanism: %s",
 380                      SafepointMechanism::uses_thread_local_poll() ? "thread-local poll" :
 381                      (SafepointMechanism::uses_global_page_poll() ? "global-page poll" : "unknown"));
 382 
 383   return JNI_OK;
 384 }
 385 
 386 void ShenandoahHeap::initialize_heuristics() {
 387   if (ShenandoahGCMode != NULL) {
 388     if (strcmp(ShenandoahGCMode, "traversal") == 0) {
 389       _gc_mode = new ShenandoahTraversalMode();
 390     } else if (strcmp(ShenandoahGCMode, "normal") == 0) {
 391       _gc_mode = new ShenandoahNormalMode();
 392     } else if (strcmp(ShenandoahGCMode, "passive") == 0) {
 393       _gc_mode = new ShenandoahPassiveMode();






 394     } else {
 395       vm_exit_during_initialization("Unknown -XX:ShenandoahGCMode option");
 396     }
 397   } else {
 398     ShouldNotReachHere();
 399   }
 400   _gc_mode->initialize_flags();
 401   _heuristics = _gc_mode->initialize_heuristics();
 402 
 403   if (_heuristics->is_diagnostic() && !UnlockDiagnosticVMOptions) {
 404     vm_exit_during_initialization(
 405             err_msg("Heuristics \"%s\" is diagnostic, and must be enabled via -XX:+UnlockDiagnosticVMOptions.",
 406                     _heuristics->name()));
 407   }
 408   if (_heuristics->is_experimental() && !UnlockExperimentalVMOptions) {
 409     vm_exit_during_initialization(
 410             err_msg("Heuristics \"%s\" is experimental, and must be enabled via -XX:+UnlockExperimentalVMOptions.",
 411                     _heuristics->name()));
 412   }
 413   log_info(gc, init)("Shenandoah heuristics: %s",
 414                      _heuristics->name());




 415 }
 416 
 417 #ifdef _MSC_VER
 418 #pragma warning( push )
 419 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
 420 #endif
 421 
 422 ShenandoahHeap::ShenandoahHeap(ShenandoahCollectorPolicy* policy) :
 423   CollectedHeap(),
 424   _initial_size(0),
 425   _used(0),
 426   _committed(0),
 427   _bytes_allocated_since_gc_start(0),
 428   _max_workers(MAX2(ConcGCThreads, ParallelGCThreads)),
 429   _workers(NULL),
 430   _safepoint_workers(NULL),
 431   _heap_region_special(false),
 432   _num_regions(0),
 433   _regions(NULL),
 434   _update_refs_iterator(this),


1679       op_final_traversal();
1680       op_cleanup();
1681       return;
1682 
1683     // The cases below form the Duff's-like device: it describes the actual GC cycle,
1684     // but enters it at different points, depending on which concurrent phase had
1685     // degenerated.
1686 
1687     case _degenerated_outside_cycle:
1688       // We have degenerated from outside the cycle, which means something is bad with
1689       // the heap, most probably heavy humongous fragmentation, or we are very low on free
1690       // space. It makes little sense to wait for Full GC to reclaim as much as it can, when
1691       // we can do the most aggressive degen cycle, which includes processing references and
1692       // class unloading, unless those features are explicitly disabled.
1693       //
1694       // Note that we can only do this for "outside-cycle" degens, otherwise we would risk
1695       // changing the cycle parameters mid-cycle during concurrent -> degenerated handover.
1696       set_process_references(heuristics()->can_process_references());
1697       set_unload_classes(heuristics()->can_unload_classes());
1698 
1699       if (is_traversal_mode()) {
1700         // Not possible to degenerate from here, upgrade to Full GC right away.
1701         cancel_gc(GCCause::_shenandoah_upgrade_to_full_gc);
1702         op_degenerated_fail();
1703         return;
1704       }
1705 
1706       op_reset();
1707 
1708       op_init_mark();
1709       if (cancelled_gc()) {
1710         op_degenerated_fail();
1711         return;
1712       }
1713 
1714     case _degenerated_mark:
1715       op_final_mark();
1716       if (cancelled_gc()) {
1717         op_degenerated_fail();
1718         return;
1719       }


< prev index next >