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