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 class ShenandoahSerialWeakRoots {
88 private:
89 JVMTI_ONLY(ShenandoahJVMTIWeakRoot _jvmti_weak_roots;)
90 JFR_ONLY(ShenandoahJFRWeakRoot _jfr_weak_roots;)
91 public:
92 void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id);
93 void weak_oops_do(OopClosure* cl, uint worker_id);
94 };
95
96 template <bool CONCURRENT>
97 class ShenandoahVMRoot {
98 private:
99 OopStorage::ParState<CONCURRENT, false /* is_const */> _itr;
100 const ShenandoahPhaseTimings::GCParPhases _phase;
101 public:
102 ShenandoahVMRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase);
103
104 template <typename Closure>
105 void oops_do(Closure* cl, uint worker_id);
106 };
107
108 template <bool CONCURRENT>
109 class ShenandoahWeakRoot : public ShenandoahVMRoot<CONCURRENT> {
110 public:
111 ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase);
112 };
113
114 template <>
115 class ShenandoahWeakRoot<false /*concurrent*/> {
116 private:
117 OopStorage::ParState<false /*concurrent*/, false /*is_const*/> _itr;
118 const ShenandoahPhaseTimings::GCParPhases _phase;
119
120 public:
121 ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase);
122
123 template <typename IsAliveClosure, typename KeepAliveClosure>
124 void weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id);
125 };
126
127 template <bool CONCURRENT>
128 class ShenandoahWeakRoots {
129 private:
130 ShenandoahWeakRoot<CONCURRENT> _jni_roots;
131 ShenandoahWeakRoot<CONCURRENT> _string_table_roots;
132 ShenandoahWeakRoot<CONCURRENT> _resolved_method_table_roots;
133 ShenandoahWeakRoot<CONCURRENT> _vm_roots;
134
135 public:
136 ShenandoahWeakRoots();
137
138 template <typename Closure>
139 void oops_do(Closure* cl, uint worker_id = 0);
140 };
141
142 template <>
143 class ShenandoahWeakRoots<false /*concurrent */> {
144 private:
145 ShenandoahWeakRoot<false /*concurrent*/> _jni_roots;
146 ShenandoahWeakRoot<false /*concurrent*/> _string_table_roots;
147 ShenandoahWeakRoot<false /*concurrent*/> _resolved_method_table_roots;
148 ShenandoahWeakRoot<false /*concurrent*/> _vm_roots;
149 public:
150 ShenandoahWeakRoots();
151
152 template <typename Closure>
153 void oops_do(Closure* cl, uint worker_id = 0);
154
155 template <typename IsAliveClosure, typename KeepAliveClosure>
156 void weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id);
157 };
158
159 template <bool CONCURRENT>
160 class ShenandoahVMRoots {
161 private:
162 ShenandoahVMRoot<CONCURRENT> _jni_handle_roots;
163 ShenandoahVMRoot<CONCURRENT> _vm_global_roots;
164
165 public:
166 ShenandoahVMRoots();
167
168 template <typename T>
169 void oops_do(T* cl, uint worker_id = 0);
170 };
171
172 class ShenandoahThreadRoots {
173 private:
174 const bool _is_par;
175 public:
176 ShenandoahThreadRoots(bool is_par);
177 ~ShenandoahThreadRoots();
178
179 void oops_do(OopClosure* oops_cl, CodeBlobClosure* code_cl, uint worker_id);
180 void threads_do(ThreadClosure* tc, uint worker_id);
181 };
182
183 class ShenandoahStringDedupRoots {
184 public:
185 ShenandoahStringDedupRoots();
186 ~ShenandoahStringDedupRoots();
187
188 void oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id);
189 };
190
191 class ShenandoahConcurrentStringDedupRoots {
192 public:
193 ShenandoahConcurrentStringDedupRoots();
194 ~ShenandoahConcurrentStringDedupRoots();
195
196 void oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id);
197 };
198
199 template <typename ITR>
200 class ShenandoahCodeCacheRoots {
201 private:
202 ITR _coderoots_iterator;
203 public:
204 ShenandoahCodeCacheRoots();
205 ~ShenandoahCodeCacheRoots();
206
207 void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id);
208 };
209
210 template <bool CONCURRENT, bool SINGLE_THREADED>
211 class ShenandoahClassLoaderDataRoots {
212 public:
213 ShenandoahClassLoaderDataRoots();
214 ~ShenandoahClassLoaderDataRoots();
215
216 void always_strong_cld_do(CLDClosure* clds, uint worker_id = 0);
217 void cld_do(CLDClosure* clds, uint worker_id = 0);
218 };
219
220 class ShenandoahRootProcessor : public StackObj {
221 private:
222 ShenandoahHeap* const _heap;
223 const ShenandoahPhaseTimings::Phase _phase;
224 public:
225 ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase);
226 ~ShenandoahRootProcessor();
227
228 ShenandoahHeap* heap() const { return _heap; }
229 };
230
231 template <typename ITR>
232 class ShenandoahRootScanner : public ShenandoahRootProcessor {
233 private:
234 ShenandoahSerialRoots _serial_roots;
235 ShenandoahThreadRoots _thread_roots;
236 ShenandoahCodeCacheRoots<ITR> _code_roots;
237 ShenandoahVMRoots<false /*concurrent*/ > _vm_roots;
238 ShenandoahStringDedupRoots _dedup_roots;
239 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
240 _cld_roots;
241 public:
242 ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase);
243
244 // Apply oops, clds and blobs to all strongly reachable roots in the system,
245 // during class unloading cycle
246 void strong_roots_do(uint worker_id, OopClosure* cl);
247 void strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL);
248
249 // Apply oops, clds and blobs to all strongly reachable roots and weakly reachable
250 // roots when class unloading is disabled during this cycle
251 void roots_do(uint worker_id, OopClosure* cl);
252 void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL);
253 };
254
255 typedef ShenandoahRootScanner<ShenandoahAllCodeRootsIterator> ShenandoahAllRootScanner;
256 typedef ShenandoahRootScanner<ShenandoahCsetCodeRootsIterator> ShenandoahCSetRootScanner;
257
258 // This scanner is only for SH::object_iteration() and only supports single-threaded
259 // root scanning
260 class ShenandoahHeapIterationRootScanner : public ShenandoahRootProcessor {
261 private:
262 ShenandoahSerialRoots _serial_roots;
263 ShenandoahThreadRoots _thread_roots;
264 ShenandoahVMRoots<false /*concurrent*/> _vm_roots;
265 ShenandoahClassLoaderDataRoots<false /*concurrent*/, true /*single threaded*/>
266 _cld_roots;
267 ShenandoahSerialWeakRoots _serial_weak_roots;
268 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots;
269 ShenandoahConcurrentStringDedupRoots _dedup_roots;
270 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots;
271
272 public:
273 ShenandoahHeapIterationRootScanner();
274
275 void roots_do(OopClosure* cl);
276 void strong_roots_do(OopClosure* cl);
277 };
278
279 // Evacuate all roots at a safepoint
280 class ShenandoahRootEvacuator : public ShenandoahRootProcessor {
281 private:
282 ShenandoahSerialRoots _serial_roots;
283 ShenandoahVMRoots<false /*concurrent*/> _vm_roots;
284 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
285 _cld_roots;
286 ShenandoahThreadRoots _thread_roots;
287 ShenandoahSerialWeakRoots _serial_weak_roots;
288 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots;
289 ShenandoahStringDedupRoots _dedup_roots;
290 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots;
291 bool _include_concurrent_roots;
292 bool _include_concurrent_code_roots;
293 public:
294 ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase,
295 bool include_concurrent_roots, bool _include_concurrent_code_roots);
296
297 void roots_do(uint worker_id, OopClosure* oops);
298 };
299
300 // Update all roots at a safepoint
301 class ShenandoahRootUpdater : public ShenandoahRootProcessor {
302 private:
303 ShenandoahSerialRoots _serial_roots;
304 ShenandoahVMRoots<false /*concurrent*/> _vm_roots;
305 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
306 _cld_roots;
307 ShenandoahThreadRoots _thread_roots;
308 ShenandoahSerialWeakRoots _serial_weak_roots;
309 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots;
310 ShenandoahStringDedupRoots _dedup_roots;
311 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots;
312
313 public:
314 ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase);
315
316 template<typename IsAlive, typename KeepAlive>
317 void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive);
318 };
319
320 // Adjuster all roots at a safepoint during full gc
321 class ShenandoahRootAdjuster : public ShenandoahRootProcessor {
322 private:
323 ShenandoahSerialRoots _serial_roots;
324 ShenandoahVMRoots<false /*concurrent*/> _vm_roots;
325 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
326 _cld_roots;
327 ShenandoahThreadRoots _thread_roots;
328 ShenandoahSerialWeakRoots _serial_weak_roots;
329 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots;
330 ShenandoahStringDedupRoots _dedup_roots;
331 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots;
332
333 public:
334 ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase);
335
336 void roots_do(uint worker_id, OopClosure* oops);
337 };
338
339 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP