1 /*
2 * Copyright (c) 2015, 2020, Red Hat, Inc. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP
26 #define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP
27
28 #include "code/codeCache.hpp"
29 #include "gc/shared/oopStorageParState.hpp"
30 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
31 #include "gc/shenandoah/shenandoahHeap.hpp"
32 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
33 #include "gc/shenandoah/shenandoahSharedVariables.hpp"
34 #include "memory/iterator.hpp"
35
36 class ShenandoahSerialRoot {
37 public:
38 typedef void (*OopsDo)(OopClosure*);
39 private:
40 ShenandoahSharedFlag _claimed;
41 const OopsDo _oops_do;
42 const ShenandoahPhaseTimings::GCParPhases _phase;
43
44 public:
45 ShenandoahSerialRoot(OopsDo oops_do, ShenandoahPhaseTimings::GCParPhases);
46 void oops_do(OopClosure* cl, uint worker_id);
47 };
48
49 class ShenandoahSerialRoots {
50 private:
51 ShenandoahSerialRoot _universe_root;
52 ShenandoahSerialRoot _object_synchronizer_root;
53 ShenandoahSerialRoot _management_root;
54 ShenandoahSerialRoot _system_dictionary_root;
55 ShenandoahSerialRoot _jvmti_root;
56 public:
57 ShenandoahSerialRoots();
58 void oops_do(OopClosure* cl, uint worker_id);
59 };
60
61 class ShenandoahWeakSerialRoot {
62 typedef void (*WeakOopsDo)(BoolObjectClosure*, OopClosure*);
63 private:
64 ShenandoahSharedFlag _claimed;
65 const WeakOopsDo _weak_oops_do;
66 const ShenandoahPhaseTimings::GCParPhases _phase;
67
68 public:
69 ShenandoahWeakSerialRoot(WeakOopsDo oops_do, ShenandoahPhaseTimings::GCParPhases);
70 void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id);
71 };
72
73 #if INCLUDE_JVMTI
74 class ShenandoahJVMTIWeakRoot : public ShenandoahWeakSerialRoot {
75 public:
76 ShenandoahJVMTIWeakRoot();
77 };
78 #endif // INCLUDE_JVMTI
79
80 #if INCLUDE_JFR
81 class ShenandoahJFRWeakRoot : public ShenandoahWeakSerialRoot {
82 public:
83 ShenandoahJFRWeakRoot();
84 };
85 #endif // INCLUDE_JFR
86
87 #if INCLUDE_TSAN
88 class ShenandoahTSANWeakRoot : public ShenandoahWeakSerialRoot {
89 public:
90 ShenandoahTSANWeakRoot();
91 };
92 #endif // INCLUDE_TSAN
93
94 class ShenandoahSerialWeakRoots {
95 private:
96 JVMTI_ONLY(ShenandoahJVMTIWeakRoot _jvmti_weak_roots;)
97 JFR_ONLY(ShenandoahJFRWeakRoot _jfr_weak_roots;)
98 TSAN_ONLY(ShenandoahTSANWeakRoot _tsan_weak_roots;)
99 public:
100 void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id);
101 void weak_oops_do(OopClosure* cl, uint worker_id);
102 };
103
104 template <bool CONCURRENT>
105 class ShenandoahVMRoot {
106 private:
107 OopStorage::ParState<CONCURRENT, false /* is_const */> _itr;
108 const ShenandoahPhaseTimings::GCParPhases _phase;
109 public:
110 ShenandoahVMRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase);
111
112 template <typename Closure>
113 void oops_do(Closure* cl, uint worker_id);
114 };
115
116 template <bool CONCURRENT>
117 class ShenandoahWeakRoot : public ShenandoahVMRoot<CONCURRENT> {
118 public:
119 ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase);
120 };
121
122 template <>
123 class ShenandoahWeakRoot<false /*concurrent*/> {
124 private:
125 OopStorage::ParState<false /*concurrent*/, false /*is_const*/> _itr;
126 const ShenandoahPhaseTimings::GCParPhases _phase;
127
128 public:
129 ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase);
130
131 template <typename IsAliveClosure, typename KeepAliveClosure>
132 void weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id);
133 };
134
135 template <bool CONCURRENT>
136 class ShenandoahWeakRoots {
137 private:
138 ShenandoahWeakRoot<CONCURRENT> _jni_roots;
139 ShenandoahWeakRoot<CONCURRENT> _string_table_roots;
140 ShenandoahWeakRoot<CONCURRENT> _resolved_method_table_roots;
141 ShenandoahWeakRoot<CONCURRENT> _vm_roots;
142
143 public:
144 ShenandoahWeakRoots();
145
146 template <typename Closure>
147 void oops_do(Closure* cl, uint worker_id = 0);
148 };
149
150 template <>
151 class ShenandoahWeakRoots<false /*concurrent */> {
152 private:
153 ShenandoahWeakRoot<false /*concurrent*/> _jni_roots;
154 ShenandoahWeakRoot<false /*concurrent*/> _string_table_roots;
155 ShenandoahWeakRoot<false /*concurrent*/> _resolved_method_table_roots;
156 ShenandoahWeakRoot<false /*concurrent*/> _vm_roots;
157 public:
158 ShenandoahWeakRoots();
159
160 template <typename Closure>
161 void oops_do(Closure* cl, uint worker_id = 0);
162
163 template <typename IsAliveClosure, typename KeepAliveClosure>
164 void weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id);
165 };
166
167 template <bool CONCURRENT>
168 class ShenandoahVMRoots {
169 private:
170 ShenandoahVMRoot<CONCURRENT> _jni_handle_roots;
171 ShenandoahVMRoot<CONCURRENT> _vm_global_roots;
172
173 public:
174 ShenandoahVMRoots();
175
176 template <typename T>
177 void oops_do(T* cl, uint worker_id = 0);
178 };
179
180 class ShenandoahThreadRoots {
181 private:
182 const bool _is_par;
183 public:
184 ShenandoahThreadRoots(bool is_par);
185 ~ShenandoahThreadRoots();
186
187 void oops_do(OopClosure* oops_cl, CodeBlobClosure* code_cl, uint worker_id);
188 void threads_do(ThreadClosure* tc, uint worker_id);
189 };
190
191 class ShenandoahStringDedupRoots {
192 public:
193 ShenandoahStringDedupRoots();
194 ~ShenandoahStringDedupRoots();
195
196 void oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id);
197 };
198
199 class ShenandoahConcurrentStringDedupRoots {
200 public:
201 ShenandoahConcurrentStringDedupRoots();
202 ~ShenandoahConcurrentStringDedupRoots();
203
204 void oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id);
205 };
206
207 template <typename ITR>
208 class ShenandoahCodeCacheRoots {
209 private:
210 ITR _coderoots_iterator;
211 public:
212 ShenandoahCodeCacheRoots();
213 ~ShenandoahCodeCacheRoots();
214
215 void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id);
216 };
217
218 template <bool CONCURRENT, bool SINGLE_THREADED>
219 class ShenandoahClassLoaderDataRoots {
220 public:
221 ShenandoahClassLoaderDataRoots();
222 ~ShenandoahClassLoaderDataRoots();
223
224 void always_strong_cld_do(CLDClosure* clds, uint worker_id = 0);
225 void cld_do(CLDClosure* clds, uint worker_id = 0);
226 };
227
228 class ShenandoahRootProcessor : public StackObj {
229 private:
230 ShenandoahHeap* const _heap;
231 const ShenandoahPhaseTimings::Phase _phase;
232 public:
233 ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase);
234 ~ShenandoahRootProcessor();
235
236 ShenandoahHeap* heap() const { return _heap; }
237 };
238
239 template <typename ITR>
240 class ShenandoahRootScanner : public ShenandoahRootProcessor {
241 private:
242 ShenandoahSerialRoots _serial_roots;
243 ShenandoahThreadRoots _thread_roots;
244 ShenandoahCodeCacheRoots<ITR> _code_roots;
245 ShenandoahVMRoots<false /*concurrent*/ > _vm_roots;
246 ShenandoahStringDedupRoots _dedup_roots;
247 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
248 _cld_roots;
249 public:
250 ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase);
251
252 // Apply oops, clds and blobs to all strongly reachable roots in the system,
253 // during class unloading cycle
254 void strong_roots_do(uint worker_id, OopClosure* cl);
255 void strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL);
256
257 // Apply oops, clds and blobs to all strongly reachable roots and weakly reachable
258 // roots when class unloading is disabled during this cycle
259 void roots_do(uint worker_id, OopClosure* cl);
260 void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL);
261 };
262
263 typedef ShenandoahRootScanner<ShenandoahAllCodeRootsIterator> ShenandoahAllRootScanner;
264 typedef ShenandoahRootScanner<ShenandoahCsetCodeRootsIterator> ShenandoahCSetRootScanner;
265
266 // This scanner is only for SH::object_iteration() and only supports single-threaded
267 // root scanning
268 class ShenandoahHeapIterationRootScanner : public ShenandoahRootProcessor {
269 private:
270 ShenandoahSerialRoots _serial_roots;
271 ShenandoahThreadRoots _thread_roots;
272 ShenandoahVMRoots<false /*concurrent*/> _vm_roots;
273 ShenandoahClassLoaderDataRoots<false /*concurrent*/, true /*single threaded*/>
274 _cld_roots;
275 ShenandoahSerialWeakRoots _serial_weak_roots;
276 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots;
277 ShenandoahConcurrentStringDedupRoots _dedup_roots;
278 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots;
279
280 public:
281 ShenandoahHeapIterationRootScanner();
282
283 void roots_do(OopClosure* cl);
284 void strong_roots_do(OopClosure* cl);
285 };
286
287 // Evacuate all roots at a safepoint
288 class ShenandoahRootEvacuator : public ShenandoahRootProcessor {
289 private:
290 ShenandoahSerialRoots _serial_roots;
291 ShenandoahVMRoots<false /*concurrent*/> _vm_roots;
292 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
293 _cld_roots;
294 ShenandoahThreadRoots _thread_roots;
295 ShenandoahSerialWeakRoots _serial_weak_roots;
296 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots;
297 ShenandoahStringDedupRoots _dedup_roots;
298 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots;
299 bool _include_concurrent_roots;
300 bool _include_concurrent_code_roots;
301 public:
302 ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase,
303 bool include_concurrent_roots, bool _include_concurrent_code_roots);
304
305 void roots_do(uint worker_id, OopClosure* oops);
306 };
307
308 // Update all roots at a safepoint
309 class ShenandoahRootUpdater : public ShenandoahRootProcessor {
310 private:
311 ShenandoahSerialRoots _serial_roots;
312 ShenandoahVMRoots<false /*concurrent*/> _vm_roots;
313 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
314 _cld_roots;
315 ShenandoahThreadRoots _thread_roots;
316 ShenandoahSerialWeakRoots _serial_weak_roots;
317 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots;
318 ShenandoahStringDedupRoots _dedup_roots;
319 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots;
320
321 public:
322 ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase);
323
324 template<typename IsAlive, typename KeepAlive>
325 void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive);
326 };
327
328 // Adjuster all roots at a safepoint during full gc
329 class ShenandoahRootAdjuster : public ShenandoahRootProcessor {
330 private:
331 ShenandoahSerialRoots _serial_roots;
332 ShenandoahVMRoots<false /*concurrent*/> _vm_roots;
333 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
334 _cld_roots;
335 ShenandoahThreadRoots _thread_roots;
336 ShenandoahSerialWeakRoots _serial_weak_roots;
337 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots;
338 ShenandoahStringDedupRoots _dedup_roots;
339 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots;
340
341 public:
342 ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase);
343
344 void roots_do(uint worker_id, OopClosure* oops);
345 };
346
347 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP