< prev index next >

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

Print this page

  35 #include "gc/shenandoah/shenandoahForwarding.inline.hpp"
  36 #include "gc/shenandoah/shenandoahFreeSet.hpp"
  37 #include "gc/shenandoah/shenandoahGeneration.hpp"
  38 #include "gc/shenandoah/shenandoahGenerationalHeap.hpp"
  39 #include "gc/shenandoah/shenandoahLock.hpp"
  40 #include "gc/shenandoah/shenandoahMark.inline.hpp"
  41 #include "gc/shenandoah/shenandoahMonitoringSupport.hpp"
  42 #include "gc/shenandoah/shenandoahOldGeneration.hpp"
  43 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
  44 #include "gc/shenandoah/shenandoahReferenceProcessor.hpp"
  45 #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp"
  46 #include "gc/shenandoah/shenandoahStackWatermark.hpp"
  47 #include "gc/shenandoah/shenandoahUtils.hpp"
  48 #include "gc/shenandoah/shenandoahVerifier.hpp"
  49 #include "gc/shenandoah/shenandoahVMOperations.hpp"
  50 #include "gc/shenandoah/shenandoahWorkerPolicy.hpp"
  51 #include "gc/shenandoah/shenandoahWorkGroup.hpp"
  52 #include "gc/shenandoah/shenandoahYoungGeneration.hpp"
  53 #include "memory/allocation.hpp"
  54 #include "prims/jvmtiTagMap.hpp"

  55 #include "runtime/vmThread.hpp"
  56 #include "utilities/events.hpp"
  57 
  58 // Breakpoint support
  59 class ShenandoahBreakpointGCScope : public StackObj {
  60 private:
  61   const GCCause::Cause _cause;
  62 public:
  63   ShenandoahBreakpointGCScope(GCCause::Cause cause) : _cause(cause) {
  64     if (cause == GCCause::_wb_breakpoint) {
  65       ShenandoahBreakpoint::start_gc();
  66       ShenandoahBreakpoint::at_before_gc();
  67     }
  68   }
  69 
  70   ~ShenandoahBreakpointGCScope() {
  71     if (_cause == GCCause::_wb_breakpoint) {
  72       ShenandoahBreakpoint::at_after_gc();
  73     }
  74   }

 199 
 200   // Perform concurrent class unloading before any regions get recycled. Class unloading may
 201   // need to inspect unmarked objects in trashed regions.
 202   if (heap->unload_classes()) {
 203     entry_class_unloading();
 204   }
 205 
 206   // Final mark might have reclaimed some immediate garbage, kick cleanup to reclaim
 207   // the space. This would be the last action if there is nothing to evacuate.  Note that
 208   // we will not age young-gen objects in the case that we skip evacuation.
 209   entry_cleanup_early();
 210 
 211   // Processing strong roots
 212   // This may be skipped if there is nothing to update/evacuate.
 213   // If so, strong_root_in_progress would be unset.
 214   if (heap->is_concurrent_strong_root_in_progress()) {
 215     entry_strong_roots();
 216   }
 217 
 218   // Roots processing is complete, put the weak roots flag down.
 219   entry_final_roots();
 220 
 221   // Continue the cycle with evacuation and optional update-refs.
 222   // This may be skipped if there is nothing to evacuate.
 223   // If so, evac_in_progress would be unset by collection set preparation code.
 224   if (heap->is_evacuation_in_progress()) {
 225     // Concurrently evacuate
 226     entry_evacuate();
 227     if (check_cancellation_and_abort(ShenandoahDegenPoint::_degenerated_evac)) {
 228       return false;
 229     }
 230 
 231     // Perform update-refs phase.
 232     entry_concurrent_update_refs_prepare(heap);
 233 
 234     if (ShenandoahHeap::heap()->mode()->is_generational()) {
 235       entry_update_card_table();
 236     }
 237 
 238     if (ShenandoahVerify) {
 239       vmop_entry_init_update_refs();

 348   TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
 349   ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::init_update_refs_gross);
 350 
 351   heap->try_inject_alloc_failure();
 352   heap->try_inject_pin();
 353   VM_ShenandoahInitUpdateRefs op(this);
 354   VMThread::execute(&op);
 355 }
 356 
 357 void ShenandoahConcurrentGC::vmop_entry_final_update_refs() {
 358   ShenandoahHeap* const heap = ShenandoahHeap::heap();
 359   TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
 360   ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_update_refs_gross);
 361 
 362   heap->try_inject_alloc_failure();
 363   heap->try_inject_pin();
 364   VM_ShenandoahFinalUpdateRefs op(this);
 365   VMThread::execute(&op);
 366 }
 367 











 368 void ShenandoahConcurrentGC::vmop_entry_final_verify() {
 369   ShenandoahHeap* const heap = ShenandoahHeap::heap();
 370   TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
 371   ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_verify_gross);
 372 
 373   // This phase does not use workers, no need for setup
 374   heap->try_inject_alloc_failure();
 375   heap->try_inject_pin();
 376   VM_ShenandoahFinalVerify op(this);
 377   VMThread::execute(&op);
 378 }
 379 
 380 void ShenandoahConcurrentGC::entry_init_mark() {
 381   ShenandoahHeap* const heap = ShenandoahHeap::heap();
 382   assert(!heap->has_forwarded_objects(), "Should not have forwarded objects here");
 383 
 384   SHENANDOAH_EVENT_MESSAGE(msg, _generation->type(), "Pause Init Mark", "");
 385   ShenandoahPauseSubphase gc_phase(msg, ShenandoahPhaseTimings::init_mark);
 386   EventMark em("%s", msg);
 387 

 760     // Update region state for both young and old regions
 761     ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_region_states);
 762     ShenandoahInitMarkUpdateRegionStateClosure cl;
 763     heap->parallel_heap_region_iterate(&cl);
 764     heap->old_generation()->ref_processor()->reset_thread_locals();
 765   } else {
 766     // Update region state for only young regions
 767     ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_region_states);
 768     ShenandoahInitMarkUpdateRegionStateClosure cl;
 769     _generation->parallel_heap_region_iterate(&cl);
 770   }
 771 
 772   // Weak reference processing
 773   ShenandoahReferenceProcessor* rp = _generation->ref_processor();
 774   rp->reset_thread_locals();
 775 
 776   // Make above changes visible to worker threads
 777   OrderAccess::fence();
 778 
 779   // Arm nmethods/stack for concurrent processing
 780   ShenandoahCodeRoots::arm_nmethods();
 781   ShenandoahStackWatermark::change_epoch_id();
 782 
 783   {
 784     ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::init_propagate_gc_state);
 785     heap->propagate_gc_state_to_all_threads();
 786   }
 787 }
 788 
 789 void ShenandoahConcurrentGC::op_mark_roots() {
 790   _mark.mark_concurrent_roots();
 791 }
 792 
 793 void ShenandoahConcurrentGC::op_mark() {
 794   _mark.concurrent_mark();
 795 }
 796 
 797 void ShenandoahConcurrentGC::op_final_mark() {
 798   ShenandoahHeap* const heap = ShenandoahHeap::heap();
 799   assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Should be at safepoint");
 800   assert(!heap->has_forwarded_objects(), "No forwarded objects on this path");
 801 

 817 
 818     // Has to be done after cset selection
 819     heap->prepare_concurrent_roots();
 820 
 821     if (!heap->collection_set()->is_empty()) {
 822       LogTarget(Debug, gc, cset) lt;
 823       if (lt.is_enabled()) {
 824         ResourceMark rm;
 825         LogStream ls(lt);
 826         heap->collection_set()->print_on(&ls);
 827       }
 828 
 829       if (ShenandoahVerify) {
 830         ShenandoahTimingsTracker v(ShenandoahPhaseTimings::final_mark_verify);
 831         heap->verifier()->verify_before_evacuation(_generation);
 832       }
 833 
 834       heap->set_evacuation_in_progress(true);
 835       // From here on, we need to update references.
 836       heap->set_has_forwarded_objects(true);
 837 
 838       // Arm nmethods/stack for concurrent processing
 839       ShenandoahCodeRoots::arm_nmethods();
 840       ShenandoahStackWatermark::change_epoch_id();
 841 
 842     } else {
 843       if (ShenandoahVerify) {
 844         ShenandoahTimingsTracker v(ShenandoahPhaseTimings::final_mark_verify);
 845         if (has_in_place_promotions(heap)) {
 846           heap->verifier()->verify_after_concmark_with_promotions(_generation);
 847         } else {
 848           heap->verifier()->verify_after_concmark(_generation);
 849         }
 850       }
 851     }
 852   }
 853 



 854   {
 855     ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_mark_propagate_gc_state);
 856     heap->propagate_gc_state_to_all_threads();
 857   }
 858 }
 859 
 860 bool ShenandoahConcurrentGC::has_in_place_promotions(ShenandoahHeap* heap) {
 861   return heap->mode()->is_generational() && heap->old_generation()->has_in_place_promotions();
 862 }
 863 
 864 class ShenandoahConcurrentEvacThreadClosure : public ThreadClosure {
 865 private:
 866   OopClosure* const _oops;
 867 public:
 868   explicit ShenandoahConcurrentEvacThreadClosure(OopClosure* oops) : _oops(oops) {}
 869 
 870   void do_thread(Thread* thread) override {
 871     JavaThread* const jt = JavaThread::cast(thread);
 872     StackWatermarkSet::finish_processing(jt, _oops, StackWatermarkKind::gc);
 873   }

1053 }
1054 
1055 void ShenandoahConcurrentGC::op_class_unloading() {
1056   ShenandoahHeap* const heap = ShenandoahHeap::heap();
1057   assert (heap->is_concurrent_weak_root_in_progress() &&
1058           heap->unload_classes(),
1059           "Checked by caller");
1060   heap->do_class_unloading();
1061 }
1062 
1063 class ShenandoahEvacUpdateCodeCacheClosure : public NMethodClosure {
1064 private:
1065   ShenandoahEvacuateUpdateMetadataClosure   _cl;
1066 
1067 public:
1068   ShenandoahEvacUpdateCodeCacheClosure() : _cl() {}
1069 
1070   void do_nmethod(nmethod* n) {
1071     ShenandoahNMethod* data = ShenandoahNMethod::gc_data(n);
1072     ShenandoahNMethodLocker locker(data->lock());
1073     data->oops_do(&_cl, /* fix_relocations = */ true);
1074     ShenandoahNMethod::disarm_nmethod(n);
1075   }
1076 };
1077 
1078 class ShenandoahConcurrentRootsEvacUpdateTask : public WorkerTask {
1079 private:
1080   ShenandoahPhaseTimings::Phase                 _phase;
1081   ShenandoahVMRoots<true /*concurrent*/>        _vm_roots;
1082   ShenandoahClassLoaderDataRoots<true /*concurrent*/>
1083                                                 _cld_roots;
1084   ShenandoahConcurrentNMethodIterator           _nmethod_itr;
1085 
1086 public:
1087   ShenandoahConcurrentRootsEvacUpdateTask(ShenandoahPhaseTimings::Phase phase) :
1088     WorkerTask("Shenandoah Evacuate/Update Concurrent Strong Roots"),
1089     _phase(phase),
1090     _vm_roots(phase),
1091     _cld_roots(phase, ShenandoahHeap::heap()->workers()->active_workers(), false /*heap iteration*/),
1092     _nmethod_itr(ShenandoahCodeRoots::table()) {}
1093 
1094   void work(uint worker_id) {

1235 
1236   // If we are running in generational mode, this will also age active regions that
1237   // haven't been used for allocation.
1238   heap->update_heap_region_states(true /*concurrent*/);
1239 
1240   heap->set_update_refs_in_progress(false);
1241   heap->set_has_forwarded_objects(false);
1242 
1243   if (ShenandoahVerify) {
1244     ShenandoahTimingsTracker v(ShenandoahPhaseTimings::final_update_refs_verify);
1245     heap->verifier()->verify_after_update_refs(_generation);
1246   }
1247 
1248   if (VerifyAfterGC) {
1249     Universe::verify();
1250   }
1251 
1252   heap->rebuild_free_set(true /*concurrent*/);
1253   _generation->heuristics()->start_idle_span();
1254 



1255   {
1256     ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_update_refs_propagate_gc_state);
1257     heap->propagate_gc_state_to_all_threads();
1258   }
1259 }
1260 
1261 void ShenandoahConcurrentGC::entry_final_roots() {
1262   ShenandoahHeap* const heap = ShenandoahHeap::heap();
1263   TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
1264   SHENANDOAH_EVENT_MESSAGE(msg, _generation->type(), "Concurrent final roots", "");
1265   ShenandoahConcurrentSubphase gc_phase(msg, ShenandoahPhaseTimings::conc_final_roots);
1266   EventMark em("%s", msg);
1267 
1268   heap->concurrent_final_roots();
1269 }
1270 
1271 void ShenandoahConcurrentGC::op_verify_final() {
1272   assert(ShenandoahVerify, "Should have been checked before");
1273   ShenandoahHeap* const heap = ShenandoahHeap::heap();
1274   heap->verifier()->verify_after_gc(_generation);
1275 }
1276 
1277 void ShenandoahConcurrentGC::op_cleanup_complete() {
1278   ShenandoahWorkerScope scope(ShenandoahHeap::heap()->workers(),
1279                               ShenandoahWorkerPolicy::calc_workers_for_conc_cleanup(),
1280                               "cleanup complete.");
1281   ShenandoahHeap::heap()->recycle_trash();
1282 }
1283 
1284 void ShenandoahConcurrentGC::op_reset_after_collect() {
1285   ShenandoahWorkerScope scope(ShenandoahHeap::heap()->workers(),
1286                           ShenandoahWorkerPolicy::calc_workers_for_conc_reset(),
1287                           "reset after collection.");
1288 

  35 #include "gc/shenandoah/shenandoahForwarding.inline.hpp"
  36 #include "gc/shenandoah/shenandoahFreeSet.hpp"
  37 #include "gc/shenandoah/shenandoahGeneration.hpp"
  38 #include "gc/shenandoah/shenandoahGenerationalHeap.hpp"
  39 #include "gc/shenandoah/shenandoahLock.hpp"
  40 #include "gc/shenandoah/shenandoahMark.inline.hpp"
  41 #include "gc/shenandoah/shenandoahMonitoringSupport.hpp"
  42 #include "gc/shenandoah/shenandoahOldGeneration.hpp"
  43 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
  44 #include "gc/shenandoah/shenandoahReferenceProcessor.hpp"
  45 #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp"
  46 #include "gc/shenandoah/shenandoahStackWatermark.hpp"
  47 #include "gc/shenandoah/shenandoahUtils.hpp"
  48 #include "gc/shenandoah/shenandoahVerifier.hpp"
  49 #include "gc/shenandoah/shenandoahVMOperations.hpp"
  50 #include "gc/shenandoah/shenandoahWorkerPolicy.hpp"
  51 #include "gc/shenandoah/shenandoahWorkGroup.hpp"
  52 #include "gc/shenandoah/shenandoahYoungGeneration.hpp"
  53 #include "memory/allocation.hpp"
  54 #include "prims/jvmtiTagMap.hpp"
  55 #include "runtime/icache.hpp"
  56 #include "runtime/vmThread.hpp"
  57 #include "utilities/events.hpp"
  58 
  59 // Breakpoint support
  60 class ShenandoahBreakpointGCScope : public StackObj {
  61 private:
  62   const GCCause::Cause _cause;
  63 public:
  64   ShenandoahBreakpointGCScope(GCCause::Cause cause) : _cause(cause) {
  65     if (cause == GCCause::_wb_breakpoint) {
  66       ShenandoahBreakpoint::start_gc();
  67       ShenandoahBreakpoint::at_before_gc();
  68     }
  69   }
  70 
  71   ~ShenandoahBreakpointGCScope() {
  72     if (_cause == GCCause::_wb_breakpoint) {
  73       ShenandoahBreakpoint::at_after_gc();
  74     }
  75   }

 200 
 201   // Perform concurrent class unloading before any regions get recycled. Class unloading may
 202   // need to inspect unmarked objects in trashed regions.
 203   if (heap->unload_classes()) {
 204     entry_class_unloading();
 205   }
 206 
 207   // Final mark might have reclaimed some immediate garbage, kick cleanup to reclaim
 208   // the space. This would be the last action if there is nothing to evacuate.  Note that
 209   // we will not age young-gen objects in the case that we skip evacuation.
 210   entry_cleanup_early();
 211 
 212   // Processing strong roots
 213   // This may be skipped if there is nothing to update/evacuate.
 214   // If so, strong_root_in_progress would be unset.
 215   if (heap->is_concurrent_strong_root_in_progress()) {
 216     entry_strong_roots();
 217   }
 218 
 219   // Roots processing is complete, put the weak roots flag down.
 220   vmop_entry_final_roots();
 221 
 222   // Continue the cycle with evacuation and optional update-refs.
 223   // This may be skipped if there is nothing to evacuate.
 224   // If so, evac_in_progress would be unset by collection set preparation code.
 225   if (heap->is_evacuation_in_progress()) {
 226     // Concurrently evacuate
 227     entry_evacuate();
 228     if (check_cancellation_and_abort(ShenandoahDegenPoint::_degenerated_evac)) {
 229       return false;
 230     }
 231 
 232     // Perform update-refs phase.
 233     entry_concurrent_update_refs_prepare(heap);
 234 
 235     if (ShenandoahHeap::heap()->mode()->is_generational()) {
 236       entry_update_card_table();
 237     }
 238 
 239     if (ShenandoahVerify) {
 240       vmop_entry_init_update_refs();

 349   TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
 350   ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::init_update_refs_gross);
 351 
 352   heap->try_inject_alloc_failure();
 353   heap->try_inject_pin();
 354   VM_ShenandoahInitUpdateRefs op(this);
 355   VMThread::execute(&op);
 356 }
 357 
 358 void ShenandoahConcurrentGC::vmop_entry_final_update_refs() {
 359   ShenandoahHeap* const heap = ShenandoahHeap::heap();
 360   TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
 361   ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_update_refs_gross);
 362 
 363   heap->try_inject_alloc_failure();
 364   heap->try_inject_pin();
 365   VM_ShenandoahFinalUpdateRefs op(this);
 366   VMThread::execute(&op);
 367 }
 368 
 369 void ShenandoahConcurrentGC::vmop_entry_final_roots() {
 370   ShenandoahHeap* const heap = ShenandoahHeap::heap();
 371   TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
 372   ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_roots_gross);
 373 
 374   // This phase does not use workers, no need for setup
 375   heap->try_inject_pin();
 376   VM_ShenandoahFinalRoots op(this);
 377   VMThread::execute(&op);
 378 }
 379 
 380 void ShenandoahConcurrentGC::vmop_entry_final_verify() {
 381   ShenandoahHeap* const heap = ShenandoahHeap::heap();
 382   TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
 383   ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_verify_gross);
 384 
 385   // This phase does not use workers, no need for setup
 386   heap->try_inject_alloc_failure();
 387   heap->try_inject_pin();
 388   VM_ShenandoahFinalVerify op(this);
 389   VMThread::execute(&op);
 390 }
 391 
 392 void ShenandoahConcurrentGC::entry_init_mark() {
 393   ShenandoahHeap* const heap = ShenandoahHeap::heap();
 394   assert(!heap->has_forwarded_objects(), "Should not have forwarded objects here");
 395 
 396   SHENANDOAH_EVENT_MESSAGE(msg, _generation->type(), "Pause Init Mark", "");
 397   ShenandoahPauseSubphase gc_phase(msg, ShenandoahPhaseTimings::init_mark);
 398   EventMark em("%s", msg);
 399 

 772     // Update region state for both young and old regions
 773     ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_region_states);
 774     ShenandoahInitMarkUpdateRegionStateClosure cl;
 775     heap->parallel_heap_region_iterate(&cl);
 776     heap->old_generation()->ref_processor()->reset_thread_locals();
 777   } else {
 778     // Update region state for only young regions
 779     ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_region_states);
 780     ShenandoahInitMarkUpdateRegionStateClosure cl;
 781     _generation->parallel_heap_region_iterate(&cl);
 782   }
 783 
 784   // Weak reference processing
 785   ShenandoahReferenceProcessor* rp = _generation->ref_processor();
 786   rp->reset_thread_locals();
 787 
 788   // Make above changes visible to worker threads
 789   OrderAccess::fence();
 790 
 791   // Arm nmethods/stack for concurrent processing
 792   CodeCache::arm_all_nmethods();

 793 
 794   {
 795     ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::init_propagate_gc_state);
 796     heap->propagate_gc_state_to_all_threads();
 797   }
 798 }
 799 
 800 void ShenandoahConcurrentGC::op_mark_roots() {
 801   _mark.mark_concurrent_roots();
 802 }
 803 
 804 void ShenandoahConcurrentGC::op_mark() {
 805   _mark.concurrent_mark();
 806 }
 807 
 808 void ShenandoahConcurrentGC::op_final_mark() {
 809   ShenandoahHeap* const heap = ShenandoahHeap::heap();
 810   assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Should be at safepoint");
 811   assert(!heap->has_forwarded_objects(), "No forwarded objects on this path");
 812 

 828 
 829     // Has to be done after cset selection
 830     heap->prepare_concurrent_roots();
 831 
 832     if (!heap->collection_set()->is_empty()) {
 833       LogTarget(Debug, gc, cset) lt;
 834       if (lt.is_enabled()) {
 835         ResourceMark rm;
 836         LogStream ls(lt);
 837         heap->collection_set()->print_on(&ls);
 838       }
 839 
 840       if (ShenandoahVerify) {
 841         ShenandoahTimingsTracker v(ShenandoahPhaseTimings::final_mark_verify);
 842         heap->verifier()->verify_before_evacuation(_generation);
 843       }
 844 
 845       heap->set_evacuation_in_progress(true);
 846       // From here on, we need to update references.
 847       heap->set_has_forwarded_objects(true);





 848     } else {
 849       if (ShenandoahVerify) {
 850         ShenandoahTimingsTracker v(ShenandoahPhaseTimings::final_mark_verify);
 851         if (has_in_place_promotions(heap)) {
 852           heap->verifier()->verify_after_concmark_with_promotions(_generation);
 853         } else {
 854           heap->verifier()->verify_after_concmark(_generation);
 855         }
 856       }
 857     }
 858   }
 859 
 860   // Arm nmethods/stack for concurrent processing
 861   CodeCache::arm_all_nmethods();
 862 
 863   {
 864     ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_mark_propagate_gc_state);
 865     heap->propagate_gc_state_to_all_threads();
 866   }
 867 }
 868 
 869 bool ShenandoahConcurrentGC::has_in_place_promotions(ShenandoahHeap* heap) {
 870   return heap->mode()->is_generational() && heap->old_generation()->has_in_place_promotions();
 871 }
 872 
 873 class ShenandoahConcurrentEvacThreadClosure : public ThreadClosure {
 874 private:
 875   OopClosure* const _oops;
 876 public:
 877   explicit ShenandoahConcurrentEvacThreadClosure(OopClosure* oops) : _oops(oops) {}
 878 
 879   void do_thread(Thread* thread) override {
 880     JavaThread* const jt = JavaThread::cast(thread);
 881     StackWatermarkSet::finish_processing(jt, _oops, StackWatermarkKind::gc);
 882   }

1062 }
1063 
1064 void ShenandoahConcurrentGC::op_class_unloading() {
1065   ShenandoahHeap* const heap = ShenandoahHeap::heap();
1066   assert (heap->is_concurrent_weak_root_in_progress() &&
1067           heap->unload_classes(),
1068           "Checked by caller");
1069   heap->do_class_unloading();
1070 }
1071 
1072 class ShenandoahEvacUpdateCodeCacheClosure : public NMethodClosure {
1073 private:
1074   ShenandoahEvacuateUpdateMetadataClosure   _cl;
1075 
1076 public:
1077   ShenandoahEvacUpdateCodeCacheClosure() : _cl() {}
1078 
1079   void do_nmethod(nmethod* n) {
1080     ShenandoahNMethod* data = ShenandoahNMethod::gc_data(n);
1081     ShenandoahNMethodLocker locker(data->lock());
1082     ICacheInvalidationContext icic;
1083     data->oops_do(&_cl, /* fix_relocations = */ true, &icic);
1084   }
1085 };
1086 
1087 class ShenandoahConcurrentRootsEvacUpdateTask : public WorkerTask {
1088 private:
1089   ShenandoahPhaseTimings::Phase                 _phase;
1090   ShenandoahVMRoots<true /*concurrent*/>        _vm_roots;
1091   ShenandoahClassLoaderDataRoots<true /*concurrent*/>
1092                                                 _cld_roots;
1093   ShenandoahConcurrentNMethodIterator           _nmethod_itr;
1094 
1095 public:
1096   ShenandoahConcurrentRootsEvacUpdateTask(ShenandoahPhaseTimings::Phase phase) :
1097     WorkerTask("Shenandoah Evacuate/Update Concurrent Strong Roots"),
1098     _phase(phase),
1099     _vm_roots(phase),
1100     _cld_roots(phase, ShenandoahHeap::heap()->workers()->active_workers(), false /*heap iteration*/),
1101     _nmethod_itr(ShenandoahCodeRoots::table()) {}
1102 
1103   void work(uint worker_id) {

1244 
1245   // If we are running in generational mode, this will also age active regions that
1246   // haven't been used for allocation.
1247   heap->update_heap_region_states(true /*concurrent*/);
1248 
1249   heap->set_update_refs_in_progress(false);
1250   heap->set_has_forwarded_objects(false);
1251 
1252   if (ShenandoahVerify) {
1253     ShenandoahTimingsTracker v(ShenandoahPhaseTimings::final_update_refs_verify);
1254     heap->verifier()->verify_after_update_refs(_generation);
1255   }
1256 
1257   if (VerifyAfterGC) {
1258     Universe::verify();
1259   }
1260 
1261   heap->rebuild_free_set(true /*concurrent*/);
1262   _generation->heuristics()->start_idle_span();
1263 
1264   // Final pause: update GC barriers to idle state.
1265   CodeCache::arm_all_nmethods();
1266 
1267   {
1268     ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_update_refs_propagate_gc_state);
1269     heap->propagate_gc_state_to_all_threads();
1270   }
1271 }
1272 
1273 void ShenandoahConcurrentGC::entry_final_roots() {
1274   ShenandoahHeap* const heap = ShenandoahHeap::heap();
1275   SHENANDOAH_EVENT_MESSAGE(msg, _generation->type(), "Pause Final Roots", "");
1276   ShenandoahPauseSubphase gc_phase(msg, ShenandoahPhaseTimings::final_roots);

1277   EventMark em("%s", msg);
1278 
1279   heap->op_final_roots();
1280 }
1281 
1282 void ShenandoahConcurrentGC::op_verify_final() {
1283   assert(ShenandoahVerify, "Should have been checked before");
1284   ShenandoahHeap* const heap = ShenandoahHeap::heap();
1285   heap->verifier()->verify_after_gc(_generation);
1286 }
1287 
1288 void ShenandoahConcurrentGC::op_cleanup_complete() {
1289   ShenandoahWorkerScope scope(ShenandoahHeap::heap()->workers(),
1290                               ShenandoahWorkerPolicy::calc_workers_for_conc_cleanup(),
1291                               "cleanup complete.");
1292   ShenandoahHeap::heap()->recycle_trash();
1293 }
1294 
1295 void ShenandoahConcurrentGC::op_reset_after_collect() {
1296   ShenandoahWorkerScope scope(ShenandoahHeap::heap()->workers(),
1297                           ShenandoahWorkerPolicy::calc_workers_for_conc_reset(),
1298                           "reset after collection.");
1299 
< prev index next >