< prev index next >

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

Print this page

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

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











 366 void ShenandoahConcurrentGC::vmop_entry_final_verify() {
 367   ShenandoahHeap* const heap = ShenandoahHeap::heap();
 368   TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
 369   ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_verify_gross);
 370 
 371   // This phase does not use workers, no need for setup
 372   heap->try_inject_alloc_failure();
 373   heap->try_inject_pin();
 374   VM_ShenandoahFinalVerify op(this);
 375   VMThread::execute(&op);
 376 }
 377 
 378 void ShenandoahConcurrentGC::entry_init_mark() {
 379   const char* msg = init_mark_event_message();
 380   ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::init_mark);
 381   EventMark em("%s", msg);
 382 
 383   ShenandoahWorkerScope scope(ShenandoahHeap::heap()->workers(),
 384                               ShenandoahWorkerPolicy::calc_workers_for_init_marking(),
 385                               "init marking");

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

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



 843   {
 844     ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_mark_propagate_gc_state);
 845     heap->propagate_gc_state_to_all_threads();
 846   }
 847 }
 848 
 849 bool ShenandoahConcurrentGC::has_in_place_promotions(ShenandoahHeap* heap) {
 850   return heap->mode()->is_generational() && heap->old_generation()->has_in_place_promotions();
 851 }
 852 
 853 class ShenandoahConcurrentEvacThreadClosure : public ThreadClosure {
 854 private:
 855   OopClosure* const _oops;
 856 public:
 857   explicit ShenandoahConcurrentEvacThreadClosure(OopClosure* oops) : _oops(oops) {}
 858 
 859   void do_thread(Thread* thread) override {
 860     JavaThread* const jt = JavaThread::cast(thread);
 861     StackWatermarkSet::finish_processing(jt, _oops, StackWatermarkKind::gc);
 862   }

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

1224 
1225   // If we are running in generational mode, this will also age active regions that
1226   // haven't been used for allocation.
1227   heap->update_heap_region_states(true /*concurrent*/);
1228 
1229   heap->set_update_refs_in_progress(false);
1230   heap->set_has_forwarded_objects(false);
1231 
1232   if (ShenandoahVerify) {
1233     ShenandoahTimingsTracker v(ShenandoahPhaseTimings::final_update_refs_verify);
1234     heap->verifier()->verify_after_update_refs(_generation);
1235   }
1236 
1237   if (VerifyAfterGC) {
1238     Universe::verify();
1239   }
1240 
1241   heap->rebuild_free_set(true /*concurrent*/);
1242   _generation->heuristics()->start_idle_span();
1243 



1244   {
1245     ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_update_refs_propagate_gc_state);
1246     heap->propagate_gc_state_to_all_threads();
1247   }
1248 }
1249 
1250 void ShenandoahConcurrentGC::entry_final_roots() {
1251   ShenandoahHeap* const heap = ShenandoahHeap::heap();
1252   TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
1253   const char* msg = conc_final_roots_event_message();
1254   ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_final_roots);
1255   EventMark em("%s", msg);
1256 
1257   heap->concurrent_final_roots();
1258 }
1259 
1260 void ShenandoahConcurrentGC::op_verify_final() {
1261   assert(ShenandoahVerify, "Should have been checked before");
1262   ShenandoahHeap* const heap = ShenandoahHeap::heap();
1263   heap->verifier()->verify_after_gc(_generation);
1264 }
1265 
1266 void ShenandoahConcurrentGC::op_cleanup_complete() {
1267   ShenandoahWorkerScope scope(ShenandoahHeap::heap()->workers(),
1268                               ShenandoahWorkerPolicy::calc_workers_for_conc_cleanup(),
1269                               "cleanup complete.");
1270   ShenandoahHeap::heap()->recycle_trash();
1271 }
1272 
1273 void ShenandoahConcurrentGC::op_reset_after_collect() {
1274   ShenandoahWorkerScope scope(ShenandoahHeap::heap()->workers(),
1275                           ShenandoahWorkerPolicy::calc_workers_for_conc_reset(),
1276                           "reset after collection.");
1277 

1336     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent reset", "");
1337   }
1338 }
1339 
1340 const char* ShenandoahConcurrentGC::conc_reset_after_collect_event_message() const {
1341   if (ShenandoahHeap::heap()->unload_classes()) {
1342     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent reset after collect", " (unload classes)");
1343   } else {
1344     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent reset after collect", "");
1345   }
1346 }
1347 
1348 const char* ShenandoahConcurrentGC::verify_final_event_message() const {
1349   if (ShenandoahHeap::heap()->unload_classes()) {
1350     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Pause Verify Final", " (unload classes)");
1351   } else {
1352     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Pause Verify Final", "");
1353   }
1354 }
1355 
1356 const char* ShenandoahConcurrentGC::conc_final_roots_event_message() const {
1357   if (ShenandoahHeap::heap()->unload_classes()) {
1358     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent Final Roots", " (unload classes)");
1359   } else {
1360     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent Final Roots", "");
1361   }
1362 }
1363 
1364 const char* ShenandoahConcurrentGC::conc_weak_refs_event_message() const {
1365   if (ShenandoahHeap::heap()->unload_classes()) {
1366     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent weak references", " (unload classes)");
1367   } else {
1368     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent weak references", "");
1369   }
1370 }
1371 
1372 const char* ShenandoahConcurrentGC::conc_weak_roots_event_message() const {
1373   if (ShenandoahHeap::heap()->unload_classes()) {
1374     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent weak roots", " (unload classes)");
1375   } else {
1376     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent weak roots", "");
1377   }
1378 }
1379 
1380 const char* ShenandoahConcurrentGC::conc_cleanup_event_message() const {

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

 346   TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
 347   ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::init_update_refs_gross);
 348 
 349   heap->try_inject_alloc_failure();
 350   heap->try_inject_pin();
 351   VM_ShenandoahInitUpdateRefs op(this);
 352   VMThread::execute(&op);
 353 }
 354 
 355 void ShenandoahConcurrentGC::vmop_entry_final_update_refs() {
 356   ShenandoahHeap* const heap = ShenandoahHeap::heap();
 357   TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
 358   ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_update_refs_gross);
 359 
 360   heap->try_inject_alloc_failure();
 361   heap->try_inject_pin();
 362   VM_ShenandoahFinalUpdateRefs op(this);
 363   VMThread::execute(&op);
 364 }
 365 
 366 void ShenandoahConcurrentGC::vmop_entry_final_roots() {
 367   ShenandoahHeap* const heap = ShenandoahHeap::heap();
 368   TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
 369   ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_roots_gross);
 370 
 371   // This phase does not use workers, no need for setup
 372   heap->try_inject_alloc_failure();
 373   VM_ShenandoahFinalRoots op(this);
 374   VMThread::execute(&op);
 375 }
 376 
 377 void ShenandoahConcurrentGC::vmop_entry_final_verify() {
 378   ShenandoahHeap* const heap = ShenandoahHeap::heap();
 379   TraceCollectorStats tcs(heap->monitoring_support()->stw_collection_counters());
 380   ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_verify_gross);
 381 
 382   // This phase does not use workers, no need for setup
 383   heap->try_inject_alloc_failure();
 384   heap->try_inject_pin();
 385   VM_ShenandoahFinalVerify op(this);
 386   VMThread::execute(&op);
 387 }
 388 
 389 void ShenandoahConcurrentGC::entry_init_mark() {
 390   const char* msg = init_mark_event_message();
 391   ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::init_mark);
 392   EventMark em("%s", msg);
 393 
 394   ShenandoahWorkerScope scope(ShenandoahHeap::heap()->workers(),
 395                               ShenandoahWorkerPolicy::calc_workers_for_init_marking(),
 396                               "init marking");

 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 
 782   {
 783     ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::init_propagate_gc_state);
 784     heap->propagate_gc_state_to_all_threads();
 785   }
 786 }
 787 
 788 void ShenandoahConcurrentGC::op_mark_roots() {
 789   _mark.mark_concurrent_roots();
 790 }
 791 
 792 void ShenandoahConcurrentGC::op_mark() {
 793   _mark.concurrent_mark();
 794 }
 795 
 796 void ShenandoahConcurrentGC::op_final_mark() {
 797   ShenandoahHeap* const heap = ShenandoahHeap::heap();
 798   assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Should be at safepoint");
 799   assert(!heap->has_forwarded_objects(), "No forwarded objects on this path");
 800 

 816 
 817     // Has to be done after cset selection
 818     heap->prepare_concurrent_roots();
 819 
 820     if (!heap->collection_set()->is_empty()) {
 821       LogTarget(Debug, gc, cset) lt;
 822       if (lt.is_enabled()) {
 823         ResourceMark rm;
 824         LogStream ls(lt);
 825         heap->collection_set()->print_on(&ls);
 826       }
 827 
 828       if (ShenandoahVerify) {
 829         ShenandoahTimingsTracker v(ShenandoahPhaseTimings::final_mark_verify);
 830         heap->verifier()->verify_before_evacuation(_generation);
 831       }
 832 
 833       heap->set_evacuation_in_progress(true);
 834       // From here on, we need to update references.
 835       heap->set_has_forwarded_objects(true);





 836     } else {
 837       if (ShenandoahVerify) {
 838         ShenandoahTimingsTracker v(ShenandoahPhaseTimings::final_mark_verify);
 839         if (has_in_place_promotions(heap)) {
 840           heap->verifier()->verify_after_concmark_with_promotions(_generation);
 841         } else {
 842           heap->verifier()->verify_after_concmark(_generation);
 843         }
 844       }
 845     }
 846   }
 847 
 848   // Arm nmethods/stack for concurrent processing
 849   ShenandoahCodeRoots::arm_nmethods();
 850 
 851   {
 852     ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_mark_propagate_gc_state);
 853     heap->propagate_gc_state_to_all_threads();
 854   }
 855 }
 856 
 857 bool ShenandoahConcurrentGC::has_in_place_promotions(ShenandoahHeap* heap) {
 858   return heap->mode()->is_generational() && heap->old_generation()->has_in_place_promotions();
 859 }
 860 
 861 class ShenandoahConcurrentEvacThreadClosure : public ThreadClosure {
 862 private:
 863   OopClosure* const _oops;
 864 public:
 865   explicit ShenandoahConcurrentEvacThreadClosure(OopClosure* oops) : _oops(oops) {}
 866 
 867   void do_thread(Thread* thread) override {
 868     JavaThread* const jt = JavaThread::cast(thread);
 869     StackWatermarkSet::finish_processing(jt, _oops, StackWatermarkKind::gc);
 870   }

1051 
1052 void ShenandoahConcurrentGC::op_class_unloading() {
1053   ShenandoahHeap* const heap = ShenandoahHeap::heap();
1054   assert (heap->is_concurrent_weak_root_in_progress() &&
1055           heap->unload_classes(),
1056           "Checked by caller");
1057   heap->do_class_unloading();
1058 }
1059 
1060 class ShenandoahEvacUpdateCodeCacheClosure : public NMethodClosure {
1061 private:
1062   ShenandoahEvacuateUpdateMetadataClosure   _cl;
1063 
1064 public:
1065   ShenandoahEvacUpdateCodeCacheClosure() : _cl() {}
1066 
1067   void do_nmethod(nmethod* n) {
1068     ShenandoahNMethod* data = ShenandoahNMethod::gc_data(n);
1069     ShenandoahNMethodLocker locker(data->lock());
1070     data->oops_do(&_cl, /* fix_relocations = */ true);

1071   }
1072 };
1073 
1074 class ShenandoahConcurrentRootsEvacUpdateTask : public WorkerTask {
1075 private:
1076   ShenandoahPhaseTimings::Phase                 _phase;
1077   ShenandoahVMRoots<true /*concurrent*/>        _vm_roots;
1078   ShenandoahClassLoaderDataRoots<true /*concurrent*/>
1079                                                 _cld_roots;
1080   ShenandoahConcurrentNMethodIterator           _nmethod_itr;
1081 
1082 public:
1083   ShenandoahConcurrentRootsEvacUpdateTask(ShenandoahPhaseTimings::Phase phase) :
1084     WorkerTask("Shenandoah Evacuate/Update Concurrent Strong Roots"),
1085     _phase(phase),
1086     _vm_roots(phase),
1087     _cld_roots(phase, ShenandoahHeap::heap()->workers()->active_workers(), false /*heap iteration*/),
1088     _nmethod_itr(ShenandoahCodeRoots::table()) {}
1089 
1090   void work(uint worker_id) {

1231 
1232   // If we are running in generational mode, this will also age active regions that
1233   // haven't been used for allocation.
1234   heap->update_heap_region_states(true /*concurrent*/);
1235 
1236   heap->set_update_refs_in_progress(false);
1237   heap->set_has_forwarded_objects(false);
1238 
1239   if (ShenandoahVerify) {
1240     ShenandoahTimingsTracker v(ShenandoahPhaseTimings::final_update_refs_verify);
1241     heap->verifier()->verify_after_update_refs(_generation);
1242   }
1243 
1244   if (VerifyAfterGC) {
1245     Universe::verify();
1246   }
1247 
1248   heap->rebuild_free_set(true /*concurrent*/);
1249   _generation->heuristics()->start_idle_span();
1250 
1251   // Final pause: update GC barriers to idle state.
1252   ShenandoahCodeRoots::arm_nmethods();
1253 
1254   {
1255     ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::final_update_refs_propagate_gc_state);
1256     heap->propagate_gc_state_to_all_threads();
1257   }
1258 }
1259 
1260 void ShenandoahConcurrentGC::entry_final_roots() {
1261   const char* msg = final_roots_event_message();
1262   ShenandoahPausePhase gc_phase(msg, ShenandoahPhaseTimings::final_roots);


1263   EventMark em("%s", msg);
1264 
1265   ShenandoahHeap::heap()->op_final_roots();
1266 }
1267 
1268 void ShenandoahConcurrentGC::op_verify_final() {
1269   assert(ShenandoahVerify, "Should have been checked before");
1270   ShenandoahHeap* const heap = ShenandoahHeap::heap();
1271   heap->verifier()->verify_after_gc(_generation);
1272 }
1273 
1274 void ShenandoahConcurrentGC::op_cleanup_complete() {
1275   ShenandoahWorkerScope scope(ShenandoahHeap::heap()->workers(),
1276                               ShenandoahWorkerPolicy::calc_workers_for_conc_cleanup(),
1277                               "cleanup complete.");
1278   ShenandoahHeap::heap()->recycle_trash();
1279 }
1280 
1281 void ShenandoahConcurrentGC::op_reset_after_collect() {
1282   ShenandoahWorkerScope scope(ShenandoahHeap::heap()->workers(),
1283                           ShenandoahWorkerPolicy::calc_workers_for_conc_reset(),
1284                           "reset after collection.");
1285 

1344     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent reset", "");
1345   }
1346 }
1347 
1348 const char* ShenandoahConcurrentGC::conc_reset_after_collect_event_message() const {
1349   if (ShenandoahHeap::heap()->unload_classes()) {
1350     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent reset after collect", " (unload classes)");
1351   } else {
1352     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent reset after collect", "");
1353   }
1354 }
1355 
1356 const char* ShenandoahConcurrentGC::verify_final_event_message() const {
1357   if (ShenandoahHeap::heap()->unload_classes()) {
1358     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Pause Verify Final", " (unload classes)");
1359   } else {
1360     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Pause Verify Final", "");
1361   }
1362 }
1363 
1364 const char* ShenandoahConcurrentGC::final_roots_event_message() const {
1365   if (ShenandoahHeap::heap()->unload_classes()) {
1366     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Pause Final Roots", " (unload classes)");
1367   } else {
1368     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Pause Final Roots", "");
1369   }
1370 }
1371 
1372 const char* ShenandoahConcurrentGC::conc_weak_refs_event_message() const {
1373   if (ShenandoahHeap::heap()->unload_classes()) {
1374     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent weak references", " (unload classes)");
1375   } else {
1376     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent weak references", "");
1377   }
1378 }
1379 
1380 const char* ShenandoahConcurrentGC::conc_weak_roots_event_message() const {
1381   if (ShenandoahHeap::heap()->unload_classes()) {
1382     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent weak roots", " (unload classes)");
1383   } else {
1384     SHENANDOAH_RETURN_EVENT_MESSAGE(_generation->type(), "Concurrent weak roots", "");
1385   }
1386 }
1387 
1388 const char* ShenandoahConcurrentGC::conc_cleanup_event_message() const {
< prev index next >