< prev index next >

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

Print this page
*** 248,20 ***
  
      // Update references freed up collection set, kick the cleanup to reclaim the space.
      entry_cleanup_complete();
    } else {
      _abbreviated = true;
!     if (!entry_final_roots()) {
!       assert(_degen_point != _degenerated_unset, "Need to know where to start degenerated cycle");
!       return false;
      }
  
      // In normal cycle, final-update-refs would verify at the end of the cycle.
      // In abbreviated cycle, we need to verify separately.
!     if (ShenandoahVerify) {
!       vmop_entry_final_verify();
-     }
    }
  
    // We defer generation resizing actions until after cset regions have been recycled.  We do this even following an
    // abbreviated cycle.
    if (heap->mode()->is_generational()) {
--- 248,22 ---
  
      // Update references freed up collection set, kick the cleanup to reclaim the space.
      entry_cleanup_complete();
    } else {
      _abbreviated = true;
! 
!     if (heap->mode()->is_generational()) {
!       if (!complete_abbreviated_cycle()) {
+         assert(_degen_point != _degenerated_unset, "Need to know where to start degenerated cycle");
+         return false;
+       }
      }
  
      // In normal cycle, final-update-refs would verify at the end of the cycle.
      // In abbreviated cycle, we need to verify separately.
!     // This is now also puts the barriers down at the end of the cycle. TODO: Refine.
!     vmop_entry_final_roots();
    }
  
    // We defer generation resizing actions until after cset regions have been recycled.  We do this even following an
    // abbreviated cycle.
    if (heap->mode()->is_generational()) {

*** 344,18 ***
    heap->try_inject_alloc_failure();
    VM_ShenandoahFinalUpdateRefs op(this);
    VMThread::execute(&op);
  }
  
! void ShenandoahConcurrentGC::vmop_entry_final_verify() {
    ShenandoahHeap* const heap = ShenandoahHeap::heap();
    TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
!   ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_verify_gross);
  
    // This phase does not use workers, no need for setup
    heap->try_inject_alloc_failure();
!   VM_ShenandoahFinalVerify op(this);
    VMThread::execute(&op);
  }
  
  void ShenandoahConcurrentGC::entry_init_mark() {
    const char* msg = init_mark_event_message();
--- 346,18 ---
    heap->try_inject_alloc_failure();
    VM_ShenandoahFinalUpdateRefs op(this);
    VMThread::execute(&op);
  }
  
! void ShenandoahConcurrentGC::vmop_entry_final_roots() {
    ShenandoahHeap* const heap = ShenandoahHeap::heap();
    TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
!   ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_roots_gross);
  
    // This phase does not use workers, no need for setup
    heap->try_inject_alloc_failure();
!   VM_ShenandoahFinalRoots op(this);
    VMThread::execute(&op);
  }
  
  void ShenandoahConcurrentGC::entry_init_mark() {
    const char* msg = init_mark_event_message();

*** 400,18 ***
                                "final reference update");
  
    op_final_update_refs();
  }
  
- void ShenandoahConcurrentGC::entry_final_verify() {
-   const char* msg = verify_final_event_message();
-   ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::final_verify);
-   EventMark em("%s", msg);
- 
-   op_verify_final();
- }
- 
  void ShenandoahConcurrentGC::entry_reset() {
    ShenandoahHeap* const heap = ShenandoahHeap::heap();
    heap->try_inject_alloc_failure();
  
    TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
--- 402,10 ---

*** 695,10 ***
--- 689,13 ---
  
    assert(_generation->is_bitmap_clear(), "need clear marking bitmap");
    assert(!_generation->is_mark_complete(), "should not be complete");
    assert(!heap->has_forwarded_objects(), "No forwarded objects on this path");
  
+   // First pause in cycle, check that barriers were not left enabled.
+   ShenandoahCodeRoots::check_barriers();
+ 
    if (heap->mode()->is_generational()) {
      if (_generation->is_global()) {
        heap->old_generation()->cancel_gc();
      }
  

*** 802,15 ***
        }
  
        heap->set_evacuation_in_progress(true);
        // From here on, we need to update references.
        heap->set_has_forwarded_objects(true);
- 
-       // Arm nmethods/stack for concurrent processing
-       ShenandoahCodeRoots::arm_nmethods();
-       ShenandoahStackWatermark::change_epoch_id();
- 
      } else {
        if (ShenandoahVerify) {
          ShenandoahTimingsTracker v(ShenandoahPhaseTimings::final_mark_verify);
          if (has_in_place_promotions(heap)) {
            heap->verifier()->verify_after_concmark_with_promotions(_generation);
--- 799,10 ---

*** 819,10 ***
--- 811,14 ---
          }
        }
      }
    }
  
+   // Arm nmethods/stack for concurrent processing
+   ShenandoahCodeRoots::arm_nmethods();
+   ShenandoahStackWatermark::change_epoch_id();
+ 
    {
      ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_mark_propagate_gc_state);
      heap->propagate_gc_state_to_all_threads();
    }
  }

