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 "gc/shenandoah/shenandoahUtils.hpp"
  35 #include "memory/iterator.hpp"
  36 
  37 class ShenandoahSerialRoot {
  38 public:
  39   typedef void (*OopsDo)(OopClosure*);
  40 private:
  41   ShenandoahSharedFlag                   _claimed;
  42   const OopsDo                           _oops_do;
  43   const ShenandoahPhaseTimings::Phase    _phase;
  44   const ShenandoahPhaseTimings::ParPhase _par_phase;
  45 
  46 public:
  47   ShenandoahSerialRoot(OopsDo oops_do,
  48           ShenandoahPhaseTimings::Phase phase, ShenandoahPhaseTimings::ParPhase par_phase);
  49   void oops_do(OopClosure* cl, uint worker_id);
  50 };
  51 
  52 class ShenandoahSerialRoots {
  53 private:
  54   ShenandoahSerialRoot  _universe_root;
  55   ShenandoahSerialRoot  _object_synchronizer_root;
  56   ShenandoahSerialRoot  _management_root;
  57   ShenandoahSerialRoot  _system_dictionary_root;
  58   ShenandoahSerialRoot  _jvmti_root;
  59 public:
  60   ShenandoahSerialRoots(ShenandoahPhaseTimings::Phase phase);
  61   void oops_do(OopClosure* cl, uint worker_id);
  62 };
  63 
  64 class ShenandoahWeakSerialRoot {
  65   typedef void (*WeakOopsDo)(BoolObjectClosure*, OopClosure*);
  66 private:
  67   ShenandoahSharedFlag                   _claimed;
  68   const WeakOopsDo                       _weak_oops_do;
  69   const ShenandoahPhaseTimings::Phase    _phase;
  70   const ShenandoahPhaseTimings::ParPhase _par_phase;
  71 
  72 public:
  73   ShenandoahWeakSerialRoot(WeakOopsDo oops_do,
  74           ShenandoahPhaseTimings::Phase phase, ShenandoahPhaseTimings::ParPhase par_phase);
  75   void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id);
  76 };
  77 
  78 #if INCLUDE_JVMTI
  79 class ShenandoahJVMTIWeakRoot : public ShenandoahWeakSerialRoot {
  80 public:
  81   ShenandoahJVMTIWeakRoot(ShenandoahPhaseTimings::Phase phase);
  82 };
  83 #endif // INCLUDE_JVMTI
  84 
  85 #if INCLUDE_JFR
  86 class ShenandoahJFRWeakRoot : public ShenandoahWeakSerialRoot {
  87 public:
  88   ShenandoahJFRWeakRoot(ShenandoahPhaseTimings::Phase phase);
  89 };
  90 #endif // INCLUDE_JFR
  91 
  92 class ShenandoahSerialWeakRoots {
  93 private:
  94   JVMTI_ONLY(ShenandoahJVMTIWeakRoot _jvmti_weak_roots;)
  95   JFR_ONLY(ShenandoahJFRWeakRoot     _jfr_weak_roots;)
  96 public:
  97   ShenandoahSerialWeakRoots(ShenandoahPhaseTimings::Phase phase) :
  98   JVMTI_ONLY(_jvmti_weak_roots(phase))
  99   JFR_ONLY(JVMTI_ONLY(COMMA)_jfr_weak_roots(phase)) {};
 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::Phase    _phase;
 109   const ShenandoahPhaseTimings::ParPhase _par_phase;
 110 public:
 111   ShenandoahVMRoot(OopStorage* storage,
 112           ShenandoahPhaseTimings::Phase phase, ShenandoahPhaseTimings::ParPhase par_phase);
 113 
 114   template <typename Closure>
 115   void oops_do(Closure* cl, uint worker_id);
 116 };
 117 
 118 template <bool CONCURRENT>
 119 class ShenandoahWeakRoot : public ShenandoahVMRoot<CONCURRENT> {
 120 public:
 121   ShenandoahWeakRoot(OopStorage* storage,
 122           ShenandoahPhaseTimings::Phase phase, ShenandoahPhaseTimings::ParPhase par_phase);
 123 };
 124 
 125 template <>
 126 class ShenandoahWeakRoot<false /*concurrent*/> {
 127 private:
 128   OopStorage::ParState<false /*concurrent*/, false /*is_const*/> _itr;
 129   const ShenandoahPhaseTimings::Phase    _phase;
 130   const ShenandoahPhaseTimings::ParPhase _par_phase;
 131 
 132 public:
 133   ShenandoahWeakRoot(OopStorage* storage,
 134           ShenandoahPhaseTimings::Phase phase, ShenandoahPhaseTimings::ParPhase par_phase);
 135 
 136   template <typename IsAliveClosure, typename KeepAliveClosure>
 137   void weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id);
 138 };
 139 
 140 template <bool CONCURRENT>
 141 class ShenandoahWeakRoots {
 142 private:
 143   ShenandoahWeakRoot<CONCURRENT>  _jni_roots;
 144   ShenandoahWeakRoot<CONCURRENT>  _string_table_roots;
 145   ShenandoahWeakRoot<CONCURRENT>  _resolved_method_table_roots;
 146   ShenandoahWeakRoot<CONCURRENT>  _vm_roots;
 147 
 148 public:
 149   ShenandoahWeakRoots();
 150 
 151   template <typename Closure>
 152   void oops_do(Closure* cl, uint worker_id);
 153 };
 154 
 155 template <>
 156 class ShenandoahWeakRoots<false /*concurrent */> {
 157 private:
 158   ShenandoahWeakRoot<false /*concurrent*/>  _jni_roots;
 159   ShenandoahWeakRoot<false /*concurrent*/>  _string_table_roots;
 160   ShenandoahWeakRoot<false /*concurrent*/>  _resolved_method_table_roots;
 161   ShenandoahWeakRoot<false /*concurrent*/>  _vm_roots;
 162 public:
 163   ShenandoahWeakRoots(ShenandoahPhaseTimings::Phase phase);
 164 
 165   template <typename Closure>
 166   void oops_do(Closure* cl, uint worker_id);
 167 
 168   template <typename IsAliveClosure, typename KeepAliveClosure>
 169   void weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id);
 170 };
 171 
 172 template <bool CONCURRENT>
 173 class ShenandoahVMRoots {
 174 private:
 175   ShenandoahVMRoot<CONCURRENT>    _jni_handle_roots;
 176   ShenandoahVMRoot<CONCURRENT>    _vm_global_roots;
 177 
 178 public:
 179   ShenandoahVMRoots(ShenandoahPhaseTimings::Phase phase);
 180 
 181   template <typename T>
 182   void oops_do(T* cl, uint worker_id);
 183 };
 184 
 185 class ShenandoahThreadRoots {
 186 private:
 187   ShenandoahPhaseTimings::Phase _phase;
 188   const bool _is_par;
 189 public:
 190   ShenandoahThreadRoots(ShenandoahPhaseTimings::Phase phase, bool is_par);
 191   ~ShenandoahThreadRoots();
 192 
 193   void oops_do(OopClosure* oops_cl, CodeBlobClosure* code_cl, uint worker_id);
 194   void threads_do(ThreadClosure* tc, uint worker_id);
 195 };
 196 
 197 class ShenandoahStringDedupRoots {
 198 private:
 199   ShenandoahPhaseTimings::Phase _phase;
 200 public:
 201   ShenandoahStringDedupRoots(ShenandoahPhaseTimings::Phase phase);
 202   ~ShenandoahStringDedupRoots();
 203 
 204   void oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id);
 205 };
 206 
 207 class ShenandoahConcurrentStringDedupRoots {
 208 public:
 209   ShenandoahConcurrentStringDedupRoots();
 210   ~ShenandoahConcurrentStringDedupRoots();
 211 
 212   void oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id);
 213 };
 214 
 215 class ShenandoahCodeCacheRoots {
 216 private:
 217   ShenandoahPhaseTimings::Phase _phase;
 218   ShenandoahCodeRootsIterator   _coderoots_iterator;
 219 public:
 220   ShenandoahCodeCacheRoots(ShenandoahPhaseTimings::Phase phase);
 221   ~ShenandoahCodeCacheRoots();
 222 
 223   void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id);
 224 };
 225 
 226 template <bool CONCURRENT, bool SINGLE_THREADED>
 227 class ShenandoahClassLoaderDataRoots {
 228 private:
 229   ShenandoahPhaseTimings::Phase _phase;
 230 public:
 231   ShenandoahClassLoaderDataRoots(ShenandoahPhaseTimings::Phase phase);
 232   ~ShenandoahClassLoaderDataRoots();
 233 
 234   void always_strong_cld_do(CLDClosure* clds, uint worker_id);
 235   void cld_do(CLDClosure* clds, uint worker_id);
 236 };
 237 
 238 class ShenandoahRootProcessor : public StackObj {
 239 private:
 240   ShenandoahHeap* const               _heap;
 241   const ShenandoahPhaseTimings::Phase _phase;
 242   const ShenandoahGCWorkerPhase       _worker_phase;
 243 public:
 244   ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase);
 245 
 246   ShenandoahHeap* heap() const { return _heap; }
 247 };
 248 
 249 class ShenandoahRootScanner : public ShenandoahRootProcessor {
 250 private:
 251   ShenandoahSerialRoots                                     _serial_roots;
 252   ShenandoahThreadRoots                                     _thread_roots;
 253   ShenandoahStringDedupRoots                                _dedup_roots;
 254 
 255 public:
 256   ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 257   ~ShenandoahRootScanner();
 258 
 259   // Apply oops, clds and blobs to all strongly reachable roots in the system,
 260   // during class unloading cycle
 261   void strong_roots_do(uint worker_id, OopClosure* cl);
 262   void strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL);
 263 
 264   // Apply oops, clds and blobs to all strongly reachable roots and weakly reachable
 265   // roots when class unloading is disabled during this cycle
 266   void roots_do(uint worker_id, OopClosure* cl);
 267   void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL);
 268 };
 269 
 270 template <bool CONCURRENT, bool SINGLE_THREADED>
 271 class ShenandoahConcurrentRootScanner {
 272 private:
 273   ShenandoahVMRoots<CONCURRENT>            _vm_roots;
 274   ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>
 275                                            _cld_roots;
 276   ShenandoahNMethodTableSnapshot*          _codecache_snapshot;
 277   ShenandoahPhaseTimings::Phase            _phase;
 278 
 279 public:
 280   ShenandoahConcurrentRootScanner(ShenandoahPhaseTimings::Phase phase);
 281   ~ShenandoahConcurrentRootScanner();
 282 
 283   void oops_do(OopClosure* oops, uint worker_id);
 284 };
 285 
 286 
 287 // This scanner is only for SH::object_iteration() and only supports single-threaded
 288 // root scanning
 289 class ShenandoahHeapIterationRootScanner : public ShenandoahRootProcessor {
 290 private:
 291   ShenandoahSerialRoots                                    _serial_roots;
 292   ShenandoahThreadRoots                                    _thread_roots;
 293   ShenandoahVMRoots<false /*concurrent*/>                  _vm_roots;
 294   ShenandoahClassLoaderDataRoots<false /*concurrent*/, true /*single threaded*/>
 295                                                            _cld_roots;
 296   ShenandoahSerialWeakRoots                                _serial_weak_roots;
 297   ShenandoahWeakRoots<false /*concurrent*/>                _weak_roots;
 298   ShenandoahConcurrentStringDedupRoots                     _dedup_roots;
 299   ShenandoahCodeCacheRoots                                 _code_roots;
 300 
 301 public:
 302   ShenandoahHeapIterationRootScanner();
 303 
 304   void roots_do(OopClosure* cl);
 305 };
 306 
 307 // Evacuate all roots at a safepoint
 308 class ShenandoahRootEvacuator : public ShenandoahRootProcessor {
 309 private:
 310   ShenandoahSerialRoots                                     _serial_roots;
 311   ShenandoahVMRoots<false /*concurrent*/>                   _vm_roots;
 312   ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
 313                                                             _cld_roots;
 314   ShenandoahThreadRoots                                     _thread_roots;
 315   ShenandoahSerialWeakRoots                                 _serial_weak_roots;
 316   ShenandoahWeakRoots<false /*concurrent*/>                 _weak_roots;
 317   ShenandoahStringDedupRoots                                _dedup_roots;
 318   ShenandoahCodeCacheRoots                                  _code_roots;
 319   bool                                                      _stw_roots_processing;
 320   bool                                                      _stw_class_unloading;
 321 public:
 322   ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase,
 323                           bool stw_roots_processing, bool stw_class_unloading);
 324 
 325   void roots_do(uint worker_id, OopClosure* oops);
 326 };
 327 
 328 // Update all roots at a safepoint
 329 class ShenandoahRootUpdater : 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                                  _code_roots;
 340 
 341 public:
 342   ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 343 
 344   template<typename IsAlive, typename KeepAlive>
 345   void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive);
 346 };
 347 
 348 // Adjuster all roots at a safepoint during full gc
 349 class ShenandoahRootAdjuster : public ShenandoahRootProcessor {
 350 private:
 351   ShenandoahSerialRoots                                     _serial_roots;
 352   ShenandoahVMRoots<false /*concurrent*/>                   _vm_roots;
 353   ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
 354                                                             _cld_roots;
 355   ShenandoahThreadRoots                                     _thread_roots;
 356   ShenandoahSerialWeakRoots                                 _serial_weak_roots;
 357   ShenandoahWeakRoots<false /*concurrent*/>                 _weak_roots;
 358   ShenandoahStringDedupRoots                                _dedup_roots;
 359   ShenandoahCodeCacheRoots                                  _code_roots;
 360 
 361 public:
 362   ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 363 
 364   void roots_do(uint worker_id, OopClosure* oops);
 365 };
 366 
 367 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP