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   ShenandoahSharedSemaphore     _semaphore;
 230   ShenandoahPhaseTimings::Phase _phase;
 231 
 232   static uint worker_count(uint n_workers) {
 233     // Limit concurrency a bit, otherwise it wastes resources when workers are tripping
 234     // over each other. This also leaves free workers to process other parts of the root
 235     // set, while admitted workers are busy with doing the CLDG walk.
 236     return MAX2(1u, MIN2(ShenandoahSharedSemaphore::max_tokens(), n_workers / 2));
 237   }
 238 
 239 public:
 240   ShenandoahClassLoaderDataRoots(ShenandoahPhaseTimings::Phase phase, uint n_workers);
 241   ~ShenandoahClassLoaderDataRoots();
 242 
 243   void always_strong_cld_do(CLDClosure* clds, uint worker_id);
 244   void cld_do(CLDClosure* clds, uint worker_id);
 245 };
 246 
 247 class ShenandoahRootProcessor : public StackObj {
 248 private:
 249   ShenandoahHeap* const               _heap;
 250   const ShenandoahPhaseTimings::Phase _phase;
 251   const ShenandoahGCWorkerPhase       _worker_phase;
 252 public:
 253   ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase);
 254 
 255   ShenandoahHeap* heap() const { return _heap; }
 256 };
 257 
 258 class ShenandoahRootScanner : public ShenandoahRootProcessor {
 259 private:
 260   ShenandoahSerialRoots                                     _serial_roots;
 261   ShenandoahThreadRoots                                     _thread_roots;
 262   ShenandoahCodeCacheRoots                                  _code_roots;
 263   ShenandoahVMRoots<false /*concurrent*/ >                  _vm_roots;
 264   ShenandoahStringDedupRoots                                _dedup_roots;
 265   ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
 266                                                             _cld_roots;
 267 public:
 268   ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 269 
 270   // Apply oops, clds and blobs to all strongly reachable roots in the system,
 271   // during class unloading cycle
 272   void strong_roots_do(uint worker_id, OopClosure* cl);
 273   void strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL);
 274 
 275   // Apply oops, clds and blobs to all strongly reachable roots and weakly reachable
 276   // roots when class unloading is disabled during this cycle
 277   void roots_do(uint worker_id, OopClosure* cl);
 278   void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL);
 279 };
 280 
 281 // This scanner is only for SH::object_iteration() and only supports single-threaded
 282 // root scanning
 283 class ShenandoahHeapIterationRootScanner : public ShenandoahRootProcessor {
 284 private:
 285   ShenandoahSerialRoots                                    _serial_roots;
 286   ShenandoahThreadRoots                                    _thread_roots;
 287   ShenandoahVMRoots<false /*concurrent*/>                  _vm_roots;
 288   ShenandoahClassLoaderDataRoots<false /*concurrent*/, true /*single threaded*/>
 289                                                            _cld_roots;
 290   ShenandoahSerialWeakRoots                                _serial_weak_roots;
 291   ShenandoahWeakRoots<false /*concurrent*/>                _weak_roots;
 292   ShenandoahConcurrentStringDedupRoots                     _dedup_roots;
 293   ShenandoahCodeCacheRoots                                 _code_roots;
 294 
 295 public:
 296   ShenandoahHeapIterationRootScanner();
 297 
 298   void roots_do(OopClosure* cl);
 299 };
 300 
 301 // Evacuate all roots at a safepoint
 302 class ShenandoahRootEvacuator : public ShenandoahRootProcessor {
 303 private:
 304   ShenandoahSerialRoots                                     _serial_roots;
 305   ShenandoahVMRoots<false /*concurrent*/>                   _vm_roots;
 306   ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
 307                                                             _cld_roots;
 308   ShenandoahThreadRoots                                     _thread_roots;
 309   ShenandoahSerialWeakRoots                                 _serial_weak_roots;
 310   ShenandoahWeakRoots<false /*concurrent*/>                 _weak_roots;
 311   ShenandoahStringDedupRoots                                _dedup_roots;
 312   ShenandoahCodeCacheRoots                                  _code_roots;
 313   bool                                                      _stw_roots_processing;
 314   bool                                                      _stw_class_unloading;
 315 public:
 316   ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase,
 317                           bool stw_roots_processing, bool stw_class_unloading);
 318 
 319   void roots_do(uint worker_id, OopClosure* oops);
 320 };
 321 
 322 // Update all roots at a safepoint
 323 class ShenandoahRootUpdater : public ShenandoahRootProcessor {
 324 private:
 325   ShenandoahSerialRoots                                     _serial_roots;
 326   ShenandoahVMRoots<false /*concurrent*/>                   _vm_roots;
 327   ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
 328                                                             _cld_roots;
 329   ShenandoahThreadRoots                                     _thread_roots;
 330   ShenandoahSerialWeakRoots                                 _serial_weak_roots;
 331   ShenandoahWeakRoots<false /*concurrent*/>                 _weak_roots;
 332   ShenandoahStringDedupRoots                                _dedup_roots;
 333   ShenandoahCodeCacheRoots                                  _code_roots;
 334 
 335 public:
 336   ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 337 
 338   template<typename IsAlive, typename KeepAlive>
 339   void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive);
 340 };
 341 
 342 // Adjuster all roots at a safepoint during full gc
 343 class ShenandoahRootAdjuster : public ShenandoahRootProcessor {
 344 private:
 345   ShenandoahSerialRoots                                     _serial_roots;
 346   ShenandoahVMRoots<false /*concurrent*/>                   _vm_roots;
 347   ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
 348                                                             _cld_roots;
 349   ShenandoahThreadRoots                                     _thread_roots;
 350   ShenandoahSerialWeakRoots                                 _serial_weak_roots;
 351   ShenandoahWeakRoots<false /*concurrent*/>                 _weak_roots;
 352   ShenandoahStringDedupRoots                                _dedup_roots;
 353   ShenandoahCodeCacheRoots                                  _code_roots;
 354 
 355 public:
 356   ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 357 
 358   void roots_do(uint worker_id, OopClosure* oops);
 359 };
 360 
 361 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP