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 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
25 #define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
26
27 #include "classfile/classLoaderDataGraph.hpp"
28 #include "gc/shared/oopStorageParState.inline.hpp"
29 #include "gc/shenandoah/shenandoahHeuristics.hpp"
30 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
31 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
32 #include "gc/shenandoah/shenandoahUtils.hpp"
33 #include "memory/resourceArea.hpp"
34
35 template <bool CONCURRENT>
36 ShenandoahJNIHandleRoots<CONCURRENT>::ShenandoahJNIHandleRoots() :
37 _itr(JNIHandles::global_handles()) {
38 }
39
40 template <bool CONCURRENT>
41 template <typename T>
42 void ShenandoahJNIHandleRoots<CONCURRENT>::oops_do(T* cl, uint worker_id) {
43 if (CONCURRENT) {
44 _itr.oops_do(cl);
45 } else {
46 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
47 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id);
48 _itr.oops_do(cl);
49 }
50 }
51
52 template <typename IsAlive, typename KeepAlive>
53 void ShenandoahWeakRoots::oops_do(IsAlive* is_alive, KeepAlive* keep_alive, uint worker_id) {
54 _task.work<IsAlive, KeepAlive>(worker_id, is_alive, keep_alive);
55 }
56
57 template <typename ITR>
58 ShenandoahCodeCacheRoots<ITR>::ShenandoahCodeCacheRoots() {
59 nmethod::oops_do_marking_prologue();
60 }
61
62 template <typename ITR>
63 void ShenandoahCodeCacheRoots<ITR>::code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id) {
64 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
65 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CodeCacheRoots, worker_id);
66 _coderoots_iterator.possibly_parallel_blobs_do(blob_cl);
67 }
68
69 template <typename ITR>
70 ShenandoahCodeCacheRoots<ITR>::~ShenandoahCodeCacheRoots() {
71 nmethod::oops_do_marking_epilogue();
72 }
73
74 class ShenandoahParallelOopsDoThreadClosure : public ThreadClosure {
75 private:
76 OopClosure* _f;
111 template <typename ITR>
112 void ShenandoahRootScanner<ITR>::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
113 assert(!ShenandoahSafepoint::is_at_shenandoah_safepoint() ||
114 !ShenandoahHeap::heap()->unload_classes() ||
115 ShenandoahHeap::heap()->heuristics()->can_do_traversal_gc(),
116 "Expect class unloading or traversal when Shenandoah cycle is running");
117 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
118 ResourceMark rm;
119
120 _serial_roots.oops_do(oops, worker_id);
121 _jni_roots.oops_do(oops, worker_id);
122 _cld_roots.clds_do(clds, clds, worker_id);
123 _thread_roots.threads_do(&tc_cl, worker_id);
124
125 // With ShenandoahConcurrentScanCodeRoots, we avoid scanning the entire code cache here,
126 // and instead do that in concurrent phase under the relevant lock. This saves init mark
127 // pause time.
128 if (code != NULL && !ShenandoahConcurrentScanCodeRoots) {
129 _code_roots.code_blobs_do(code, worker_id);
130 }
131 }
132
133 template <typename ITR>
134 void ShenandoahRootScanner<ITR>::roots_do_unchecked(OopClosure* oops) {
135 CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
136 MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations);
137 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL);
138 ResourceMark rm;
139
140 _serial_roots.oops_do(oops, 0);
141 _jni_roots.oops_do(oops, 0);
142 _cld_roots.clds_do(&clds, &clds, 0);
143 _thread_roots.threads_do(&tc_cl, 0);
144 _code_roots.code_blobs_do(&code, 0);
145 }
146
147 template <typename ITR>
148 void ShenandoahRootScanner<ITR>::strong_roots_do_unchecked(OopClosure* oops) {
149 CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
150 MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations);
151 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL);
152 ResourceMark rm;
153
154 _serial_roots.oops_do(oops, 0);
155 _jni_roots.oops_do(oops, 0);
156 _cld_roots.clds_do(&clds, NULL, 0);
157 _thread_roots.threads_do(&tc_cl, 0);
158 }
159
160 template <typename ITR>
161 void ShenandoahRootScanner<ITR>::strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc) {
162 assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading");
163 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
164 ResourceMark rm;
165
166 _serial_roots.oops_do(oops, worker_id);
167 _jni_roots.oops_do(oops, worker_id);
168 _cld_roots.clds_do(clds, NULL, worker_id);
169 _thread_roots.threads_do(&tc_cl, worker_id);
170 }
171
172 template <typename IsAlive, typename KeepAlive>
173 void ShenandoahRootUpdater::roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive) {
174 CodeBlobToOopClosure update_blobs(keep_alive, CodeBlobToOopClosure::FixRelocations);
175 CLDToOopClosure clds(keep_alive, ClassLoaderData::_claim_strong);
176 CLDToOopClosure* weak_clds = ShenandoahHeap::heap()->unload_classes() ? NULL : &clds;
177
|
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 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
25 #define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
26
27 #include "classfile/classLoaderDataGraph.hpp"
28 #include "gc/shared/oopStorageParState.inline.hpp"
29 #include "gc/shenandoah/shenandoahHeuristics.hpp"
30 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
31 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
32 #include "gc/shenandoah/shenandoahUtils.hpp"
33 #include "memory/resourceArea.hpp"
34 #include "runtime/safepoint.hpp"
35
36 template <bool CONCURRENT>
37 ShenandoahJNIHandleRoots<CONCURRENT>::ShenandoahJNIHandleRoots() :
38 _itr(JNIHandles::global_handles()) {
39 }
40
41 template <bool CONCURRENT>
42 template <typename T>
43 void ShenandoahJNIHandleRoots<CONCURRENT>::oops_do(T* cl, uint worker_id) {
44 if (CONCURRENT) {
45 _itr.oops_do(cl);
46 } else {
47 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
48 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id);
49 _itr.oops_do(cl);
50 }
51 }
52
53 template <typename IsAlive, typename KeepAlive>
54 void ShenandoahWeakRoots::oops_do(IsAlive* is_alive, KeepAlive* keep_alive, uint worker_id) {
55 _task.work<IsAlive, KeepAlive>(worker_id, is_alive, keep_alive);
56 }
57
58 template <bool SINGLE_THREADED>
59 ShenandoahClassLoaderDataRoots<SINGLE_THREADED>::ShenandoahClassLoaderDataRoots() {
60 if (!SINGLE_THREADED) {
61 ClassLoaderDataGraph::clear_claimed_marks();
62 }
63 }
64
65 template <bool SINGLE_THREADED>
66 void ShenandoahClassLoaderDataRoots<SINGLE_THREADED>::clds_do(CLDClosure* strong_clds, CLDClosure* weak_clds, uint worker_id) {
67 if (SINGLE_THREADED) {
68 assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
69 assert(Thread::current()->is_VM_thread(), "Single threaded CLDG iteration can only be done by VM thread");
70
71 ClassLoaderDataGraph::roots_cld_do(strong_clds, weak_clds);
72 } else {
73 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
74 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
75 ClassLoaderDataGraph::roots_cld_do(strong_clds, weak_clds);
76 }
77 }
78
79 template <typename ITR>
80 ShenandoahCodeCacheRoots<ITR>::ShenandoahCodeCacheRoots() {
81 nmethod::oops_do_marking_prologue();
82 }
83
84 template <typename ITR>
85 void ShenandoahCodeCacheRoots<ITR>::code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id) {
86 ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
87 ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CodeCacheRoots, worker_id);
88 _coderoots_iterator.possibly_parallel_blobs_do(blob_cl);
89 }
90
91 template <typename ITR>
92 ShenandoahCodeCacheRoots<ITR>::~ShenandoahCodeCacheRoots() {
93 nmethod::oops_do_marking_epilogue();
94 }
95
96 class ShenandoahParallelOopsDoThreadClosure : public ThreadClosure {
97 private:
98 OopClosure* _f;
133 template <typename ITR>
134 void ShenandoahRootScanner<ITR>::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
135 assert(!ShenandoahSafepoint::is_at_shenandoah_safepoint() ||
136 !ShenandoahHeap::heap()->unload_classes() ||
137 ShenandoahHeap::heap()->heuristics()->can_do_traversal_gc(),
138 "Expect class unloading or traversal when Shenandoah cycle is running");
139 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
140 ResourceMark rm;
141
142 _serial_roots.oops_do(oops, worker_id);
143 _jni_roots.oops_do(oops, worker_id);
144 _cld_roots.clds_do(clds, clds, worker_id);
145 _thread_roots.threads_do(&tc_cl, worker_id);
146
147 // With ShenandoahConcurrentScanCodeRoots, we avoid scanning the entire code cache here,
148 // and instead do that in concurrent phase under the relevant lock. This saves init mark
149 // pause time.
150 if (code != NULL && !ShenandoahConcurrentScanCodeRoots) {
151 _code_roots.code_blobs_do(code, worker_id);
152 }
153 }
154
155 template <typename ITR>
156 void ShenandoahRootScanner<ITR>::strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc) {
157 assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading");
158 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
159 ResourceMark rm;
160
161 _serial_roots.oops_do(oops, worker_id);
162 _jni_roots.oops_do(oops, worker_id);
163 _cld_roots.clds_do(clds, NULL, worker_id);
164 _thread_roots.threads_do(&tc_cl, worker_id);
165 }
166
167 template <typename IsAlive, typename KeepAlive>
168 void ShenandoahRootUpdater::roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive) {
169 CodeBlobToOopClosure update_blobs(keep_alive, CodeBlobToOopClosure::FixRelocations);
170 CLDToOopClosure clds(keep_alive, ClassLoaderData::_claim_strong);
171 CLDToOopClosure* weak_clds = ShenandoahHeap::heap()->unload_classes() ? NULL : &clds;
172
|