*** 1039,11 ***
  
    void do_nmethod(nmethod* n) {
      ShenandoahNMethod* data = ShenandoahNMethod::gc_data(n);
      ShenandoahNMethodLocker locker(data->lock());
      data->oops_do(&_cl, /* fix_relocations = */ true);
!     ShenandoahNMethod::disarm_nmethod(n);
    }
  };
  
  class ShenandoahConcurrentRootsEvacUpdateTask : public WorkerTask {
  private:
--- 1035,11 ---
  
    void do_nmethod(nmethod* n) {
      ShenandoahNMethod* data = ShenandoahNMethod::gc_data(n);
      ShenandoahNMethodLocker locker(data->lock());
      data->oops_do(&_cl, /* fix_relocations = */ true);
!     ShenandoahNMethod::disarm_nmethod_unlocked(n);
    }
  };
  
  class ShenandoahConcurrentRootsEvacUpdateTask : public WorkerTask {
  private:

*** 1226,42 ***
    }
  
    heap->rebuild_free_set(true /*concurrent*/);
    _generation->heuristics()->start_idle_span();
  
    {
      ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_update_refs_propagate_gc_state);
      heap->propagate_gc_state_to_all_threads();
    }
  }
  
! bool ShenandoahConcurrentGC::entry_final_roots() {
    ShenandoahHeap* const heap = ShenandoahHeap::heap();
    TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
  
! 
!   const char* msg = conc_final_roots_event_message();
-   ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_final_roots);
    EventMark em("%s", msg);
    ShenandoahWorkerScope scope(heap->workers(),
!                               ShenandoahWorkerPolicy::calc_workers_for_conc_evac(),
                                msg);
  
!   if (heap->mode()->is_generational()) {
-     if (!complete_abbreviated_cycle()) {
-       return false;
-     }
-   }
- 
-   heap->concurrent_final_roots();
-   return true;
- }
- 
- void ShenandoahConcurrentGC::op_verify_final() {
-   assert(ShenandoahVerify, "Should have been checked before");
-   ShenandoahHeap* const heap = ShenandoahHeap::heap();
-   heap->verifier()->verify_after_gc(_generation);
  }
  
  void ShenandoahConcurrentGC::op_cleanup_complete() {
    ShenandoahWorkerScope scope(ShenandoahHeap::heap()->workers(),
                                ShenandoahWorkerPolicy::calc_workers_for_conc_cleanup(),
--- 1222,34 ---
    }
  
    heap->rebuild_free_set(true /*concurrent*/);
    _generation->heuristics()->start_idle_span();
  
+   {
+     // Final pause: update GC barriers to idle state.
+     ShenandoahCodeRoots::arm_nmethods();
+     ShenandoahStackWatermark::change_epoch_id();
+   }
+ 
    {
      ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_update_refs_propagate_gc_state);
      heap->propagate_gc_state_to_all_threads();
    }
  }
  
! void ShenandoahConcurrentGC::entry_final_roots() {
    ShenandoahHeap* const heap = ShenandoahHeap::heap();
    TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
  
!   const char* msg = final_roots_event_message();
!   ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::final_roots);
    EventMark em("%s", msg);
    ShenandoahWorkerScope scope(heap->workers(),
!                               ParallelGCThreads,
                                msg);
  
!   heap->op_final_roots();
  }
  
  void ShenandoahConcurrentGC::op_cleanup_complete() {
    ShenandoahWorkerScope scope(ShenandoahHeap::heap()->workers(),
                                ShenandoahWorkerPolicy::calc_workers_for_conc_cleanup(),

*** 1272,10 ***
--- 1260,16 ---
  void ShenandoahConcurrentGC::op_reset_after_collect() {
    ShenandoahWorkerScope scope(ShenandoahHeap::heap()->workers(),
                            ShenandoahWorkerPolicy::calc_workers_for_conc_reset(),
                            "reset after collection.");
  
+   // Final concurrent phase: complete disabling all barriers.
+   ShenandoahCodeRoots::disarm_nmethods();
+ 
+   // Check that barriers were not left enabled.
+   ShenandoahCodeRoots::check_barriers();
+ 
    ShenandoahHeap* const heap = ShenandoahHeap::heap();
    if (heap->mode()->is_generational()) {
      // If we are in the midst of an old gc bootstrap or an old marking, we want to leave the mark bit map of
      // the young generation intact. In particular, reference processing in the old generation may potentially
      // need the reachability of a young generation referent of a Reference object in the old generation.

*** 1342,23 ***
    } else {
      SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent reset after collect", "");
    }
  }
  
! const char* ShenandoahConcurrentGC::verify_final_event_message() const {
-   if (ShenandoahHeap::heap()->unload_classes()) {
-     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Pause Verify Final", " (unload classes)");
-   } else {
-     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Pause Verify Final", "");
-   }
- }
- 
- const char* ShenandoahConcurrentGC::conc_final_roots_event_message() const {
    if (ShenandoahHeap::heap()->unload_classes()) {
!     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent Final Roots", " (unload classes)");
    } else {
!     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent Final Roots", "");
    }
  }
  
  const char* ShenandoahConcurrentGC::conc_weak_refs_event_message() const {
    if (ShenandoahHeap::heap()->unload_classes()) {
--- 1336,15 ---
    } else {
      SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent reset after collect", "");
    }
  }
  
! const char* ShenandoahConcurrentGC::final_roots_event_message() const {
    if (ShenandoahHeap::heap()->unload_classes()) {
!     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Pause Final Roots", " (unload classes)");
    } else {
!     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Pause Final Roots", "");
    }
  }
  
  const char* ShenandoahConcurrentGC::conc_weak_refs_event_message() const {
    if (ShenandoahHeap::heap()->unload_classes()) {
< prev index next >