20 * questions.
21 *
22 */
23
24 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
25 #define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
26
27 #include "classfile/classLoaderDataGraph.hpp"
28 #include "classfile/stringTable.hpp"
29 #include "classfile/systemDictionary.hpp"
30 #include "gc/shared/oopStorageParState.inline.hpp"
31 #include "gc/shenandoah/shenandoahHeuristics.hpp"
32 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
33 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
34 #include "gc/shenandoah/shenandoahUtils.hpp"
35 #include "memory/resourceArea.hpp"
36 #include "prims/resolvedMethodTable.hpp"
37 #include "runtime/safepoint.hpp"
38
39 template <bool CONCURRENT>
40 inline ShenandoahWeakRoot<CONCURRENT>::ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) :
41 _itr(storage), _phase(phase) {
42 }
43
44 template <bool CONCURRENT>
45 template <typename Closure>
46 inline void ShenandoahWeakRoot<CONCURRENT>::oops_do(Closure* cl, uint worker_id) {
47 if (CONCURRENT) {
48 _itr.oops_do(cl);
49 } else {
50 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
51 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ThreadRoots, worker_id);
52 _itr.oops_do(cl);
53 }
54 }
55
56 inline ShenandoahWeakRoot<false>::ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) :
57 _itr(storage), _phase(phase) {
58 }
59
60 template <typename IsAliveClosure, typename KeepAliveClosure>
61 void ShenandoahWeakRoot<false /* concurrent */>::weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id) {
62 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
63 ShenandoahWorkerTimingsTracker timer(worker_times, _phase, worker_id);
64 _itr.weak_oops_do(is_alive, keep_alive);
65 }
66
67 template <bool CONCURRENT>
68 ShenandoahWeakRoots<CONCURRENT>::ShenandoahWeakRoots() :
69 _jni_roots(JNIHandles::weak_global_handles(), ShenandoahPhaseTimings::JNIWeakRoots),
70 _string_table_roots(StringTable::weak_storage(), ShenandoahPhaseTimings::StringTableRoots),
71 _resolved_method_table_roots(ResolvedMethodTable::weak_storage(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
72 _vm_roots(SystemDictionary::vm_weak_oop_storage(), ShenandoahPhaseTimings::VMWeakRoots) {
73 }
74
75 template <bool CONCURRENT>
86 _string_table_roots(StringTable::weak_storage(), ShenandoahPhaseTimings::StringTableRoots),
87 _resolved_method_table_roots(ResolvedMethodTable::weak_storage(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
88 _vm_roots(SystemDictionary::vm_weak_oop_storage(), ShenandoahPhaseTimings::VMWeakRoots) {
89 }
90
91 template <typename IsAliveClosure, typename KeepAliveClosure>
92 void ShenandoahWeakRoots<false /* concurrent*/>::weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id) {
93 _jni_roots.weak_oops_do(is_alive, keep_alive, worker_id);
94 _string_table_roots.weak_oops_do(is_alive, keep_alive, worker_id);
95 _resolved_method_table_roots.weak_oops_do(is_alive, keep_alive, worker_id);
96 _vm_roots.weak_oops_do(is_alive, keep_alive, worker_id);
97 }
98
99 template <typename Closure>
100 void ShenandoahWeakRoots<false /* concurrent */>::oops_do(Closure* cl, uint worker_id) {
101 AlwaysTrueClosure always_true;
102 weak_oops_do<AlwaysTrueClosure, Closure>(&always_true, cl, worker_id);
103 }
104
105 template <bool CONCURRENT>
106 ShenandoahJNIHandleRoots<CONCURRENT>::ShenandoahJNIHandleRoots() :
107 _itr(JNIHandles::global_handles()) {
108 }
109
110 template <bool CONCURRENT>
111 template <typename T>
112 void ShenandoahJNIHandleRoots<CONCURRENT>::oops_do(T* cl, uint worker_id) {
113 if (CONCURRENT) {
114 _itr.oops_do(cl);
115 } else {
116 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
117 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id);
118 _itr.oops_do(cl);
119 }
120 }
121
122 template <bool CONCURRENT, bool SINGLE_THREADED>
123 ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::ShenandoahClassLoaderDataRoots() {
124 if (!SINGLE_THREADED) {
125 ClassLoaderDataGraph::clear_claimed_marks();
126 }
127 if (CONCURRENT) {
128 ClassLoaderDataGraph_lock->lock();
129 }
130 }
131
132 template <bool CONCURRENT, bool SINGLE_THREADED>
133 ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::~ShenandoahClassLoaderDataRoots() {
134 if (CONCURRENT) {
135 ClassLoaderDataGraph_lock->unlock();
136 }
137 }
138
139
214 roots_do(worker_id, oops, &clds_cl, &blobs_cl);
215 }
216
217 template <typename ITR>
218 void ShenandoahRootScanner<ITR>::strong_roots_do(uint worker_id, OopClosure* oops) {
219 CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
220 MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
221 strong_roots_do(worker_id, oops, &clds_cl, &blobs_cl);
222 }
223
224 template <typename ITR>
225 void ShenandoahRootScanner<ITR>::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
226 assert(!ShenandoahSafepoint::is_at_shenandoah_safepoint() ||
227 !ShenandoahHeap::heap()->unload_classes() ||
228 ShenandoahHeap::heap()->is_traversal_mode(),
229 "Expect class unloading or traversal when Shenandoah cycle is running");
230 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
231 ResourceMark rm;
232
233 _serial_roots.oops_do(oops, worker_id);
234 _jni_roots.oops_do(oops, worker_id);
235
236 if (clds != NULL) {
237 _cld_roots.cld_do(clds, worker_id);
238 } else {
239 assert(ShenandoahHeap::heap()->is_concurrent_traversal_in_progress(), "Only possible with traversal GC");
240 }
241
242 _thread_roots.threads_do(&tc_cl, worker_id);
243
244 // With ShenandoahConcurrentScanCodeRoots, we avoid scanning the entire code cache here,
245 // and instead do that in concurrent phase under the relevant lock. This saves init mark
246 // pause time.
247 if (code != NULL && !ShenandoahConcurrentScanCodeRoots) {
248 _code_roots.code_blobs_do(code, worker_id);
249 }
250 }
251
252 template <typename ITR>
253 void ShenandoahRootScanner<ITR>::strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc) {
254 assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading");
255 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
256 ResourceMark rm;
257
258 _serial_roots.oops_do(oops, worker_id);
259 _jni_roots.oops_do(oops, worker_id);
260 _cld_roots.always_strong_cld_do(clds, worker_id);
261 _thread_roots.threads_do(&tc_cl, worker_id);
262 }
263
264 template <typename IsAlive, typename KeepAlive>
265 void ShenandoahRootUpdater::roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive) {
266 CodeBlobToOopClosure update_blobs(keep_alive, CodeBlobToOopClosure::FixRelocations);
267 CLDToOopClosure clds(keep_alive, ClassLoaderData::_claim_strong);
268
269 _serial_roots.oops_do(keep_alive, worker_id);
270 _jni_roots.oops_do(keep_alive, worker_id);
271
272 _thread_roots.oops_do(keep_alive, NULL, worker_id);
273 _cld_roots.cld_do(&clds, worker_id);
274
275 if(_update_code_cache) {
276 _code_roots.code_blobs_do(&update_blobs, worker_id);
277 }
278
279 _serial_weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);
280 _weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);
281 _dedup_roots.oops_do(is_alive, keep_alive, worker_id);
282 }
283
284 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
|
20 * questions.
21 *
22 */
23
24 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
25 #define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
26
27 #include "classfile/classLoaderDataGraph.hpp"
28 #include "classfile/stringTable.hpp"
29 #include "classfile/systemDictionary.hpp"
30 #include "gc/shared/oopStorageParState.inline.hpp"
31 #include "gc/shenandoah/shenandoahHeuristics.hpp"
32 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
33 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
34 #include "gc/shenandoah/shenandoahUtils.hpp"
35 #include "memory/resourceArea.hpp"
36 #include "prims/resolvedMethodTable.hpp"
37 #include "runtime/safepoint.hpp"
38
39 template <bool CONCURRENT>
40 inline ShenandoahVMRoot<CONCURRENT>::ShenandoahVMRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) :
41 _itr(storage), _phase(phase) {
42 }
43
44 template <bool CONCURRENT>
45 template <typename Closure>
46 inline void ShenandoahVMRoot<CONCURRENT>::oops_do(Closure* cl, uint worker_id) {
47 if (CONCURRENT) {
48 _itr.oops_do(cl);
49 } else {
50 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
51 ShenandoahWorkerTimingsTracker timer(worker_times, _phase, worker_id);
52 _itr.oops_do(cl);
53 }
54 }
55
56 template <bool CONCURRENT>
57 inline ShenandoahWeakRoot<CONCURRENT>::ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) :
58 ShenandoahVMRoot<CONCURRENT>(storage, phase) {
59 }
60
61 inline ShenandoahWeakRoot<false>::ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) :
62 _itr(storage), _phase(phase) {
63 }
64
65 template <typename IsAliveClosure, typename KeepAliveClosure>
66 void ShenandoahWeakRoot<false /* concurrent */>::weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id) {
67 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
68 ShenandoahWorkerTimingsTracker timer(worker_times, _phase, worker_id);
69 _itr.weak_oops_do(is_alive, keep_alive);
70 }
71
72 template <bool CONCURRENT>
73 ShenandoahWeakRoots<CONCURRENT>::ShenandoahWeakRoots() :
74 _jni_roots(JNIHandles::weak_global_handles(), ShenandoahPhaseTimings::JNIWeakRoots),
75 _string_table_roots(StringTable::weak_storage(), ShenandoahPhaseTimings::StringTableRoots),
76 _resolved_method_table_roots(ResolvedMethodTable::weak_storage(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
77 _vm_roots(SystemDictionary::vm_weak_oop_storage(), ShenandoahPhaseTimings::VMWeakRoots) {
78 }
79
80 template <bool CONCURRENT>
91 _string_table_roots(StringTable::weak_storage(), ShenandoahPhaseTimings::StringTableRoots),
92 _resolved_method_table_roots(ResolvedMethodTable::weak_storage(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
93 _vm_roots(SystemDictionary::vm_weak_oop_storage(), ShenandoahPhaseTimings::VMWeakRoots) {
94 }
95
96 template <typename IsAliveClosure, typename KeepAliveClosure>
97 void ShenandoahWeakRoots<false /* concurrent*/>::weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id) {
98 _jni_roots.weak_oops_do(is_alive, keep_alive, worker_id);
99 _string_table_roots.weak_oops_do(is_alive, keep_alive, worker_id);
100 _resolved_method_table_roots.weak_oops_do(is_alive, keep_alive, worker_id);
101 _vm_roots.weak_oops_do(is_alive, keep_alive, worker_id);
102 }
103
104 template <typename Closure>
105 void ShenandoahWeakRoots<false /* concurrent */>::oops_do(Closure* cl, uint worker_id) {
106 AlwaysTrueClosure always_true;
107 weak_oops_do<AlwaysTrueClosure, Closure>(&always_true, cl, worker_id);
108 }
109
110 template <bool CONCURRENT>
111 ShenandoahVMRoots<CONCURRENT>::ShenandoahVMRoots() :
112 _jni_handle_roots(JNIHandles::global_handles(), ShenandoahPhaseTimings::JNIRoots),
113 _vm_global_roots(SystemDictionary::vm_global_oop_storage(), ShenandoahPhaseTimings::VMGlobalRoots) {
114 }
115
116 template <bool CONCURRENT>
117 template <typename T>
118 void ShenandoahVMRoots<CONCURRENT>::oops_do(T* cl, uint worker_id) {
119 _jni_handle_roots.oops_do(cl, worker_id);
120 _vm_global_roots.oops_do(cl, worker_id);
121 }
122
123 template <bool CONCURRENT, bool SINGLE_THREADED>
124 ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::ShenandoahClassLoaderDataRoots() {
125 if (!SINGLE_THREADED) {
126 ClassLoaderDataGraph::clear_claimed_marks();
127 }
128 if (CONCURRENT) {
129 ClassLoaderDataGraph_lock->lock();
130 }
131 }
132
133 template <bool CONCURRENT, bool SINGLE_THREADED>
134 ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::~ShenandoahClassLoaderDataRoots() {
135 if (CONCURRENT) {
136 ClassLoaderDataGraph_lock->unlock();
137 }
138 }
139
140
215 roots_do(worker_id, oops, &clds_cl, &blobs_cl);
216 }
217
218 template <typename ITR>
219 void ShenandoahRootScanner<ITR>::strong_roots_do(uint worker_id, OopClosure* oops) {
220 CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
221 MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
222 strong_roots_do(worker_id, oops, &clds_cl, &blobs_cl);
223 }
224
225 template <typename ITR>
226 void ShenandoahRootScanner<ITR>::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
227 assert(!ShenandoahSafepoint::is_at_shenandoah_safepoint() ||
228 !ShenandoahHeap::heap()->unload_classes() ||
229 ShenandoahHeap::heap()->is_traversal_mode(),
230 "Expect class unloading or traversal when Shenandoah cycle is running");
231 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
232 ResourceMark rm;
233
234 _serial_roots.oops_do(oops, worker_id);
235 _vm_roots.oops_do(oops, worker_id);
236
237 if (clds != NULL) {
238 _cld_roots.cld_do(clds, worker_id);
239 } else {
240 assert(ShenandoahHeap::heap()->is_concurrent_traversal_in_progress(), "Only possible with traversal GC");
241 }
242
243 _thread_roots.threads_do(&tc_cl, worker_id);
244
245 // With ShenandoahConcurrentScanCodeRoots, we avoid scanning the entire code cache here,
246 // and instead do that in concurrent phase under the relevant lock. This saves init mark
247 // pause time.
248 if (code != NULL && !ShenandoahConcurrentScanCodeRoots) {
249 _code_roots.code_blobs_do(code, worker_id);
250 }
251 }
252
253 template <typename ITR>
254 void ShenandoahRootScanner<ITR>::strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc) {
255 assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading");
256 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
257 ResourceMark rm;
258
259 _serial_roots.oops_do(oops, worker_id);
260 _vm_roots.oops_do(oops, worker_id);
261 _cld_roots.always_strong_cld_do(clds, worker_id);
262 _thread_roots.threads_do(&tc_cl, worker_id);
263 }
264
265 template <typename IsAlive, typename KeepAlive>
266 void ShenandoahRootUpdater::roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive) {
267 CodeBlobToOopClosure update_blobs(keep_alive, CodeBlobToOopClosure::FixRelocations);
268 CLDToOopClosure clds(keep_alive, ClassLoaderData::_claim_strong);
269
270 _serial_roots.oops_do(keep_alive, worker_id);
271 _vm_roots.oops_do(keep_alive, worker_id);
272
273 _thread_roots.oops_do(keep_alive, NULL, worker_id);
274 _cld_roots.cld_do(&clds, worker_id);
275
276 if(_update_code_cache) {
277 _code_roots.code_blobs_do(&update_blobs, worker_id);
278 }
279
280 _serial_weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);
281 _weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);
282 _dedup_roots.oops_do(is_alive, keep_alive, worker_id);
283 }
284
285 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
|