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