14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25
26 #include "classfile/stringTable.hpp"
27 #include "classfile/systemDictionary.hpp"
28 #include "code/codeCache.hpp"
29 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
30 #include "gc/shenandoah/shenandoahHeap.hpp"
31 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
32 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
33 #include "gc/shenandoah/shenandoahPhaseTimes.hpp"
34 #include "memory/allocation.inline.hpp"
35 #include "runtime/fprofiler.hpp"
36 #include "runtime/mutex.hpp"
37 #include "services/management.hpp"
38
39 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahHeap* heap, uint n_workers,
40 ShenandoahCollectorPolicy::TimingPhase phase) :
41 _process_strong_tasks(new SubTasksDone(SHENANDOAH_RP_PS_NumElements)),
42 _srs(n_workers),
43 _phase(phase),
44 _codecache_iterator(CodeCache::parallel_iterator()),
45 _om_iterator(ObjectSynchronizer::parallel_iterator())
46 {
47 heap->shenandoahPolicy()->record_workers_start(_phase);
48 }
49
50 ShenandoahRootProcessor::~ShenandoahRootProcessor() {
51 delete _process_strong_tasks;
52 ShenandoahHeap::heap()->shenandoahPolicy()->record_workers_end(_phase);
53 }
54
55 void ShenandoahRootProcessor::process_strong_roots(OopClosure* oops,
56 OopClosure* weak_oops,
57 CLDClosure* clds,
58 CodeBlobClosure* blobs,
59 uint worker_id) {
60
61 process_java_roots(oops, clds, NULL, blobs, worker_id);
62 process_vm_roots(oops, NULL, weak_oops, worker_id);
63
64 _process_strong_tasks->all_tasks_completed(n_workers());
65 }
66
67 void ShenandoahRootProcessor::process_all_roots(OopClosure* oops,
68 OopClosure* weak_oops,
69 CLDClosure* clds,
70 CodeBlobClosure* blobs,
71 uint worker_id) {
72
73 ShenandoahPhaseTimes* phase_times = ShenandoahHeap::heap()->shenandoahPolicy()->phase_times();
74 process_java_roots(oops, clds, clds, NULL, worker_id);
75 process_vm_roots(oops, oops, weak_oops, worker_id);
76
77 if (blobs != NULL) {
78 ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::CodeCacheRoots, worker_id);
79 _codecache_iterator.parallel_blobs_do(blobs);
80 }
81
82 _process_strong_tasks->all_tasks_completed(n_workers());
83 }
84
85 void ShenandoahRootProcessor::process_java_roots(OopClosure* strong_roots,
86 CLDClosure* strong_clds,
87 CLDClosure* weak_clds,
88 CodeBlobClosure* strong_code,
89 uint worker_id)
90 {
91 ShenandoahPhaseTimes* phase_times = ShenandoahHeap::heap()->shenandoahPolicy()->phase_times();
92 // Iterating over the CLDG and the Threads are done early to allow us to
93 // first process the strong CLDs and nmethods and then, after a barrier,
94 // let the thread process the weak CLDs and nmethods.
95 {
96 ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::CLDGRoots, worker_id);
97 _cld_iterator.root_cld_do(strong_clds, weak_clds);
98 }
99
100 {
101 ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::ThreadRoots, worker_id);
102 bool is_par = n_workers() > 1;
103 ResourceMark rm;
104 Threads::possibly_parallel_oops_do(is_par, strong_roots, strong_code);
105 }
106 }
107
108 void ShenandoahRootProcessor::process_vm_roots(OopClosure* strong_roots,
109 OopClosure* weak_roots,
110 OopClosure* jni_weak_roots,
111 uint worker_id)
112 {
113 ShenandoahPhaseTimes* phase_times = ShenandoahHeap::heap()->shenandoahPolicy()->phase_times();
114 if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_Universe_oops_do)) {
115 ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::UniverseRoots, worker_id);
116 Universe::oops_do(strong_roots);
117 }
118
119 if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_JNIHandles_oops_do)) {
120 ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::JNIRoots, worker_id);
121 JNIHandles::oops_do(strong_roots);
122 }
123
124 if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_FlatProfiler_oops_do)) {
153 while(_om_iterator.parallel_oops_do(strong_roots));
154 }
155 }
156
157 // All threads execute the following. A specific chunk of buckets
158 // from the StringTable are the individual tasks.
159 if (weak_roots != NULL) {
160 ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::StringTableRoots, worker_id);
161 StringTable::possibly_parallel_oops_do(weak_roots);
162 }
163 }
164
165 uint ShenandoahRootProcessor::n_workers() const {
166 return _srs.n_threads();
167 }
168
169 ShenandoahRootEvacuator::ShenandoahRootEvacuator(ShenandoahHeap* heap, uint n_workers, ShenandoahCollectorPolicy::TimingPhase phase) :
170 _process_strong_tasks(new SubTasksDone(SHENANDOAH_RP_PS_NumElements)),
171 _srs(n_workers),
172 _phase(phase),
173 _codecache_iterator(CodeCache::parallel_iterator())
174 {
175 heap->shenandoahPolicy()->record_workers_start(_phase);
176 }
177
178 ShenandoahRootEvacuator::~ShenandoahRootEvacuator() {
179 delete _process_strong_tasks;
180 ShenandoahHeap::heap()->shenandoahPolicy()->record_workers_end(_phase);
181 }
182
183 void ShenandoahRootEvacuator::process_evacuate_roots(OopClosure* oops,
184 CodeBlobClosure* blobs,
185 uint worker_id) {
186
187 ShenandoahPhaseTimes* phase_times = ShenandoahHeap::heap()->shenandoahPolicy()->phase_times();
188 {
189 bool is_par = n_workers() > 1;
190 ResourceMark rm;
191 ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::ThreadRoots, worker_id);
192 Threads::possibly_parallel_oops_do(is_par, oops, NULL);
193 }
194
195 {
196 ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::CodeCacheRoots, worker_id);
197 _codecache_iterator.parallel_blobs_do(blobs);
198 }
199
200 _process_strong_tasks->all_tasks_completed(n_workers());
201 }
202
203 uint ShenandoahRootEvacuator::n_workers() const {
204 return _srs.n_threads();
205 }
206
207 // Implemenation of ParallelCLDRootIterator
208 ParallelCLDRootIterator::ParallelCLDRootIterator() {
209 assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
210 ClassLoaderDataGraph::clear_claimed_marks();
211 }
212
|
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25
26 #include "classfile/stringTable.hpp"
27 #include "classfile/systemDictionary.hpp"
28 #include "code/codeCache.hpp"
29 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
30 #include "gc/shenandoah/shenandoahHeap.hpp"
31 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
32 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
33 #include "gc/shenandoah/shenandoahPhaseTimes.hpp"
34 #include "gc/shenandoah/vm_operations_shenandoah.hpp"
35 #include "memory/allocation.inline.hpp"
36 #include "runtime/fprofiler.hpp"
37 #include "runtime/mutex.hpp"
38 #include "runtime/sweeper.hpp"
39 #include "services/management.hpp"
40
41 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahHeap* heap, uint n_workers,
42 ShenandoahCollectorPolicy::TimingPhase phase) :
43 _process_strong_tasks(new SubTasksDone(SHENANDOAH_RP_PS_NumElements)),
44 _srs(n_workers),
45 _phase(phase),
46 _codecache_iterator(CodeCache::parallel_iterator()),
47 _om_iterator(ObjectSynchronizer::parallel_iterator()),
48 _threads_nmethods_cl(NULL)
49 {
50 heap->shenandoahPolicy()->record_workers_start(_phase);
51 VM_ShenandoahOperation* op = (VM_ShenandoahOperation*) VMThread::vm_operation();
52 if (! op->_safepoint_cleanup_done) {
53 _threads_nmethods_cl = NMethodSweeper::prepare_mark_active_nmethods();
54 }
55 }
56
57 ShenandoahRootProcessor::~ShenandoahRootProcessor() {
58 delete _process_strong_tasks;
59 ShenandoahHeap::heap()->shenandoahPolicy()->record_workers_end(_phase);
60 VM_ShenandoahOperation* op = (VM_ShenandoahOperation*) VMThread::vm_operation();
61 op->_safepoint_cleanup_done = true;
62 }
63
64 void ShenandoahRootProcessor::process_strong_roots(OopClosure* oops,
65 OopClosure* weak_oops,
66 CLDClosure* clds,
67 CodeBlobClosure* blobs,
68 uint worker_id) {
69
70 process_java_roots(oops, clds, NULL, NULL, _threads_nmethods_cl, worker_id);
71 process_vm_roots(oops, NULL, weak_oops, worker_id);
72
73 _process_strong_tasks->all_tasks_completed(n_workers());
74 }
75
76 void ShenandoahRootProcessor::process_all_roots(OopClosure* oops,
77 OopClosure* weak_oops,
78 CLDClosure* clds,
79 CodeBlobClosure* blobs,
80 uint worker_id) {
81
82 ShenandoahPhaseTimes* phase_times = ShenandoahHeap::heap()->shenandoahPolicy()->phase_times();
83 process_java_roots(oops, clds, clds, blobs, _threads_nmethods_cl, worker_id);
84 process_vm_roots(oops, oops, weak_oops, worker_id);
85
86 if (blobs != NULL) {
87 ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::CodeCacheRoots, worker_id);
88 _codecache_iterator.parallel_blobs_do(blobs);
89 }
90
91 _process_strong_tasks->all_tasks_completed(n_workers());
92 }
93
94 void ShenandoahRootProcessor::process_java_roots(OopClosure* strong_roots,
95 CLDClosure* strong_clds,
96 CLDClosure* weak_clds,
97 CodeBlobClosure* strong_code,
98 CodeBlobClosure* nmethods_cl,
99 uint worker_id)
100 {
101 ShenandoahPhaseTimes* phase_times = ShenandoahHeap::heap()->shenandoahPolicy()->phase_times();
102 // Iterating over the CLDG and the Threads are done early to allow us to
103 // first process the strong CLDs and nmethods and then, after a barrier,
104 // let the thread process the weak CLDs and nmethods.
105 {
106 ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::CLDGRoots, worker_id);
107 _cld_iterator.root_cld_do(strong_clds, weak_clds);
108 }
109
110 {
111 ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::ThreadRoots, worker_id);
112 bool is_par = n_workers() > 1;
113 ResourceMark rm;
114 Threads::possibly_parallel_oops_do(is_par, strong_roots, strong_code, nmethods_cl);
115 }
116 }
117
118 void ShenandoahRootProcessor::process_vm_roots(OopClosure* strong_roots,
119 OopClosure* weak_roots,
120 OopClosure* jni_weak_roots,
121 uint worker_id)
122 {
123 ShenandoahPhaseTimes* phase_times = ShenandoahHeap::heap()->shenandoahPolicy()->phase_times();
124 if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_Universe_oops_do)) {
125 ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::UniverseRoots, worker_id);
126 Universe::oops_do(strong_roots);
127 }
128
129 if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_JNIHandles_oops_do)) {
130 ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::JNIRoots, worker_id);
131 JNIHandles::oops_do(strong_roots);
132 }
133
134 if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_FlatProfiler_oops_do)) {
163 while(_om_iterator.parallel_oops_do(strong_roots));
164 }
165 }
166
167 // All threads execute the following. A specific chunk of buckets
168 // from the StringTable are the individual tasks.
169 if (weak_roots != NULL) {
170 ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::StringTableRoots, worker_id);
171 StringTable::possibly_parallel_oops_do(weak_roots);
172 }
173 }
174
175 uint ShenandoahRootProcessor::n_workers() const {
176 return _srs.n_threads();
177 }
178
179 ShenandoahRootEvacuator::ShenandoahRootEvacuator(ShenandoahHeap* heap, uint n_workers, ShenandoahCollectorPolicy::TimingPhase phase) :
180 _process_strong_tasks(new SubTasksDone(SHENANDOAH_RP_PS_NumElements)),
181 _srs(n_workers),
182 _phase(phase),
183 _codecache_iterator(CodeCache::parallel_iterator()),
184 _threads_nmethods_cl(NULL)
185 {
186 heap->shenandoahPolicy()->record_workers_start(_phase);
187 VM_ShenandoahOperation* op = (VM_ShenandoahOperation*) VMThread::vm_operation();
188 if (! op->_safepoint_cleanup_done) {
189 _threads_nmethods_cl = NMethodSweeper::prepare_mark_active_nmethods();
190 }
191 }
192
193 ShenandoahRootEvacuator::~ShenandoahRootEvacuator() {
194 delete _process_strong_tasks;
195 ShenandoahHeap::heap()->shenandoahPolicy()->record_workers_end(_phase);
196 VM_ShenandoahOperation* op = (VM_ShenandoahOperation*) VMThread::vm_operation();
197 op->_safepoint_cleanup_done = true;
198 }
199
200 void ShenandoahRootEvacuator::process_evacuate_roots(OopClosure* oops,
201 CodeBlobClosure* blobs,
202 uint worker_id) {
203
204 ShenandoahPhaseTimes* phase_times = ShenandoahHeap::heap()->shenandoahPolicy()->phase_times();
205 {
206 bool is_par = n_workers() > 1;
207 ResourceMark rm;
208 ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::ThreadRoots, worker_id);
209
210 Threads::possibly_parallel_oops_do(is_par, oops, NULL, _threads_nmethods_cl);
211 }
212
213 {
214 ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::CodeCacheRoots, worker_id);
215 _codecache_iterator.parallel_blobs_do(blobs);
216 }
217
218 _process_strong_tasks->all_tasks_completed(n_workers());
219 }
220
221 uint ShenandoahRootEvacuator::n_workers() const {
222 return _srs.n_threads();
223 }
224
225 // Implemenation of ParallelCLDRootIterator
226 ParallelCLDRootIterator::ParallelCLDRootIterator() {
227 assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
228 ClassLoaderDataGraph::clear_claimed_marks();
229 }
230
|