< prev index next >

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

Print this page
@@ -28,34 +28,31 @@
  #include "gc/shenandoah/shenandoahConcurrentGC.hpp"
  #include "gc/shenandoah/shenandoahControlThread.hpp"
  #include "gc/shenandoah/shenandoahDegeneratedGC.hpp"
  #include "gc/shenandoah/shenandoahFreeSet.hpp"
  #include "gc/shenandoah/shenandoahFullGC.hpp"
+ #include "gc/shenandoah/shenandoahGeneration.hpp"
  #include "gc/shenandoah/shenandoahHeap.inline.hpp"
  #include "gc/shenandoah/shenandoahMonitoringSupport.hpp"
  #include "gc/shenandoah/shenandoahPacer.inline.hpp"
  #include "gc/shenandoah/shenandoahUtils.hpp"
  #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp"
+ #include "gc/shenandoah/mode/shenandoahMode.hpp"
+ #include "logging/log.hpp"
  #include "memory/metaspaceUtils.hpp"
  #include "memory/metaspaceStats.hpp"
- #include "memory/resourceArea.hpp"
- #include "runtime/atomic.hpp"
  
  ShenandoahControlThread::ShenandoahControlThread() :
-   ConcurrentGCThread(),
-   _alloc_failure_waiters_lock(Mutex::safepoint-2, "ShenandoahAllocFailureGC_lock", true),
-   _gc_waiters_lock(Mutex::safepoint-2, "ShenandoahRequestedGC_lock", true),
+   ShenandoahController(),
    _requested_gc_cause(GCCause::_no_cause_specified),
-   _degen_point(ShenandoahGC::_degenerated_outside_cycle),
-   _allocs_seen(0) {
+   _degen_point(ShenandoahGC::_degenerated_outside_cycle) {
    set_name("Shenandoah Control Thread");
-   reset_gc_id();
    create_and_start();
  }
  
  void ShenandoahControlThread::run_service() {
-   ShenandoahHeap* heap = ShenandoahHeap::heap();
+   ShenandoahHeap* const heap = ShenandoahHeap::heap();
  
    const GCMode default_mode = concurrent_normal;
    const GCCause::Cause default_cause = GCCause::_shenandoah_concurrent_gc;
    int sleep = ShenandoahControlIntervalMin;
  

@@ -75,11 +72,11 @@
      const bool alloc_failure_pending = _alloc_failure_gc.is_set();
      const bool is_gc_requested = _gc_requested.is_set();
      const GCCause::Cause requested_gc_cause = _requested_gc_cause;
  
      // This control loop iteration has seen this much allocation.
-     const size_t allocs_seen = Atomic::xchg(&_allocs_seen, (size_t)0, memory_order_relaxed);
+     const size_t allocs_seen = reset_allocs_seen();
  
      // Check if we have seen a new target for soft max heap size.
      const bool soft_max_changed = heap->check_soft_max_changed();
  
      // Choose which GC mode to run in. The block below should select a single mode.

@@ -104,11 +101,10 @@
        } else {
          heuristics->record_allocation_failure_gc();
          policy->record_alloc_failure_to_full();
          mode = stw_full;
        }
- 
      } else if (is_gc_requested) {
        cause = requested_gc_cause;
        log_info(gc)("Trigger: GC request (%s)", GCCause::to_string(cause));
        heuristics->record_requested_gc();
  

@@ -237,11 +233,11 @@
        // GC is over, we are at idle now
        if (ShenandoahPacing) {
          heap->pacer()->setup_for_idle();
        }
      } else {
-       // Allow allocators to know we have seen this much regions
+       // Report to pacer that we have seen this many words allocated
        if (ShenandoahPacing && (allocs_seen > 0)) {
          heap->pacer()->report_alloc(allocs_seen);
        }
      }
  

@@ -321,22 +317,24 @@
    //
    ShenandoahHeap* heap = ShenandoahHeap::heap();
    if (check_cancellation_or_degen(ShenandoahGC::_degenerated_outside_cycle)) return;
  
    GCIdMark gc_id_mark;
-   ShenandoahGCSession session(cause);
+   ShenandoahGCSession session(cause, heap->global_generation());
  
    TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
  
