73 };
74
75 HeapRegionGatheringOopClosure _oc;
76 public:
77 G1CodeBlobClosure(OopClosure* oc) : _oc(oc) {}
78
79 void do_code_blob(CodeBlob* cb) {
80 nmethod* nm = cb->as_nmethod_or_null();
81 if (nm != NULL) {
82 if (!nm->test_set_oops_do_mark()) {
83 _oc.set_nm(nm);
84 nm->oops_do(&_oc);
85 nm->fix_oop_relocations();
86 }
87 }
88 }
89 };
90
91
92 void G1RootProcessor::worker_has_discovered_all_strong_classes() {
93 assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
94
95 uint new_value = (uint)Atomic::add(1, &_n_workers_discovered_strong_classes);
96 if (new_value == n_workers()) {
97 // This thread is last. Notify the others.
98 MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag);
99 _lock.notify_all();
100 }
101 }
102
103 void G1RootProcessor::wait_until_all_strong_classes_discovered() {
104 assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
105
106 if ((uint)_n_workers_discovered_strong_classes != n_workers()) {
107 MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag);
108 while ((uint)_n_workers_discovered_strong_classes != n_workers()) {
109 _lock.wait(Mutex::_no_safepoint_check_flag, 0, false);
110 }
111 }
112 }
113
114 G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h, uint n_workers) :
115 _g1h(g1h),
116 _process_strong_tasks(new SubTasksDone(G1RP_PS_NumElements)),
117 _srs(n_workers),
118 _lock(Mutex::leaf, "G1 Root Scanning barrier lock", false, Monitor::_safepoint_check_never),
119 _n_workers_discovered_strong_classes(0) {}
120
121 void G1RootProcessor::evacuate_roots(OopClosure* scan_non_heap_roots,
122 OopClosure* scan_non_heap_weak_roots,
123 CLDClosure* scan_strong_clds,
124 CLDClosure* scan_weak_clds,
194
195 phase_times->record_time_secs(G1GCPhaseTimes::ExtRootScan, worker_i, ext_root_time_sec);
196
197 // During conc marking we have to filter the per-thread SATB buffers
198 // to make sure we remove any oops into the CSet (which will show up
199 // as implicitly live).
200 {
201 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SATBFiltering, worker_i);
202 if (!_process_strong_tasks->is_task_claimed(G1RP_PS_filter_satb_buffers) && _g1h->mark_in_progress()) {
203 JavaThread::satb_mark_queue_set().filter_thread_buffers();
204 }
205 }
206
207 _process_strong_tasks->all_tasks_completed(n_workers());
208 }
209
210 void G1RootProcessor::process_strong_roots(OopClosure* oops,
211 CLDClosure* clds,
212 CodeBlobClosure* blobs) {
213
214 process_java_roots(oops, clds, clds, NULL, blobs, NULL, 0);
215 process_vm_roots(oops, NULL, NULL, 0);
216
217 _process_strong_tasks->all_tasks_completed(n_workers());
218 }
219
220 void G1RootProcessor::process_all_roots(OopClosure* oops,
221 CLDClosure* clds,
222 CodeBlobClosure* blobs) {
223
224 process_java_roots(oops, NULL, clds, clds, NULL, NULL, 0);
225 process_vm_roots(oops, oops, NULL, 0);
226
227 if (!_process_strong_tasks->is_task_claimed(G1RP_PS_CodeCache_oops_do)) {
228 CodeCache::blobs_do(blobs);
229 }
230
231 _process_strong_tasks->all_tasks_completed(n_workers());
232 }
233
234 void G1RootProcessor::process_java_roots(OopClosure* strong_roots,
235 CLDClosure* thread_stack_clds,
236 CLDClosure* strong_clds,
237 CLDClosure* weak_clds,
238 CodeBlobClosure* strong_code,
239 G1GCPhaseTimes* phase_times,
240 uint worker_i) {
241 assert(thread_stack_clds == NULL || weak_clds == NULL, "There is overlap between those, only one may be set");
242 // Iterating over the CLDG and the Threads are done early to allow us to
243 // first process the strong CLDs and nmethods and then, after a barrier,
244 // let the thread process the weak CLDs and nmethods.
245 {
246 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CLDGRoots, worker_i);
247 if (!_process_strong_tasks->is_task_claimed(G1RP_PS_ClassLoaderDataGraph_oops_do)) {
248 ClassLoaderDataGraph::roots_cld_do(strong_clds, weak_clds);
249 }
250 }
251
252 {
253 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ThreadRoots, worker_i);
254 bool is_par = n_workers() > 1;
255 Threads::possibly_parallel_oops_do(is_par, strong_roots, thread_stack_clds, strong_code);
256 }
257 }
258
259 void G1RootProcessor::process_vm_roots(OopClosure* strong_roots,
260 OopClosure* weak_roots,
261 G1GCPhaseTimes* phase_times,
|
73 };
74
75 HeapRegionGatheringOopClosure _oc;
76 public:
77 G1CodeBlobClosure(OopClosure* oc) : _oc(oc) {}
78
79 void do_code_blob(CodeBlob* cb) {
80 nmethod* nm = cb->as_nmethod_or_null();
81 if (nm != NULL) {
82 if (!nm->test_set_oops_do_mark()) {
83 _oc.set_nm(nm);
84 nm->oops_do(&_oc);
85 nm->fix_oop_relocations();
86 }
87 }
88 }
89 };
90
91
92 void G1RootProcessor::worker_has_discovered_all_strong_classes() {
93 assert(ClassUnloading && ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
94
95 uint new_value = (uint)Atomic::add(1, &_n_workers_discovered_strong_classes);
96 if (new_value == n_workers()) {
97 // This thread is last. Notify the others.
98 MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag);
99 _lock.notify_all();
100 }
101 }
102
103 void G1RootProcessor::wait_until_all_strong_classes_discovered() {
104 assert(ClassUnloading && ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
105
106 if ((uint)_n_workers_discovered_strong_classes != n_workers()) {
107 MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag);
108 while ((uint)_n_workers_discovered_strong_classes != n_workers()) {
109 _lock.wait(Mutex::_no_safepoint_check_flag, 0, false);
110 }
111 }
112 }
113
114 G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h, uint n_workers) :
115 _g1h(g1h),
116 _process_strong_tasks(new SubTasksDone(G1RP_PS_NumElements)),
117 _srs(n_workers),
118 _lock(Mutex::leaf, "G1 Root Scanning barrier lock", false, Monitor::_safepoint_check_never),
119 _n_workers_discovered_strong_classes(0) {}
120
121 void G1RootProcessor::evacuate_roots(OopClosure* scan_non_heap_roots,
122 OopClosure* scan_non_heap_weak_roots,
123 CLDClosure* scan_strong_clds,
124 CLDClosure* scan_weak_clds,
194
195 phase_times->record_time_secs(G1GCPhaseTimes::ExtRootScan, worker_i, ext_root_time_sec);
196
197 // During conc marking we have to filter the per-thread SATB buffers
198 // to make sure we remove any oops into the CSet (which will show up
199 // as implicitly live).
200 {
201 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SATBFiltering, worker_i);
202 if (!_process_strong_tasks->is_task_claimed(G1RP_PS_filter_satb_buffers) && _g1h->mark_in_progress()) {
203 JavaThread::satb_mark_queue_set().filter_thread_buffers();
204 }
205 }
206
207 _process_strong_tasks->all_tasks_completed(n_workers());
208 }
209
210 void G1RootProcessor::process_strong_roots(OopClosure* oops,
211 CLDClosure* clds,
212 CodeBlobClosure* blobs) {
213
214 process_java_roots(oops, clds, clds, ClassUnloading ? NULL : clds, blobs, NULL, 0);
215 process_vm_roots(oops, NULL, NULL, 0);
216
217 _process_strong_tasks->all_tasks_completed(n_workers());
218 }
219
220 void G1RootProcessor::process_all_roots(OopClosure* oops,
221 CLDClosure* clds,
222 CodeBlobClosure* blobs) {
223
224 process_java_roots(oops, NULL, clds, clds, NULL, NULL, 0);
225 process_vm_roots(oops, oops, NULL, 0);
226
227 if (!_process_strong_tasks->is_task_claimed(G1RP_PS_CodeCache_oops_do)) {
228 CodeCache::blobs_do(blobs);
229 }
230
231 _process_strong_tasks->all_tasks_completed(n_workers());
232 }
233
234 void G1RootProcessor::process_java_roots(OopClosure* strong_roots,
235 CLDClosure* thread_stack_clds,
236 CLDClosure* strong_clds,
237 CLDClosure* weak_clds,
238 CodeBlobClosure* strong_code,
239 G1GCPhaseTimes* phase_times,
240 uint worker_i) {
241 assert(thread_stack_clds == NULL || weak_clds == NULL || !ClassUnloading, "There is overlap between those, only one may be set");
242 // Iterating over the CLDG and the Threads are done early to allow us to
243 // first process the strong CLDs and nmethods and then, after a barrier,
244 // let the thread process the weak CLDs and nmethods.
245 {
246 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CLDGRoots, worker_i);
247 if (!_process_strong_tasks->is_task_claimed(G1RP_PS_ClassLoaderDataGraph_oops_do)) {
248 ClassLoaderDataGraph::roots_cld_do(strong_clds, weak_clds);
249 }
250 }
251
252 {
253 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ThreadRoots, worker_i);
254 bool is_par = n_workers() > 1;
255 Threads::possibly_parallel_oops_do(is_par, strong_roots, thread_stack_clds, strong_code);
256 }
257 }
258
259 void G1RootProcessor::process_vm_roots(OopClosure* strong_roots,
260 OopClosure* weak_roots,
261 G1GCPhaseTimes* phase_times,
|