35 #include "memory/resourceArea.hpp" |
35 #include "memory/resourceArea.hpp" |
36 #include "prims/resolvedMethodTable.hpp" |
36 #include "prims/resolvedMethodTable.hpp" |
37 #include "runtime/safepoint.hpp" |
37 #include "runtime/safepoint.hpp" |
38 |
38 |
39 template <bool CONCURRENT> |
39 template <bool CONCURRENT> |
40 inline ShenandoahWeakRoot<CONCURRENT>::ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) : |
40 inline ShenandoahVMRoot<CONCURRENT>::ShenandoahVMRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) : |
41 _itr(storage), _phase(phase) { |
41 _itr(storage), _phase(phase) { |
42 } |
42 } |
43 |
43 |
44 template <bool CONCURRENT> |
44 template <bool CONCURRENT> |
45 template <typename Closure> |
45 template <typename Closure> |
46 inline void ShenandoahWeakRoot<CONCURRENT>::oops_do(Closure* cl, uint worker_id) { |
46 inline void ShenandoahVMRoot<CONCURRENT>::oops_do(Closure* cl, uint worker_id) { |
47 if (CONCURRENT) { |
47 if (CONCURRENT) { |
48 _itr.oops_do(cl); |
48 _itr.oops_do(cl); |
49 } else { |
49 } else { |
50 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times(); |
50 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times(); |
51 ShenandoahWorkerTimingsTracker timer(worker_times, _phase, worker_id); |
51 ShenandoahWorkerTimingsTracker timer(worker_times, _phase, worker_id); |
52 _itr.oops_do(cl); |
52 _itr.oops_do(cl); |
53 } |
53 } |
54 } |
54 } |
55 |
55 |
|
56 template <bool CONCURRENT> |
|
57 inline ShenandoahWeakRoot<CONCURRENT>::ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) : |
|
58 ShenandoahVMRoot<CONCURRENT>(storage, phase) { |
|
59 } |
|
60 |
56 inline ShenandoahWeakRoot<false>::ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) : |
61 inline ShenandoahWeakRoot<false>::ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) : |
57 _itr(storage), _phase(phase) { |
62 _itr(storage), _phase(phase) { |
58 } |
63 } |
59 |
64 |
60 template <typename IsAliveClosure, typename KeepAliveClosure> |
65 template <typename IsAliveClosure, typename KeepAliveClosure> |
101 AlwaysTrueClosure always_true; |
106 AlwaysTrueClosure always_true; |
102 weak_oops_do<AlwaysTrueClosure, Closure>(&always_true, cl, worker_id); |
107 weak_oops_do<AlwaysTrueClosure, Closure>(&always_true, cl, worker_id); |
103 } |
108 } |
104 |
109 |
105 template <bool CONCURRENT> |
110 template <bool CONCURRENT> |
106 ShenandoahJNIHandleRoots<CONCURRENT>::ShenandoahJNIHandleRoots() : |
111 ShenandoahVMRoots<CONCURRENT>::ShenandoahVMRoots() : |
107 _itr(JNIHandles::global_handles()) { |
112 _jni_handle_roots(JNIHandles::global_handles(), ShenandoahPhaseTimings::JNIRoots), |
|
113 _vm_global_roots(SystemDictionary::vm_global_oop_storage(), ShenandoahPhaseTimings::VMGlobalRoots) { |
108 } |
114 } |
109 |
115 |
110 template <bool CONCURRENT> |
116 template <bool CONCURRENT> |
111 template <typename T> |
117 template <typename T> |
112 void ShenandoahJNIHandleRoots<CONCURRENT>::oops_do(T* cl, uint worker_id) { |
118 void ShenandoahVMRoots<CONCURRENT>::oops_do(T* cl, uint worker_id) { |
113 if (CONCURRENT) { |
119 _jni_handle_roots.oops_do(cl, worker_id); |
114 _itr.oops_do(cl); |
120 _vm_global_roots.oops_do(cl, worker_id); |
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 } |
121 |
122 |
122 template <bool CONCURRENT, bool SINGLE_THREADED> |
123 template <bool CONCURRENT, bool SINGLE_THREADED> |
123 ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::ShenandoahClassLoaderDataRoots() { |
124 ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::ShenandoahClassLoaderDataRoots() { |
124 if (!SINGLE_THREADED) { |
125 if (!SINGLE_THREADED) { |
229 "Expect class unloading or traversal when Shenandoah cycle is running"); |
230 "Expect class unloading or traversal when Shenandoah cycle is running"); |
230 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc); |
231 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc); |
231 ResourceMark rm; |
232 ResourceMark rm; |
232 |
233 |
233 _serial_roots.oops_do(oops, worker_id); |
234 _serial_roots.oops_do(oops, worker_id); |
234 _jni_roots.oops_do(oops, worker_id); |
235 _vm_roots.oops_do(oops, worker_id); |
235 |
236 |
236 if (clds != NULL) { |
237 if (clds != NULL) { |
237 _cld_roots.cld_do(clds, worker_id); |
238 _cld_roots.cld_do(clds, worker_id); |
238 } else { |
239 } else { |
239 assert(ShenandoahHeap::heap()->is_concurrent_traversal_in_progress(), "Only possible with traversal GC"); |
240 assert(ShenandoahHeap::heap()->is_concurrent_traversal_in_progress(), "Only possible with traversal GC"); |
254 assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading"); |
255 assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading"); |
255 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc); |
256 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc); |
256 ResourceMark rm; |
257 ResourceMark rm; |
257 |
258 |
258 _serial_roots.oops_do(oops, worker_id); |
259 _serial_roots.oops_do(oops, worker_id); |
259 _jni_roots.oops_do(oops, worker_id); |
260 _vm_roots.oops_do(oops, worker_id); |
260 _cld_roots.always_strong_cld_do(clds, worker_id); |
261 _cld_roots.always_strong_cld_do(clds, worker_id); |
261 _thread_roots.threads_do(&tc_cl, worker_id); |
262 _thread_roots.threads_do(&tc_cl, worker_id); |
262 } |
263 } |
263 |
264 |
264 template <typename IsAlive, typename KeepAlive> |
265 template <typename IsAlive, typename KeepAlive> |
265 void ShenandoahRootUpdater::roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive) { |
266 void ShenandoahRootUpdater::roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive) { |
266 CodeBlobToOopClosure update_blobs(keep_alive, CodeBlobToOopClosure::FixRelocations); |
267 CodeBlobToOopClosure update_blobs(keep_alive, CodeBlobToOopClosure::FixRelocations); |
267 CLDToOopClosure clds(keep_alive, ClassLoaderData::_claim_strong); |
268 CLDToOopClosure clds(keep_alive, ClassLoaderData::_claim_strong); |
268 |
269 |
269 _serial_roots.oops_do(keep_alive, worker_id); |
270 _serial_roots.oops_do(keep_alive, worker_id); |
270 _jni_roots.oops_do(keep_alive, worker_id); |
271 _vm_roots.oops_do(keep_alive, worker_id); |
271 |
272 |
272 _thread_roots.oops_do(keep_alive, NULL, worker_id); |
273 _thread_roots.oops_do(keep_alive, NULL, worker_id); |
273 _cld_roots.cld_do(&clds, worker_id); |
274 _cld_roots.cld_do(&clds, worker_id); |
274 |
275 |
275 if(_update_code_cache) { |
276 if(_update_code_cache) { |