21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26
27 #include "aot/aotLoader.hpp"
28 #include "classfile/stringTable.hpp"
29 #include "classfile/systemDictionary.hpp"
30 #include "code/codeCache.hpp"
31 #include "gc/g1/g1BarrierSet.hpp"
32 #include "gc/g1/g1CodeBlobClosure.hpp"
33 #include "gc/g1/g1CollectedHeap.inline.hpp"
34 #include "gc/g1/g1CollectorState.hpp"
35 #include "gc/g1/g1GCPhaseTimes.hpp"
36 #include "gc/g1/g1ParScanThreadState.inline.hpp"
37 #include "gc/g1/g1Policy.hpp"
38 #include "gc/g1/g1RootClosures.hpp"
39 #include "gc/g1/g1RootProcessor.hpp"
40 #include "gc/g1/heapRegion.inline.hpp"
41 #include "gc/shared/referenceProcessor.hpp"
42 #include "gc/shared/weakProcessor.hpp"
43 #include "memory/allocation.inline.hpp"
44 #include "runtime/mutex.hpp"
45 #include "services/management.hpp"
46 #include "utilities/macros.hpp"
47
48 void G1RootProcessor::worker_has_discovered_all_strong_classes() {
49 assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
50
51 uint new_value = (uint)Atomic::add(1, &_n_workers_discovered_strong_classes);
52 if (new_value == n_workers()) {
53 // This thread is last. Notify the others.
54 MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag);
55 _lock.notify_all();
56 }
57 }
58
59 void G1RootProcessor::wait_until_all_strong_classes_discovered() {
60 assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
61
62 if ((uint)_n_workers_discovered_strong_classes != n_workers()) {
63 MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag);
64 while ((uint)_n_workers_discovered_strong_classes != n_workers()) {
65 _lock.wait(Mutex::_no_safepoint_check_flag, 0, false);
66 }
67 }
68 }
69
70 G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h, uint n_workers) :
71 _g1h(g1h),
72 _process_strong_tasks(G1RP_PS_NumElements),
73 _srs(n_workers),
74 _lock(Mutex::leaf, "G1 Root Scanning barrier lock", false, Monitor::_safepoint_check_never),
75 _n_workers_discovered_strong_classes(0) {}
76
77 void G1RootProcessor::evacuate_roots(G1ParScanThreadState* pss, uint worker_i) {
78 G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times();
79
80 G1EvacPhaseTimesTracker timer(phase_times, pss, G1GCPhaseTimes::ExtRootScan, worker_i);
81
82 G1EvacuationRootClosures* closures = pss->closures();
83 process_java_roots(closures, phase_times, worker_i);
84
85 // This is the point where this worker thread will not find more strong CLDs/nmethods.
86 // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing.
87 if (closures->trace_metadata()) {
88 worker_has_discovered_all_strong_classes();
89 }
90
91 process_vm_roots(closures, phase_times, worker_i);
92 process_string_table_roots(closures, phase_times, worker_i);
93
94 {
284 AOTLoader::oops_do(strong_roots);
285 }
286 }
287 #endif
288
289 {
290 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SystemDictionaryRoots, worker_i);
291 if (!_process_strong_tasks.is_task_claimed(G1RP_PS_SystemDictionary_oops_do)) {
292 SystemDictionary::oops_do(strong_roots);
293 }
294 }
295 }
296
297 void G1RootProcessor::process_string_table_roots(G1RootClosures* closures,
298 G1GCPhaseTimes* phase_times,
299 uint worker_i) {
300 assert(closures->weak_oops() != NULL, "Should only be called when all roots are processed");
301 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::StringTableRoots, worker_i);
302 // All threads execute the following. A specific chunk of buckets
303 // from the StringTable are the individual tasks.
304 StringTable::possibly_parallel_oops_do(closures->weak_oops());
305 }
306
307 void G1RootProcessor::process_code_cache_roots(CodeBlobClosure* code_closure,
308 G1GCPhaseTimes* phase_times,
309 uint worker_i) {
310 if (!_process_strong_tasks.is_task_claimed(G1RP_PS_CodeCache_oops_do)) {
311 CodeCache::blobs_do(code_closure);
312 }
313 }
314
315 void G1RootProcessor::process_full_gc_weak_roots(OopClosure* oops) {
316 if (!_process_strong_tasks.is_task_claimed(G1RP_PS_refProcessor_oops_do)) {
317 _g1h->ref_processor_stw()->weak_oops_do(oops);
318 }
319
320 if (!_process_strong_tasks.is_task_claimed(G1RP_PS_weakProcessor_oops_do)) {
321 WeakProcessor::oops_do(oops);
322 }
323 }
324
|
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26
27 #include "aot/aotLoader.hpp"
28 #include "classfile/stringTable.hpp"
29 #include "classfile/systemDictionary.hpp"
30 #include "code/codeCache.hpp"
31 #include "gc/g1/g1BarrierSet.hpp"
32 #include "gc/g1/g1CodeBlobClosure.hpp"
33 #include "gc/g1/g1CollectedHeap.inline.hpp"
34 #include "gc/g1/g1CollectorState.hpp"
35 #include "gc/g1/g1GCPhaseTimes.hpp"
36 #include "gc/g1/g1ParScanThreadState.inline.hpp"
37 #include "gc/g1/g1Policy.hpp"
38 #include "gc/g1/g1RootClosures.hpp"
39 #include "gc/g1/g1RootProcessor.hpp"
40 #include "gc/g1/heapRegion.inline.hpp"
41 #include "gc/shared/oopStorageParState.hpp"
42 #include "gc/shared/referenceProcessor.hpp"
43 #include "gc/shared/weakProcessor.hpp"
44 #include "memory/allocation.inline.hpp"
45 #include "runtime/mutex.hpp"
46 #include "services/management.hpp"
47 #include "utilities/macros.hpp"
48
49 void G1RootProcessor::worker_has_discovered_all_strong_classes() {
50 assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
51
52 uint new_value = (uint)Atomic::add(1, &_n_workers_discovered_strong_classes);
53 if (new_value == n_workers()) {
54 // This thread is last. Notify the others.
55 MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag);
56 _lock.notify_all();
57 }
58 }
59
60 void G1RootProcessor::wait_until_all_strong_classes_discovered() {
61 assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
62
63 if ((uint)_n_workers_discovered_strong_classes != n_workers()) {
64 MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag);
65 while ((uint)_n_workers_discovered_strong_classes != n_workers()) {
66 _lock.wait(Mutex::_no_safepoint_check_flag, 0, false);
67 }
68 }
69 }
70
71 G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h, uint n_workers) :
72 _g1h(g1h),
73 _process_strong_tasks(G1RP_PS_NumElements),
74 _srs(n_workers),
75 _lock(Mutex::leaf, "G1 Root Scanning barrier lock", false, Monitor::_safepoint_check_never),
76 _par_state_string(StringTable::weak_storage()),
77 _n_workers_discovered_strong_classes(0) {}
78
79 void G1RootProcessor::evacuate_roots(G1ParScanThreadState* pss, uint worker_i) {
80 G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times();
81
82 G1EvacPhaseTimesTracker timer(phase_times, pss, G1GCPhaseTimes::ExtRootScan, worker_i);
83
84 G1EvacuationRootClosures* closures = pss->closures();
85 process_java_roots(closures, phase_times, worker_i);
86
87 // This is the point where this worker thread will not find more strong CLDs/nmethods.
88 // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing.
89 if (closures->trace_metadata()) {
90 worker_has_discovered_all_strong_classes();
91 }
92
93 process_vm_roots(closures, phase_times, worker_i);
94 process_string_table_roots(closures, phase_times, worker_i);
95
96 {
286 AOTLoader::oops_do(strong_roots);
287 }
288 }
289 #endif
290
291 {
292 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SystemDictionaryRoots, worker_i);
293 if (!_process_strong_tasks.is_task_claimed(G1RP_PS_SystemDictionary_oops_do)) {
294 SystemDictionary::oops_do(strong_roots);
295 }
296 }
297 }
298
299 void G1RootProcessor::process_string_table_roots(G1RootClosures* closures,
300 G1GCPhaseTimes* phase_times,
301 uint worker_i) {
302 assert(closures->weak_oops() != NULL, "Should only be called when all roots are processed");
303 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::StringTableRoots, worker_i);
304 // All threads execute the following. A specific chunk of buckets
305 // from the StringTable are the individual tasks.
306 StringTable::possibly_parallel_oops_do(&_par_state_string, closures->weak_oops());
307 }
308
309 void G1RootProcessor::process_code_cache_roots(CodeBlobClosure* code_closure,
310 G1GCPhaseTimes* phase_times,
311 uint worker_i) {
312 if (!_process_strong_tasks.is_task_claimed(G1RP_PS_CodeCache_oops_do)) {
313 CodeCache::blobs_do(code_closure);
314 }
315 }
316
317 void G1RootProcessor::process_full_gc_weak_roots(OopClosure* oops) {
318 if (!_process_strong_tasks.is_task_claimed(G1RP_PS_refProcessor_oops_do)) {
319 _g1h->ref_processor_stw()->weak_oops_do(oops);
320 }
321
322 if (!_process_strong_tasks.is_task_claimed(G1RP_PS_weakProcessor_oops_do)) {
323 WeakProcessor::oops_do(oops);
324 }
325 }
326
|