src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 55076 785a12e0f89b
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
    26 #include "classfile/classLoaderData.hpp"
    26 #include "classfile/classLoaderData.hpp"
    27 #include "classfile/classLoaderDataGraph.hpp"
    27 #include "classfile/classLoaderDataGraph.hpp"
    28 #include "gc/shared/referenceProcessor.hpp"
    28 #include "gc/shared/referenceProcessor.hpp"
    29 #include "gc/shared/referenceProcessorPhaseTimes.hpp"
    29 #include "gc/shared/referenceProcessorPhaseTimes.hpp"
    30 #include "gc/shared/workgroup.hpp"
    30 #include "gc/shared/workgroup.hpp"
    31 #include "gc/shared/weakProcessor.inline.hpp"
       
    32 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
    31 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
    33 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
    32 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
    34 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
    33 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
    35 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
    34 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
    36 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
    35 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
   365   prepare_regions();
   364   prepare_regions();
   366 
   365 
   367   // Rebuild free set
   366   // Rebuild free set
   368   free_set->rebuild();
   367   free_set->rebuild();
   369 
   368 
   370   log_info(gc, ergo)("Collectable Garbage: " SIZE_FORMAT "M, " SIZE_FORMAT "M CSet, " SIZE_FORMAT " CSet regions",
   369   log_info(gc, ergo)("Collectable Garbage: " SIZE_FORMAT "%s, " SIZE_FORMAT "%s CSet, " SIZE_FORMAT " CSet regions",
   371                      collection_set->garbage() / M, collection_set->live_data() / M, collection_set->count());
   370                      byte_size_in_proper_unit(collection_set->garbage()),   proper_unit_for_byte_size(collection_set->garbage()),
       
   371                      byte_size_in_proper_unit(collection_set->live_data()), proper_unit_for_byte_size(collection_set->live_data()),
       
   372                      collection_set->count());
   372 }
   373 }
   373 
   374 
   374 void ShenandoahTraversalGC::init_traversal_collection() {
   375 void ShenandoahTraversalGC::init_traversal_collection() {
   375   assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "STW traversal GC");
   376   assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "STW traversal GC");
   376 
   377 
   387     ShenandoahHeapLocker lock(_heap->lock());
   388     ShenandoahHeapLocker lock(_heap->lock());
   388     prepare();
   389     prepare();
   389   }
   390   }
   390 
   391 
   391   _heap->set_concurrent_traversal_in_progress(true);
   392   _heap->set_concurrent_traversal_in_progress(true);
       
   393   _heap->set_has_forwarded_objects(true);
   392 
   394 
   393   bool process_refs = _heap->process_references();
   395   bool process_refs = _heap->process_references();
   394   if (process_refs) {
   396   if (process_refs) {
   395     ReferenceProcessor* rp = _heap->ref_processor();
   397     ReferenceProcessor* rp = _heap->ref_processor();
   396     rp->enable_discovery(true /*verify_no_refs*/);
   398     rp->enable_discovery(true /*verify_no_refs*/);
   400   {
   402   {
   401     ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::init_traversal_gc_work);
   403     ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::init_traversal_gc_work);
   402     assert(_task_queues->is_empty(), "queues must be empty before traversal GC");
   404     assert(_task_queues->is_empty(), "queues must be empty before traversal GC");
   403     TASKQUEUE_STATS_ONLY(_task_queues->reset_taskqueue_stats());
   405     TASKQUEUE_STATS_ONLY(_task_queues->reset_taskqueue_stats());
   404 
   406 
   405 #if defined(COMPILER2) || INCLUDE_JVMCI
   407 #if COMPILER2_OR_JVMCI
   406     DerivedPointerTable::clear();
   408     DerivedPointerTable::clear();
   407 #endif
   409 #endif
   408 
   410 
   409     {
   411     {
   410       uint nworkers = _heap->workers()->active_workers();
   412       uint nworkers = _heap->workers()->active_workers();
   412       ShenandoahCSetRootScanner rp(nworkers, ShenandoahPhaseTimings::init_traversal_gc_work);
   414       ShenandoahCSetRootScanner rp(nworkers, ShenandoahPhaseTimings::init_traversal_gc_work);
   413       ShenandoahInitTraversalCollectionTask traversal_task(&rp);
   415       ShenandoahInitTraversalCollectionTask traversal_task(&rp);
   414       _heap->workers()->run_task(&traversal_task);
   416       _heap->workers()->run_task(&traversal_task);
   415     }
   417     }
   416 
   418 
   417 #if defined(COMPILER2) || INCLUDE_JVMCI
   419 #if COMPILER2_OR_JVMCI
   418     DerivedPointerTable::update_pointers();
   420     DerivedPointerTable::update_pointers();
   419 #endif
   421 #endif
   420   }
   422   }
   421 
   423 
   422   if (ShenandoahPacing) {
   424   if (ShenandoahPacing) {
   569 
   571 
   570 void ShenandoahTraversalGC::final_traversal_collection() {
   572 void ShenandoahTraversalGC::final_traversal_collection() {
   571   _heap->make_parsable(true);
   573   _heap->make_parsable(true);
   572 
   574 
   573   if (!_heap->cancelled_gc()) {
   575   if (!_heap->cancelled_gc()) {
   574 #if defined(COMPILER2) || INCLUDE_JVMCI
   576 #if COMPILER2_OR_JVMCI
   575     DerivedPointerTable::clear();
   577     DerivedPointerTable::clear();
   576 #endif
   578 #endif
   577     ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::final_traversal_gc_work);
   579     ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::final_traversal_gc_work);
   578     uint nworkers = _heap->workers()->active_workers();
   580     uint nworkers = _heap->workers()->active_workers();
   579     task_queues()->reserve(nworkers);
   581     task_queues()->reserve(nworkers);
   583     ShenandoahTerminationTracker term(ShenandoahPhaseTimings::final_traversal_gc_termination);
   585     ShenandoahTerminationTracker term(ShenandoahPhaseTimings::final_traversal_gc_termination);
   584 
   586 
   585     ShenandoahTaskTerminator terminator(nworkers, task_queues());
   587     ShenandoahTaskTerminator terminator(nworkers, task_queues());
   586     ShenandoahFinalTraversalCollectionTask task(&rp, &terminator);
   588     ShenandoahFinalTraversalCollectionTask task(&rp, &terminator);
   587     _heap->workers()->run_task(&task);
   589     _heap->workers()->run_task(&task);
   588 #if defined(COMPILER2) || INCLUDE_JVMCI
   590 #if COMPILER2_OR_JVMCI
   589     DerivedPointerTable::update_pointers();
   591     DerivedPointerTable::update_pointers();
   590 #endif
   592 #endif
   591   }
   593   }
   592 
   594 
   593   if (!_heap->cancelled_gc() && _heap->process_references()) {
   595   if (!_heap->cancelled_gc() && _heap->process_references()) {
   594     weak_refs_work();
   596     weak_refs_work();
   595   }
       
   596 
       
   597   if (!_heap->cancelled_gc()) {
       
   598     fixup_roots();
       
   599     if (_heap->unload_classes()) {
       
   600       _heap->unload_classes_and_cleanup_tables(false);
       
   601     }
       
   602   }
   597   }
   603 
   598 
   604   if (!_heap->cancelled_gc()) {
   599   if (!_heap->cancelled_gc()) {
   605     assert(_task_queues->is_empty(), "queues must be empty after traversal GC");
   600     assert(_task_queues->is_empty(), "queues must be empty after traversal GC");
   606     TASKQUEUE_STATS_ONLY(_task_queues->print_taskqueue_stats());
   601     TASKQUEUE_STATS_ONLY(_task_queues->print_taskqueue_stats());
   607     TASKQUEUE_STATS_ONLY(_task_queues->reset_taskqueue_stats());
   602     TASKQUEUE_STATS_ONLY(_task_queues->reset_taskqueue_stats());
   608 
   603 
   609     // No more marking expected
   604     // No more marking expected
       
   605     _heap->set_concurrent_traversal_in_progress(false);
   610     _heap->mark_complete_marking_context();
   606     _heap->mark_complete_marking_context();
       
   607 
       
   608     fixup_roots();
       
   609     _heap->parallel_cleaning(false);
       
   610 
       
   611     _heap->set_has_forwarded_objects(false);
   611 
   612 
   612     // Resize metaspace
   613     // Resize metaspace
   613     MetaspaceGC::compute_new_size();
   614     MetaspaceGC::compute_new_size();
   614 
   615 
   615     // Still good? We can now trash the cset, and make final verification
   616     // Still good? We can now trash the cset, and make final verification
   652       _heap->free_set()->rebuild();
   653       _heap->free_set()->rebuild();
   653       reset();
   654       reset();
   654     }
   655     }
   655 
   656 
   656     assert(_task_queues->is_empty(), "queues must be empty after traversal GC");
   657     assert(_task_queues->is_empty(), "queues must be empty after traversal GC");
   657     _heap->set_concurrent_traversal_in_progress(false);
       
   658     assert(!_heap->cancelled_gc(), "must not be cancelled when getting out here");
   658     assert(!_heap->cancelled_gc(), "must not be cancelled when getting out here");
   659 
   659 
   660     if (ShenandoahVerify) {
   660     if (ShenandoahVerify) {
   661       _heap->verifier()->verify_after_traversal();
   661       _heap->verifier()->verify_after_traversal();
   662     }
   662     }
   673   inline void do_oop_work(T* p) {
   673   inline void do_oop_work(T* p) {
   674     T o = RawAccess<>::oop_load(p);
   674     T o = RawAccess<>::oop_load(p);
   675     if (!CompressedOops::is_null(o)) {
   675     if (!CompressedOops::is_null(o)) {
   676       oop obj = CompressedOops::decode_not_null(o);
   676       oop obj = CompressedOops::decode_not_null(o);
   677       oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
   677       oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
   678       if (!oopDesc::equals_raw(obj, forw)) {
   678       if (obj != forw) {
   679         RawAccess<IS_NOT_NULL>::oop_store(p, forw);
   679         RawAccess<IS_NOT_NULL>::oop_store(p, forw);
   680       }
   680       }
   681     }
   681     }
   682   }
   682   }
   683 
   683 
   704     _rp->roots_do<ShenandoahForwardedIsAliveClosure, ShenandoahTraversalFixRootsClosure>(worker_id, &is_alive, &cl);
   704     _rp->roots_do<ShenandoahForwardedIsAliveClosure, ShenandoahTraversalFixRootsClosure>(worker_id, &is_alive, &cl);
   705   }
   705   }
   706 };
   706 };
   707 
   707 
   708 void ShenandoahTraversalGC::fixup_roots() {
   708 void ShenandoahTraversalGC::fixup_roots() {
   709 #if defined(COMPILER2) || INCLUDE_JVMCI
   709 #if COMPILER2_OR_JVMCI
   710   DerivedPointerTable::clear();
   710   DerivedPointerTable::clear();
   711 #endif
   711 #endif
   712   ShenandoahRootUpdater rp(_heap->workers()->active_workers(), ShenandoahPhaseTimings::final_traversal_update_roots, true /* update code cache */);
   712   ShenandoahRootUpdater rp(_heap->workers()->active_workers(), ShenandoahPhaseTimings::final_traversal_update_roots);
   713   ShenandoahTraversalFixRootsTask update_roots_task(&rp);
   713   ShenandoahTraversalFixRootsTask update_roots_task(&rp);
   714   _heap->workers()->run_task(&update_roots_task);
   714   _heap->workers()->run_task(&update_roots_task);
   715 #if defined(COMPILER2) || INCLUDE_JVMCI
   715 #if COMPILER2_OR_JVMCI
   716   DerivedPointerTable::update_pointers();
   716   DerivedPointerTable::update_pointers();
   717 #endif
   717 #endif
   718 }
   718 }
   719 
   719 
   720 void ShenandoahTraversalGC::reset() {
   720 void ShenandoahTraversalGC::reset() {