-   ShenandoahConcurrentGC gc;
+   ShenandoahConcurrentGC gc(heap->global_generation(), false);
    if (gc.collect(cause)) {
      // Cycle is complete
-     heap->heuristics()->record_success_concurrent();
-     heap->shenandoah_policy()->record_success_concurrent(gc.abbreviated());
+     heap->global_generation()->heuristics()->record_success_concurrent(gc.abbreviated());
+     heap->shenandoah_policy()->record_success_concurrent(false, gc.abbreviated());
+     heap->log_heap_status("At end of GC");
    } else {
      assert(heap->cancelled_gc(), "Must have been cancelled");
      check_cancellation_or_degen(gc.degen_point());
+     heap->log_heap_status("At end of cancelled GC");
    }
  }
  
  bool ShenandoahControlThread::check_cancellation_or_degen(ShenandoahGC::ShenandoahDegenPoint point) {
    ShenandoahHeap* heap = ShenandoahHeap::heap();

@@ -355,24 +353,25 @@
  void ShenandoahControlThread::stop_service() {
    // Nothing to do here.
  }
  
  void ShenandoahControlThread::service_stw_full_cycle(GCCause::Cause cause) {
+   ShenandoahHeap* const heap = ShenandoahHeap::heap();
    GCIdMark gc_id_mark;
-   ShenandoahGCSession session(cause);
+   ShenandoahGCSession session(cause, heap->global_generation());
  
    ShenandoahFullGC gc;
    gc.collect(cause);
  }
  
  void ShenandoahControlThread::service_stw_degenerated_cycle(GCCause::Cause cause, ShenandoahGC::ShenandoahDegenPoint point) {
    assert (point != ShenandoahGC::_degenerated_unset, "Degenerated point should be set");
- 
+   ShenandoahHeap* const heap = ShenandoahHeap::heap();
    GCIdMark gc_id_mark;
-   ShenandoahGCSession session(cause);
+   ShenandoahGCSession session(cause, heap->global_generation());
  
-   ShenandoahDegenGC gc(point);
+   ShenandoahDegenGC gc(point, heap->global_generation());
    gc.collect(cause);
  }
  
  void ShenandoahControlThread::request_gc(GCCause::Cause cause) {
    if (ShenandoahCollectorPolicy::should_handle_requested_gc(cause)) {

@@ -405,90 +404,10 @@
      }
      current_gc_id = get_gc_id();
    }
  }
  
- void ShenandoahControlThread::handle_alloc_failure(ShenandoahAllocRequest& req, bool block) {
-   ShenandoahHeap* heap = ShenandoahHeap::heap();
- 
-   assert(current()->is_Java_thread(), "expect Java thread here");
- 
-   if (try_set_alloc_failure_gc()) {
-     // Only report the first allocation failure
-     log_info(gc)("Failed to allocate %s, " SIZE_FORMAT "%s",
-                  req.type_string(),
-                  byte_size_in_proper_unit(req.size() * HeapWordSize), proper_unit_for_byte_size(req.size() * HeapWordSize));
- 
-     // Now that alloc failure GC is scheduled, we can abort everything else
-     heap->cancel_gc(GCCause::_allocation_failure);
-   }
- 
- 
-   if (block) {
-     MonitorLocker ml(&_alloc_failure_waiters_lock);
-     while (is_alloc_failure_gc()) {
-       ml.wait();
-     }
-   }
- }
- 
- void ShenandoahControlThread::handle_alloc_failure_evac(size_t words) {
-   ShenandoahHeap* heap = ShenandoahHeap::heap();
- 
-   if (try_set_alloc_failure_gc()) {
-     // Only report the first allocation failure
-     log_info(gc)("Failed to allocate " SIZE_FORMAT "%s for evacuation",
-                  byte_size_in_proper_unit(words * HeapWordSize), proper_unit_for_byte_size(words * HeapWordSize));
-   }
- 
-   // Forcefully report allocation failure
-   heap->cancel_gc(GCCause::_shenandoah_allocation_failure_evac);
- }
- 
- void ShenandoahControlThread::notify_alloc_failure_waiters() {
-   _alloc_failure_gc.unset();
-   MonitorLocker ml(&_alloc_failure_waiters_lock);
-   ml.notify_all();
- }
- 
- bool ShenandoahControlThread::try_set_alloc_failure_gc() {
-   return _alloc_failure_gc.try_set();
- }
- 
- bool ShenandoahControlThread::is_alloc_failure_gc() {
-   return _alloc_failure_gc.is_set();
- }
- 
  void ShenandoahControlThread::notify_gc_waiters() {
    _gc_requested.unset();
    MonitorLocker ml(&_gc_waiters_lock);
    ml.notify_all();
  }
- 
- void ShenandoahControlThread::pacing_notify_alloc(size_t words) {
-   assert(ShenandoahPacing, "should only call when pacing is enabled");
-   Atomic::add(&_allocs_seen, words, memory_order_relaxed);
- }
- 
- void ShenandoahControlThread::reset_gc_id() {
-   Atomic::store(&_gc_id, (size_t)0);
- }
- 
- void ShenandoahControlThread::update_gc_id() {
-   Atomic::inc(&_gc_id);
- }
- 
- size_t ShenandoahControlThread::get_gc_id() {
-   return Atomic::load(&_gc_id);
- }
- 
- void ShenandoahControlThread::start() {
-   create_and_start();
- }
- 
- void ShenandoahControlThread::prepare_for_graceful_shutdown() {
-   _graceful_shutdown.set();
- }
- 
- bool ShenandoahControlThread::in_graceful_shutdown() {
-   return _graceful_shutdown.is_set();
- }
< prev index next >