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