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   ShenandoahCodeCacheRoots                                  _code_roots;
 254   ShenandoahVMRoots<false /*concurrent*/ >                  _vm_roots;
 255   ShenandoahStringDedupRoots                                _dedup_roots;
 256   ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
 257                                                             _cld_roots;
 258 public:
 259   ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 260 
 261   // Apply oops, clds and blobs to all strongly reachable roots in the system,
 262   // during class unloading cycle
 263   void strong_roots_do(uint worker_id, OopClosure* cl);
 264   void strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL);
 265 
 266   // Apply oops, clds and blobs to all strongly reachable roots and weakly reachable
 267   // roots when class unloading is disabled during this cycle
 268   void roots_do(uint worker_id, OopClosure* cl);
 269   void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL);
 270 };
 271 
 272 // This scanner is only for SH::object_iteration() and only supports single-threaded
 273 // root scanning
 274 class ShenandoahHeapIterationRootScanner : public ShenandoahRootProcessor {
 275 private:
 276   ShenandoahSerialRoots                                    _serial_roots;
 277   ShenandoahThreadRoots                                    _thread_roots;
 278   ShenandoahVMRoots<false /*concurrent*/>                  _vm_roots;
 279   ShenandoahClassLoaderDataRoots<false /*concurrent*/, true /*single threaded*/>
 280                                                            _cld_roots;
 281   ShenandoahSerialWeakRoots                                _serial_weak_roots;
 282   ShenandoahWeakRoots<false /*concurrent*/>                _weak_roots;
 283   ShenandoahConcurrentStringDedupRoots                     _dedup_roots;
 284   ShenandoahCodeCacheRoots                                 _code_roots;
 285 
 286 public:
 287   ShenandoahHeapIterationRootScanner();
 288 
 289   void roots_do(OopClosure* cl);
 290 };
 291 
 292 // Evacuate all roots at a safepoint
 293 class ShenandoahRootEvacuator : public ShenandoahRootProcessor {
 294 private:
 295   ShenandoahSerialRoots                                     _serial_roots;
 296   ShenandoahVMRoots<false /*concurrent*/>                   _vm_roots;
 297   ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
 298                                                             _cld_roots;
 299   ShenandoahThreadRoots                                     _thread_roots;
 300   ShenandoahSerialWeakRoots                                 _serial_weak_roots;
 301   ShenandoahWeakRoots<false /*concurrent*/>                 _weak_roots;
 302   ShenandoahStringDedupRoots                                _dedup_roots;
 303   ShenandoahCodeCacheRoots                                  _code_roots;
 304   bool                                                      _stw_roots_processing;
 305   bool                                                      _stw_class_unloading;
 306 public:
 307   ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase,
 308                           bool stw_roots_processing, bool stw_class_unloading);
 309 
 310   void roots_do(uint worker_id, OopClosure* oops);
 311 };
 312 
 313 // Update all roots at a safepoint
 314 class ShenandoahRootUpdater : public ShenandoahRootProcessor {
 315 private:
 316   ShenandoahSerialRoots                                     _serial_roots;
 317   ShenandoahVMRoots<false /*concurrent*/>                   _vm_roots;
 318   ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
 319                                                             _cld_roots;
 320   ShenandoahThreadRoots                                     _thread_roots;
 321   ShenandoahSerialWeakRoots                                 _serial_weak_roots;
 322   ShenandoahWeakRoots<false /*concurrent*/>                 _weak_roots;
 323   ShenandoahStringDedupRoots                                _dedup_roots;
 324   ShenandoahCodeCacheRoots                                  _code_roots;
 325 
 326 public:
 327   ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 328 
 329   template<typename IsAlive, typename KeepAlive>
 330   void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive);
 331 };
 332 
 333 // Adjuster all roots at a safepoint during full gc
 334 class ShenandoahRootAdjuster : public ShenandoahRootProcessor {
 335 private:
 336   ShenandoahSerialRoots                                     _serial_roots;
 337   ShenandoahVMRoots<false /*concurrent*/>                   _vm_roots;
 338   ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
 339                                                             _cld_roots;
 340   ShenandoahThreadRoots                                     _thread_roots;
 341   ShenandoahSerialWeakRoots                                 _serial_weak_roots;
 342   ShenandoahWeakRoots<false /*concurrent*/>                 _weak_roots;
 343   ShenandoahStringDedupRoots                                _dedup_roots;
 344   ShenandoahCodeCacheRoots                                  _code_roots;
 345 
 346 public:
 347   ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 348 
 349   void roots_do(uint worker_id, OopClosure* oops);
 350 };
 351 
 352 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP