1757 for (size_t i = 0; i < size; ++i) {
1758 do_entry(buffer[i]);
1759 }
1760 }
1761 };
1762
1763 class G1RemarkThreadsClosure : public ThreadClosure {
1764 G1CMSATBBufferClosure _cm_satb_cl;
1765 G1CMOopClosure _cm_cl;
1766 MarkingCodeBlobClosure _code_cl;
1767 int _thread_parity;
1768
1769 public:
1770 G1RemarkThreadsClosure(G1CollectedHeap* g1h, G1CMTask* task) :
1771 _cm_satb_cl(task, g1h),
1772 _cm_cl(g1h, task),
1773 _code_cl(&_cm_cl, !CodeBlobToOopClosure::FixRelocations),
1774 _thread_parity(Threads::thread_claim_parity()) {}
1775
1776 void do_thread(Thread* thread) {
1777 if (thread->is_Java_thread()) {
1778 if (thread->claim_oops_do(true, _thread_parity)) {
1779 JavaThread* jt = (JavaThread*)thread;
1780
1781 // In theory it should not be neccessary to explicitly walk the nmethods to find roots for concurrent marking
1782 // however the liveness of oops reachable from nmethods have very complex lifecycles:
1783 // * Alive if on the stack of an executing method
1784 // * Weakly reachable otherwise
1785 // Some objects reachable from nmethods, such as the class loader (or klass_holder) of the receiver should be
1786 // live by the SATB invariant but other oops recorded in nmethods may behave differently.
1787 jt->nmethods_do(&_code_cl);
1788
1789 G1ThreadLocalData::satb_mark_queue(jt).apply_closure_and_empty(&_cm_satb_cl);
1790 }
1791 } else if (thread->is_VM_thread()) {
1792 if (thread->claim_oops_do(true, _thread_parity)) {
1793 G1BarrierSet::satb_mark_queue_set().shared_satb_queue()->apply_closure_and_empty(&_cm_satb_cl);
1794 }
1795 }
1796 }
1797 };
1798
1799 class G1CMRemarkTask : public AbstractGangTask {
1800 G1ConcurrentMark* _cm;
1801 public:
1802 void work(uint worker_id) {
1803 G1CMTask* task = _cm->task(worker_id);
1804 task->record_start_time();
1805 {
1806 ResourceMark rm;
1807 HandleMark hm;
1808
1809 G1RemarkThreadsClosure threads_f(G1CollectedHeap::heap(), task);
1810 Threads::threads_do(&threads_f);
1811 }
1812
1813 do {
|
1757 for (size_t i = 0; i < size; ++i) {
1758 do_entry(buffer[i]);
1759 }
1760 }
1761 };
1762
1763 class G1RemarkThreadsClosure : public ThreadClosure {
1764 G1CMSATBBufferClosure _cm_satb_cl;
1765 G1CMOopClosure _cm_cl;
1766 MarkingCodeBlobClosure _code_cl;
1767 int _thread_parity;
1768
1769 public:
1770 G1RemarkThreadsClosure(G1CollectedHeap* g1h, G1CMTask* task) :
1771 _cm_satb_cl(task, g1h),
1772 _cm_cl(g1h, task),
1773 _code_cl(&_cm_cl, !CodeBlobToOopClosure::FixRelocations),
1774 _thread_parity(Threads::thread_claim_parity()) {}
1775
1776 void do_thread(Thread* thread) {
1777 if (thread->claim_oops_do(true, _thread_parity)) {
1778 SATBMarkQueue& queue = G1ThreadLocalData::satb_mark_queue(thread);
1779 queue.apply_closure_and_empty(&_cm_satb_cl);
1780 if (thread->is_Java_thread()) {
1781 // In theory it should not be neccessary to explicitly walk the nmethods to find roots for concurrent marking
1782 // however the liveness of oops reachable from nmethods have very complex lifecycles:
1783 // * Alive if on the stack of an executing method
1784 // * Weakly reachable otherwise
1785 // Some objects reachable from nmethods, such as the class loader (or klass_holder) of the receiver should be
1786 // live by the SATB invariant but other oops recorded in nmethods may behave differently.
1787 JavaThread* jt = (JavaThread*)thread;
1788 jt->nmethods_do(&_code_cl);
1789 }
1790 }
1791 }
1792 };
1793
1794 class G1CMRemarkTask : public AbstractGangTask {
1795 G1ConcurrentMark* _cm;
1796 public:
1797 void work(uint worker_id) {
1798 G1CMTask* task = _cm->task(worker_id);
1799 task->record_start_time();
1800 {
1801 ResourceMark rm;
1802 HandleMark hm;
1803
1804 G1RemarkThreadsClosure threads_f(G1CollectedHeap::heap(), task);
1805 Threads::threads_do(&threads_f);
1806 }
1807
1808 do {
|