55 }
56
57 void G1RootProcessor::wait_until_all_strong_classes_discovered() {
58 assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
59
60 if ((uint)_n_workers_discovered_strong_classes != n_workers()) {
61 MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag);
62 while ((uint)_n_workers_discovered_strong_classes != n_workers()) {
63 _lock.wait(Mutex::_no_safepoint_check_flag, 0, false);
64 }
65 }
66 }
67
68 G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h, uint n_workers) :
69 _g1h(g1h),
70 _process_strong_tasks(G1RP_PS_NumElements),
71 _srs(n_workers),
72 _lock(Mutex::leaf, "G1 Root Scanning barrier lock", false, Monitor::_safepoint_check_never),
73 _n_workers_discovered_strong_classes(0) {}
74
75 void G1RootProcessor::evacuate_roots(G1ParScanThreadState* pss, G1EvacuationRootClosures* closures, uint worker_i) {
76 double ext_roots_start = os::elapsedTime();
77 G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times();
78
79 process_java_roots(closures, phase_times, worker_i);
80
81 // This is the point where this worker thread will not find more strong CLDs/nmethods.
82 // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing.
83 if (closures->trace_metadata()) {
84 worker_has_discovered_all_strong_classes();
85 }
86
87 process_vm_roots(closures, phase_times, worker_i);
88 process_string_table_roots(closures, phase_times, worker_i);
89
90 {
91 // Now the CM ref_processor roots.
92 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CMRefRoots, worker_i);
93 if (!_process_strong_tasks.is_task_claimed(G1RP_PS_refProcessor_oops_do)) {
94 // We need to treat the discovered reference lists of the
95 // concurrent mark ref processor as roots and keep entries
96 // (which are added by the marking threads) on them live
97 // until they can be processed at the end of marking.
98 _g1h->ref_processor_cm()->weak_oops_do(closures->strong_oops());
99 }
100 }
101
102 if (closures->trace_metadata()) {
103 {
104 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WaitForStrongCLD, worker_i);
105 // Barrier to make sure all workers passed
106 // the strong CLD and strong nmethods phases.
107 wait_until_all_strong_classes_discovered();
108 }
109
110 // Now take the complement of the strong CLDs.
111 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WeakCLDRoots, worker_i);
112 assert(closures->second_pass_weak_clds() != NULL, "Should be non-null if we are tracing metadata.");
113 ClassLoaderDataGraph::roots_cld_do(NULL, closures->second_pass_weak_clds());
114 } else {
115 phase_times->record_time_secs(G1GCPhaseTimes::WaitForStrongCLD, worker_i, 0.0);
116 phase_times->record_time_secs(G1GCPhaseTimes::WeakCLDRoots, worker_i, 0.0);
117 assert(closures->second_pass_weak_clds() == NULL, "Should be null if not tracing metadata.");
118 }
119
120 double const obj_copy_time_sec = TicksToTimeHelper::seconds(pss->trim_ticks_and_reset());
121
122 phase_times->record_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, obj_copy_time_sec);
123
124 double ext_root_time_sec = os::elapsedTime() - ext_roots_start - obj_copy_time_sec;
125
126 phase_times->record_time_secs(G1GCPhaseTimes::ExtRootScan, worker_i, ext_root_time_sec);
127
128 // During conc marking we have to filter the per-thread SATB buffers
129 // to make sure we remove any oops into the CSet (which will show up
130 // as implicitly live).
131 {
132 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SATBFiltering, worker_i);
133 if (!_process_strong_tasks.is_task_claimed(G1RP_PS_filter_satb_buffers) && _g1h->collector_state()->mark_or_rebuild_in_progress()) {
134 JavaThread::satb_mark_queue_set().filter_thread_buffers();
135 }
136 }
137
138 _process_strong_tasks.all_tasks_completed(n_workers());
139 }
140
141 // Adaptor to pass the closures to the strong roots in the VM.
142 class StrongRootsClosures : public G1RootClosures {
143 OopClosure* _roots;
144 CLDClosure* _clds;
145 CodeBlobClosure* _blobs;
146 public:
|
55 }
56
57 void G1RootProcessor::wait_until_all_strong_classes_discovered() {
58 assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
59
60 if ((uint)_n_workers_discovered_strong_classes != n_workers()) {
61 MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag);
62 while ((uint)_n_workers_discovered_strong_classes != n_workers()) {
63 _lock.wait(Mutex::_no_safepoint_check_flag, 0, false);
64 }
65 }
66 }
67
68 G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h, uint n_workers) :
69 _g1h(g1h),
70 _process_strong_tasks(G1RP_PS_NumElements),
71 _srs(n_workers),
72 _lock(Mutex::leaf, "G1 Root Scanning barrier lock", false, Monitor::_safepoint_check_never),
73 _n_workers_discovered_strong_classes(0) {}
74
75 void G1RootProcessor::evacuate_roots(G1ParScanThreadState* pss, uint worker_i) {
76 G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times();
77
78 G1EvacPhaseTimesTracker timer(phase_times, pss, G1GCPhaseTimes::ExtRootScan, worker_i);
79
80 G1EvacuationRootClosures* closures = pss->closures();
81 process_java_roots(closures, phase_times, worker_i);
82
83 // This is the point where this worker thread will not find more strong CLDs/nmethods.
84 // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing.
85 if (closures->trace_metadata()) {
86 worker_has_discovered_all_strong_classes();
87 }
88
89 process_vm_roots(closures, phase_times, worker_i);
90 process_string_table_roots(closures, phase_times, worker_i);
91
92 {
93 // Now the CM ref_processor roots.
94 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CMRefRoots, worker_i);
95 if (!_process_strong_tasks.is_task_claimed(G1RP_PS_refProcessor_oops_do)) {
96 // We need to treat the discovered reference lists of the
97 // concurrent mark ref processor as roots and keep entries
98 // (which are added by the marking threads) on them live
99 // until they can be processed at the end of marking.
100 _g1h->ref_processor_cm()->weak_oops_do(closures->strong_oops());
101 }
102 }
103
104 if (closures->trace_metadata()) {
105 {
106 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WaitForStrongCLD, worker_i);
107 // Barrier to make sure all workers passed
108 // the strong CLD and strong nmethods phases.
109 wait_until_all_strong_classes_discovered();
110 }
111
112 // Now take the complement of the strong CLDs.
113 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WeakCLDRoots, worker_i);
114 assert(closures->second_pass_weak_clds() != NULL, "Should be non-null if we are tracing metadata.");
115 ClassLoaderDataGraph::roots_cld_do(NULL, closures->second_pass_weak_clds());
116 } else {
117 phase_times->record_time_secs(G1GCPhaseTimes::WaitForStrongCLD, worker_i, 0.0);
118 phase_times->record_time_secs(G1GCPhaseTimes::WeakCLDRoots, worker_i, 0.0);
119 assert(closures->second_pass_weak_clds() == NULL, "Should be null if not tracing metadata.");
120 }
121
122 // During conc marking we have to filter the per-thread SATB buffers
123 // to make sure we remove any oops into the CSet (which will show up
124 // as implicitly live).
125 {
126 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SATBFiltering, worker_i);
127 if (!_process_strong_tasks.is_task_claimed(G1RP_PS_filter_satb_buffers) && _g1h->collector_state()->mark_or_rebuild_in_progress()) {
128 JavaThread::satb_mark_queue_set().filter_thread_buffers();
129 }
130 }
131
132 _process_strong_tasks.all_tasks_completed(n_workers());
133 }
134
135 // Adaptor to pass the closures to the strong roots in the VM.
136 class StrongRootsClosures : public G1RootClosures {
137 OopClosure* _roots;
138 CLDClosure* _clds;
139 CodeBlobClosure* _blobs;
140 public:
|