184 rp = _heap->ref_processor(); |
184 rp = _heap->ref_processor(); |
185 } |
185 } |
186 |
186 |
187 // Step 1: Process ordinary GC roots. |
187 // Step 1: Process ordinary GC roots. |
188 { |
188 { |
189 ShenandoahTraversalClosure roots_cl(q, rp); |
189 ShenandoahTraversalRootsClosure roots_cl(q, rp); |
190 ShenandoahMarkCLDClosure cld_cl(&roots_cl); |
190 ShenandoahMarkCLDClosure cld_cl(&roots_cl); |
191 MarkingCodeBlobClosure code_cl(&roots_cl, CodeBlobToOopClosure::FixRelocations); |
191 MarkingCodeBlobClosure code_cl(&roots_cl, CodeBlobToOopClosure::FixRelocations); |
192 if (unload_classes) { |
192 if (unload_classes) { |
193 _rp->roots_do(worker_id, &roots_cl, NULL, &code_cl); |
193 _rp->roots_do(worker_id, &roots_cl, NULL, &code_cl); |
194 } else { |
194 } else { |
264 // For oops in code roots, they are marked, evacuated, enqueued for further traversal, |
264 // For oops in code roots, they are marked, evacuated, enqueued for further traversal, |
265 // and the references to the oops are updated during init pause. New nmethods are handled |
265 // and the references to the oops are updated during init pause. New nmethods are handled |
266 // in similar way during nmethod-register process. Therefore, we don't need to rescan code |
266 // in similar way during nmethod-register process. Therefore, we don't need to rescan code |
267 // roots here. |
267 // roots here. |
268 if (!_heap->is_degenerated_gc_in_progress()) { |
268 if (!_heap->is_degenerated_gc_in_progress()) { |
269 ShenandoahTraversalClosure roots_cl(q, rp); |
269 ShenandoahTraversalRootsClosure roots_cl(q, rp); |
270 ShenandoahTraversalSATBThreadsClosure tc(&satb_cl); |
270 ShenandoahTraversalSATBThreadsClosure tc(&satb_cl); |
271 if (unload_classes) { |
271 if (unload_classes) { |
272 ShenandoahRemarkCLDClosure remark_cld_cl(&roots_cl); |
272 ShenandoahRemarkCLDClosure remark_cld_cl(&roots_cl); |
273 _rp->strong_roots_do(worker_id, &roots_cl, &remark_cld_cl, NULL, &tc); |
273 _rp->strong_roots_do(worker_id, &roots_cl, &remark_cld_cl, NULL, &tc); |
274 } else { |
274 } else { |
765 ShenandoahTraversalGC* _traversal_gc; |
765 ShenandoahTraversalGC* _traversal_gc; |
766 ShenandoahMarkingContext* const _mark_context; |
766 ShenandoahMarkingContext* const _mark_context; |
767 |
767 |
768 template <class T> |
768 template <class T> |
769 inline void do_oop_work(T* p) { |
769 inline void do_oop_work(T* p) { |
770 _traversal_gc->process_oop<T, false /* string dedup */, false /* degen */>(p, _thread, _queue, _mark_context); |
770 _traversal_gc->process_oop<T, false /* string dedup */, false /* degen */, true /* atomic update */>(p, _thread, _queue, _mark_context); |
771 } |
771 } |
772 |
772 |
773 public: |
773 public: |
774 ShenandoahTraversalKeepAliveUpdateClosure(ShenandoahObjToScanQueue* q) : |
774 ShenandoahTraversalKeepAliveUpdateClosure(ShenandoahObjToScanQueue* q) : |
775 _queue(q), _thread(Thread::current()), |
775 _queue(q), _thread(Thread::current()), |
787 ShenandoahTraversalGC* _traversal_gc; |
787 ShenandoahTraversalGC* _traversal_gc; |
788 ShenandoahMarkingContext* const _mark_context; |
788 ShenandoahMarkingContext* const _mark_context; |
789 |
789 |
790 template <class T> |
790 template <class T> |
791 inline void do_oop_work(T* p) { |
791 inline void do_oop_work(T* p) { |
792 _traversal_gc->process_oop<T, false /* string dedup */, true /* degen */>(p, _thread, _queue, _mark_context); |
792 _traversal_gc->process_oop<T, false /* string dedup */, true /* degen */, false /* atomic update */>(p, _thread, _queue, _mark_context); |
793 } |
793 } |
794 |
794 |
795 public: |
795 public: |
796 ShenandoahTraversalKeepAliveUpdateDegenClosure(ShenandoahObjToScanQueue* q) : |
796 ShenandoahTraversalKeepAliveUpdateDegenClosure(ShenandoahObjToScanQueue* q) : |
797 _queue(q), _thread(Thread::current()), |
797 _queue(q), _thread(Thread::current()), |
810 ShenandoahMarkingContext* const _mark_context; |
810 ShenandoahMarkingContext* const _mark_context; |
811 |
811 |
812 template <class T> |
812 template <class T> |
813 inline void do_oop_work(T* p) { |
813 inline void do_oop_work(T* p) { |
814 ShenandoahEvacOOMScope evac_scope; |
814 ShenandoahEvacOOMScope evac_scope; |
815 _traversal_gc->process_oop<T, false /* string dedup */, false /* degen */>(p, _thread, _queue, _mark_context); |
815 _traversal_gc->process_oop<T, false /* string dedup */, false /* degen */, true /* atomic update */>(p, _thread, _queue, _mark_context); |
816 } |
816 } |
817 |
817 |
818 public: |
818 public: |
819 ShenandoahTraversalSingleThreadKeepAliveUpdateClosure(ShenandoahObjToScanQueue* q) : |
819 ShenandoahTraversalSingleThreadKeepAliveUpdateClosure(ShenandoahObjToScanQueue* q) : |
820 _queue(q), _thread(Thread::current()), |
820 _queue(q), _thread(Thread::current()), |
833 ShenandoahMarkingContext* const _mark_context; |
833 ShenandoahMarkingContext* const _mark_context; |
834 |
834 |
835 template <class T> |
835 template <class T> |
836 inline void do_oop_work(T* p) { |
836 inline void do_oop_work(T* p) { |
837 ShenandoahEvacOOMScope evac_scope; |
837 ShenandoahEvacOOMScope evac_scope; |
838 _traversal_gc->process_oop<T, false /* string dedup */, true /* degen */>(p, _thread, _queue, _mark_context); |
838 _traversal_gc->process_oop<T, false /* string dedup */, true /* degen */, false /* atomic update */>(p, _thread, _queue, _mark_context); |
839 } |
839 } |
840 |
840 |
841 public: |
841 public: |
842 ShenandoahTraversalSingleThreadKeepAliveUpdateDegenClosure(ShenandoahObjToScanQueue* q) : |
842 ShenandoahTraversalSingleThreadKeepAliveUpdateDegenClosure(ShenandoahObjToScanQueue* q) : |
843 _queue(q), _thread(Thread::current()), |
843 _queue(q), _thread(Thread::current()), |