< prev index next >

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

Print this page




  13  *
  14  * You should have received a copy of the GNU General Public License version
  15  * 2 along with this work; if not, write to the Free Software Foundation,
  16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  17  *
  18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  19  * or visit www.oracle.com if you need additional information or have any
  20  * questions.
  21  *
  22  */
  23 
  24 #include "precompiled.hpp"
  25 
  26 #include "classfile/classLoaderData.hpp"
  27 #include "classfile/classLoaderDataGraph.hpp"
  28 #include "gc/shared/referenceProcessor.hpp"
  29 #include "gc/shared/referenceProcessorPhaseTimes.hpp"
  30 #include "gc/shared/workgroup.hpp"
  31 #include "gc/shared/weakProcessor.inline.hpp"
  32 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
  33 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
  34 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
  35 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
  36 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
  37 #include "gc/shenandoah/shenandoahFreeSet.hpp"
  38 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
  39 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
  40 #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp"
  41 #include "gc/shenandoah/shenandoahHeuristics.hpp"
  42 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
  43 #include "gc/shenandoah/shenandoahOopClosures.inline.hpp"
  44 #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp"
  45 #include "gc/shenandoah/shenandoahStringDedup.hpp"
  46 #include "gc/shenandoah/shenandoahTaskqueue.inline.hpp"
  47 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
  48 #include "gc/shenandoah/shenandoahTraversalGC.hpp"
  49 #include "gc/shenandoah/shenandoahUtils.hpp"
  50 #include "gc/shenandoah/shenandoahVerifier.hpp"
  51 
  52 #include "memory/iterator.hpp"
  53 #include "memory/metaspace.hpp"


 180     bool unload_classes = _heap->unload_classes();
 181     ReferenceProcessor* rp = NULL;
 182     if (process_refs) {
 183       rp = _heap->ref_processor();
 184     }
 185 
 186     // Step 1: Process ordinary GC roots.
 187     {
 188       ShenandoahTraversalClosure roots_cl(q, rp);
 189       ShenandoahMarkCLDClosure cld_cl(&roots_cl);
 190       MarkingCodeBlobClosure code_cl(&roots_cl, CodeBlobToOopClosure::FixRelocations);
 191       if (unload_classes) {
 192         _rp->process_strong_roots(&roots_cl, &cld_cl, NULL, NULL, worker_id);
 193         // Need to pre-evac code roots here. Otherwise we might see from-space constants.
 194         ShenandoahWorkerTimings* worker_times = _heap->phase_timings()->worker_times();
 195         ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CodeCacheRoots, worker_id);
 196         _cset_coderoots->possibly_parallel_blobs_do(&code_cl);
 197       } else {
 198         _rp->process_all_roots(&roots_cl, &cld_cl, &code_cl, NULL, worker_id);
 199       }
 200       if (ShenandoahStringDedup::is_enabled()) {
 201         AlwaysTrueClosure is_alive;
 202         ShenandoahStringDedup::parallel_oops_do(&is_alive, &roots_cl, worker_id);
 203       }
 204     }
 205   }
 206 };
 207 
 208 class ShenandoahConcurrentTraversalCollectionTask : public AbstractGangTask {
 209 private:
 210   ShenandoahTaskTerminator* _terminator;
 211   ShenandoahHeap* _heap;
 212 public:
 213   ShenandoahConcurrentTraversalCollectionTask(ShenandoahTaskTerminator* terminator) :
 214     AbstractGangTask("Shenandoah Concurrent Traversal Collection"),
 215     _terminator(terminator),
 216     _heap(ShenandoahHeap::heap()) {}
 217 
 218   void work(uint worker_id) {
 219     ShenandoahConcurrentWorkerSession worker_session(worker_id);
 220     ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers);
 221     ShenandoahEvacOOMScope oom_evac_scope;
 222     ShenandoahTraversalGC* traversal_gc = _heap->traversal_gc();
 223 


 583     uint nworkers = _heap->workers()->active_workers();
 584     task_queues()->reserve(nworkers);
 585 
 586     // Finish traversal
 587     ShenandoahRootProcessor rp(_heap, nworkers, ShenandoahPhaseTimings::final_traversal_gc_work);
 588     ShenandoahTerminationTracker term(ShenandoahPhaseTimings::final_traversal_gc_termination);
 589 
 590     ShenandoahTaskTerminator terminator(nworkers, task_queues());
 591     ShenandoahFinalTraversalCollectionTask task(&rp, &terminator);
 592     _heap->workers()->run_task(&task);
 593 #if defined(COMPILER2) || INCLUDE_JVMCI
 594     DerivedPointerTable::update_pointers();
 595 #endif
 596   }
 597 
 598   if (!_heap->cancelled_gc() && _heap->process_references()) {
 599     weak_refs_work();
 600   }
 601 
 602   if (!_heap->cancelled_gc()) {
 603     fixup_roots();
 604     if (_heap->unload_classes()) {
 605       _heap->unload_classes_and_cleanup_tables(false);
 606     }


 607   }
 608 
 609   if (!_heap->cancelled_gc()) {
 610     assert(_task_queues->is_empty(), "queues must be empty after traversal GC");
 611     TASKQUEUE_STATS_ONLY(_task_queues->print_taskqueue_stats());
 612     TASKQUEUE_STATS_ONLY(_task_queues->reset_taskqueue_stats());
 613 
 614     // No more marking expected
 615     _heap->mark_complete_marking_context();
 616 
 617     // Resize metaspace
 618     MetaspaceGC::compute_new_size();
 619 
 620     // Still good? We can now trash the cset, and make final verification
 621     {
 622       ShenandoahGCPhase phase_cleanup(ShenandoahPhaseTimings::traversal_gc_cleanup);
 623       ShenandoahHeapLocker lock(_heap->lock());
 624 
 625       // Trash everything
 626       // Clear immediate garbage regions.


 756   ShenandoahObjToScanQueue* _queue;
 757   Thread* _thread;
 758   ShenandoahTraversalGC* _traversal_gc;
 759   ShenandoahMarkingContext* const _mark_context;
 760 
 761   template <class T>
 762   inline void do_oop_work(T* p) {
 763     _traversal_gc->process_oop<T, false /* string dedup */, false /* degen */>(p, _thread, _queue, _mark_context);
 764   }
 765 
 766 public:
 767   ShenandoahTraversalKeepAliveUpdateClosure(ShenandoahObjToScanQueue* q) :
 768     _queue(q), _thread(Thread::current()),
 769     _traversal_gc(ShenandoahHeap::heap()->traversal_gc()),
 770     _mark_context(ShenandoahHeap::heap()->marking_context()) {}
 771 
 772   void do_oop(narrowOop* p) { do_oop_work(p); }
 773   void do_oop(oop* p)       { do_oop_work(p); }
 774 };
 775 























 776 class ShenandoahTraversalKeepAliveUpdateDegenClosure : public OopClosure {
 777 private:
 778   ShenandoahObjToScanQueue* _queue;
 779   Thread* _thread;
 780   ShenandoahTraversalGC* _traversal_gc;
 781   ShenandoahMarkingContext* const _mark_context;
 782 
 783   template <class T>
 784   inline void do_oop_work(T* p) {
 785     _traversal_gc->process_oop<T, false /* string dedup */, true /* degen */>(p, _thread, _queue, _mark_context);
 786   }
 787 
 788 public:
 789   ShenandoahTraversalKeepAliveUpdateDegenClosure(ShenandoahObjToScanQueue* q) :
 790           _queue(q), _thread(Thread::current()),
 791           _traversal_gc(ShenandoahHeap::heap()->traversal_gc()),
 792           _mark_context(ShenandoahHeap::heap()->marking_context()) {}
 793 
 794   void do_oop(narrowOop* p) { do_oop_work(p); }
 795   void do_oop(oop* p)       { do_oop_work(p); }


1068   uint serial_worker_id = 0;
1069   ShenandoahTaskTerminator terminator(1, task_queues());
1070   ShenandoahTraversalSingleThreadedDrainMarkingStackClosure complete_gc(serial_worker_id, &terminator, /* reset_terminator = */ true);
1071   ShenandoahPushWorkerQueuesScope scope(workers, task_queues(), 1, /* do_check = */ false);
1072 
1073   ShenandoahTraversalRefProcTaskExecutor executor(workers);
1074 
1075   ReferenceProcessorPhaseTimes pt(_heap->gc_timer(), rp->num_queues());
1076   if (!_heap->is_degenerated_gc_in_progress()) {
1077     ShenandoahTraversalSingleThreadKeepAliveUpdateClosure keep_alive(task_queues()->queue(serial_worker_id));
1078     rp->process_discovered_references(&is_alive, &keep_alive,
1079                                       &complete_gc, &executor,
1080                                       &pt);
1081   } else {
1082     ShenandoahTraversalSingleThreadKeepAliveUpdateDegenClosure keep_alive(task_queues()->queue(serial_worker_id));
1083     rp->process_discovered_references(&is_alive, &keep_alive,
1084                                       &complete_gc, &executor,
1085                                       &pt);
1086   }
1087 
1088   pt.print_all_references();
1089   assert(task_queues()->is_empty() || _heap->cancelled_gc(), "Should be empty");










1090 }


  13  *
  14  * You should have received a copy of the GNU General Public License version
  15  * 2 along with this work; if not, write to the Free Software Foundation,
  16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  17  *
  18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  19  * or visit www.oracle.com if you need additional information or have any
  20  * questions.
  21  *
  22  */
  23 
  24 #include "precompiled.hpp"
  25 
  26 #include "classfile/classLoaderData.hpp"
  27 #include "classfile/classLoaderDataGraph.hpp"
  28 #include "gc/shared/referenceProcessor.hpp"
  29 #include "gc/shared/referenceProcessorPhaseTimes.hpp"
  30 #include "gc/shared/workgroup.hpp"
  31 #include "gc/shared/weakProcessor.inline.hpp"
  32 #include "gc/shenandoah/shenandoahBarrierSet.hpp"

  33 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
  34 #include "gc/shenandoah/shenandoahCollectionSet.hpp"
  35 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
  36 #include "gc/shenandoah/shenandoahFreeSet.hpp"
  37 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
  38 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
  39 #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp"
  40 #include "gc/shenandoah/shenandoahHeuristics.hpp"
  41 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
  42 #include "gc/shenandoah/shenandoahOopClosures.inline.hpp"
  43 #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp"
  44 #include "gc/shenandoah/shenandoahStringDedup.hpp"
  45 #include "gc/shenandoah/shenandoahTaskqueue.inline.hpp"
  46 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
  47 #include "gc/shenandoah/shenandoahTraversalGC.hpp"
  48 #include "gc/shenandoah/shenandoahUtils.hpp"
  49 #include "gc/shenandoah/shenandoahVerifier.hpp"
  50 
  51 #include "memory/iterator.hpp"
  52 #include "memory/metaspace.hpp"


 179     bool unload_classes = _heap->unload_classes();
 180     ReferenceProcessor* rp = NULL;
 181     if (process_refs) {
 182       rp = _heap->ref_processor();
 183     }
 184 
 185     // Step 1: Process ordinary GC roots.
 186     {
 187       ShenandoahTraversalClosure roots_cl(q, rp);
 188       ShenandoahMarkCLDClosure cld_cl(&roots_cl);
 189       MarkingCodeBlobClosure code_cl(&roots_cl, CodeBlobToOopClosure::FixRelocations);
 190       if (unload_classes) {
 191         _rp->process_strong_roots(&roots_cl, &cld_cl, NULL, NULL, worker_id);
 192         // Need to pre-evac code roots here. Otherwise we might see from-space constants.
 193         ShenandoahWorkerTimings* worker_times = _heap->phase_timings()->worker_times();
 194         ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CodeCacheRoots, worker_id);
 195         _cset_coderoots->possibly_parallel_blobs_do(&code_cl);
 196       } else {
 197         _rp->process_all_roots(&roots_cl, &cld_cl, &code_cl, NULL, worker_id);
 198       }




 199     }
 200   }
 201 };
 202 
 203 class ShenandoahConcurrentTraversalCollectionTask : public AbstractGangTask {
 204 private:
 205   ShenandoahTaskTerminator* _terminator;
 206   ShenandoahHeap* _heap;
 207 public:
 208   ShenandoahConcurrentTraversalCollectionTask(ShenandoahTaskTerminator* terminator) :
 209     AbstractGangTask("Shenandoah Concurrent Traversal Collection"),
 210     _terminator(terminator),
 211     _heap(ShenandoahHeap::heap()) {}
 212 
 213   void work(uint worker_id) {
 214     ShenandoahConcurrentWorkerSession worker_session(worker_id);
 215     ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers);
 216     ShenandoahEvacOOMScope oom_evac_scope;
 217     ShenandoahTraversalGC* traversal_gc = _heap->traversal_gc();
 218 


 578     uint nworkers = _heap->workers()->active_workers();
 579     task_queues()->reserve(nworkers);
 580 
 581     // Finish traversal
 582     ShenandoahRootProcessor rp(_heap, nworkers, ShenandoahPhaseTimings::final_traversal_gc_work);
 583     ShenandoahTerminationTracker term(ShenandoahPhaseTimings::final_traversal_gc_termination);
 584 
 585     ShenandoahTaskTerminator terminator(nworkers, task_queues());
 586     ShenandoahFinalTraversalCollectionTask task(&rp, &terminator);
 587     _heap->workers()->run_task(&task);
 588 #if defined(COMPILER2) || INCLUDE_JVMCI
 589     DerivedPointerTable::update_pointers();
 590 #endif
 591   }
 592 
 593   if (!_heap->cancelled_gc() && _heap->process_references()) {
 594     weak_refs_work();
 595   }
 596 
 597   if (!_heap->cancelled_gc()) {

 598     if (_heap->unload_classes()) {
 599       _heap->unload_classes_and_cleanup_tables(false);
 600     }
 601 
 602     fixup_roots();
 603   }
 604 
 605   if (!_heap->cancelled_gc()) {
 606     assert(_task_queues->is_empty(), "queues must be empty after traversal GC");
 607     TASKQUEUE_STATS_ONLY(_task_queues->print_taskqueue_stats());
 608     TASKQUEUE_STATS_ONLY(_task_queues->reset_taskqueue_stats());
 609 
 610     // No more marking expected
 611     _heap->mark_complete_marking_context();
 612 
 613     // Resize metaspace
 614     MetaspaceGC::compute_new_size();
 615 
 616     // Still good? We can now trash the cset, and make final verification
 617     {
 618       ShenandoahGCPhase phase_cleanup(ShenandoahPhaseTimings::traversal_gc_cleanup);
 619       ShenandoahHeapLocker lock(_heap->lock());
 620 
 621       // Trash everything
 622       // Clear immediate garbage regions.


 752   ShenandoahObjToScanQueue* _queue;
 753   Thread* _thread;
 754   ShenandoahTraversalGC* _traversal_gc;
 755   ShenandoahMarkingContext* const _mark_context;
 756 
 757   template <class T>
 758   inline void do_oop_work(T* p) {
 759     _traversal_gc->process_oop<T, false /* string dedup */, false /* degen */>(p, _thread, _queue, _mark_context);
 760   }
 761 
 762 public:
 763   ShenandoahTraversalKeepAliveUpdateClosure(ShenandoahObjToScanQueue* q) :
 764     _queue(q), _thread(Thread::current()),
 765     _traversal_gc(ShenandoahHeap::heap()->traversal_gc()),
 766     _mark_context(ShenandoahHeap::heap()->marking_context()) {}
 767 
 768   void do_oop(narrowOop* p) { do_oop_work(p); }
 769   void do_oop(oop* p)       { do_oop_work(p); }
 770 };
 771 
 772 class ShenandoahTraversalWeakUpdateClosure : public OopClosure {
 773 private:
 774   template <class T>
 775   inline void do_oop_work(T* p) {
 776     // Cannot call maybe_update_with_forwarded, because on traversal-degen
 777     // path the collection set is already dropped. Instead, do the unguarded store.
 778     // TODO: This can be fixed after degen-traversal stops dropping cset.
 779     T o = RawAccess<>::oop_load(p);
 780     if (!CompressedOops::is_null(o)) {
 781       oop obj = CompressedOops::decode_not_null(o);
 782       obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
 783       shenandoah_assert_marked(p, obj);
 784       RawAccess<IS_NOT_NULL>::oop_store(p, obj);
 785     }
 786   }
 787 
 788 public:
 789   ShenandoahTraversalWeakUpdateClosure() {}
 790 
 791   void do_oop(narrowOop* p) { do_oop_work(p); }
 792   void do_oop(oop* p)       { do_oop_work(p); }
 793 };
 794 
 795 class ShenandoahTraversalKeepAliveUpdateDegenClosure : public OopClosure {
 796 private:
 797   ShenandoahObjToScanQueue* _queue;
 798   Thread* _thread;
 799   ShenandoahTraversalGC* _traversal_gc;
 800   ShenandoahMarkingContext* const _mark_context;
 801 
 802   template <class T>
 803   inline void do_oop_work(T* p) {
 804     _traversal_gc->process_oop<T, false /* string dedup */, true /* degen */>(p, _thread, _queue, _mark_context);
 805   }
 806 
 807 public:
 808   ShenandoahTraversalKeepAliveUpdateDegenClosure(ShenandoahObjToScanQueue* q) :
 809           _queue(q), _thread(Thread::current()),
 810           _traversal_gc(ShenandoahHeap::heap()->traversal_gc()),
 811           _mark_context(ShenandoahHeap::heap()->marking_context()) {}
 812 
 813   void do_oop(narrowOop* p) { do_oop_work(p); }
 814   void do_oop(oop* p)       { do_oop_work(p); }


1087   uint serial_worker_id = 0;
1088   ShenandoahTaskTerminator terminator(1, task_queues());
1089   ShenandoahTraversalSingleThreadedDrainMarkingStackClosure complete_gc(serial_worker_id, &terminator, /* reset_terminator = */ true);
1090   ShenandoahPushWorkerQueuesScope scope(workers, task_queues(), 1, /* do_check = */ false);
1091 
1092   ShenandoahTraversalRefProcTaskExecutor executor(workers);
1093 
1094   ReferenceProcessorPhaseTimes pt(_heap->gc_timer(), rp->num_queues());
1095   if (!_heap->is_degenerated_gc_in_progress()) {
1096     ShenandoahTraversalSingleThreadKeepAliveUpdateClosure keep_alive(task_queues()->queue(serial_worker_id));
1097     rp->process_discovered_references(&is_alive, &keep_alive,
1098                                       &complete_gc, &executor,
1099                                       &pt);
1100   } else {
1101     ShenandoahTraversalSingleThreadKeepAliveUpdateDegenClosure keep_alive(task_queues()->queue(serial_worker_id));
1102     rp->process_discovered_references(&is_alive, &keep_alive,
1103                                       &complete_gc, &executor,
1104                                       &pt);
1105   }
1106 
1107   {
1108     ShenandoahGCPhase phase(phase_process);
1109     ShenandoahTerminationTracker termination(ShenandoahPhaseTimings::weakrefs_termination);
1110 
1111     // Process leftover weak oops (using parallel version)
1112     ShenandoahTraversalWeakUpdateClosure cl;
1113     WeakProcessor::weak_oops_do(workers, &is_alive, &cl, 1);
1114 
1115     pt.print_all_references();
1116 
1117     assert(task_queues()->is_empty() || _heap->cancelled_gc(), "Should be empty");
1118   }
1119 }
< prev index next >