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 template <typename ITR>
 192 class ShenandoahCodeCacheRoots {
 193 private:
 194   ITR _coderoots_iterator;
 195 public:
 196   ShenandoahCodeCacheRoots();
 197   ~ShenandoahCodeCacheRoots();
 198 
 199   void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id);
 200 };
 201 
 202 template <bool CONCURRENT, bool SINGLE_THREADED>
 203 class ShenandoahClassLoaderDataRoots {
 204 public:
 205   ShenandoahClassLoaderDataRoots();
 206   ~ShenandoahClassLoaderDataRoots();
 207 
 208   void always_strong_cld_do(CLDClosure* clds, uint worker_id = 0);
 209   void cld_do(CLDClosure* clds, uint worker_id = 0);
 210 };
 211 
 212 class ShenandoahRootProcessor : public StackObj {
 213 private:
 214   ShenandoahHeap* const               _heap;
 215   const ShenandoahPhaseTimings::Phase _phase;
 216 public:
 217   ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase);
 218   ~ShenandoahRootProcessor();
 219 
 220   ShenandoahHeap* heap() const { return _heap; }
 221 };
 222 
 223 template <typename ITR>
 224 class ShenandoahRootScanner : public ShenandoahRootProcessor {
 225 private:
 226   ShenandoahSerialRoots                                     _serial_roots;
 227   ShenandoahThreadRoots                                     _thread_roots;
 228   ShenandoahCodeCacheRoots<ITR>                             _code_roots;
 229   ShenandoahVMRoots<false /*concurrent*/ >                  _vm_roots;
 230   ShenandoahStringDedupRoots                                _dedup_roots;
 231   ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
 232                                                             _cld_roots;
 233 public:
 234   ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 235 
 236   // Apply oops, clds and blobs to all strongly reachable roots in the system,
 237   // during class unloading cycle
 238   void strong_roots_do(uint worker_id, OopClosure* cl);
 239   void strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL);
 240 
 241   // Apply oops, clds and blobs to all strongly reachable roots and weakly reachable
 242   // roots when class unloading is disabled during this cycle
 243   void roots_do(uint worker_id, OopClosure* cl);
 244   void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL);
 245 };
 246 
 247 typedef ShenandoahRootScanner<ShenandoahAllCodeRootsIterator> ShenandoahAllRootScanner;
 248 typedef ShenandoahRootScanner<ShenandoahCsetCodeRootsIterator> ShenandoahCSetRootScanner;
 249 
 250 // This scanner is only for SH::object_iteration() and only supports single-threaded
 251 // root scanning
 252 class ShenandoahHeapIterationRootScanner : public ShenandoahRootProcessor {
 253 private:
 254   ShenandoahSerialRoots                                    _serial_roots;
 255   ShenandoahThreadRoots                                    _thread_roots;
 256   ShenandoahVMRoots<false /*concurrent*/>                  _vm_roots;
 257   ShenandoahClassLoaderDataRoots<false /*concurrent*/, true /*single threaded*/>
 258                                                            _cld_roots;
 259   ShenandoahSerialWeakRoots                                _serial_weak_roots;
 260   ShenandoahWeakRoots<false /*concurrent*/>                _weak_roots;
 261   ShenandoahStringDedupRoots                               _dedup_roots;
 262   ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots;
 263 
 264 public:
 265   ShenandoahHeapIterationRootScanner();
 266 
 267   void roots_do(OopClosure* cl);
 268   void strong_roots_do(OopClosure* cl);
 269 };
 270 
 271 // Evacuate all roots at a safepoint
 272 class ShenandoahRootEvacuator : public ShenandoahRootProcessor {
 273 private:
 274   ShenandoahSerialRoots                                     _serial_roots;
 275   ShenandoahVMRoots<false /*concurrent*/>                   _vm_roots;
 276   ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
 277                                                             _cld_roots;
 278   ShenandoahThreadRoots                                     _thread_roots;
 279   ShenandoahSerialWeakRoots                                 _serial_weak_roots;
 280   ShenandoahWeakRoots<false /*concurrent*/>                 _weak_roots;
 281   ShenandoahStringDedupRoots                                _dedup_roots;
 282   ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator>  _code_roots;
 283   bool                                                      _include_concurrent_roots;
 284   bool                                                      _include_concurrent_code_roots;
 285 public:
 286   ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase,
 287                           bool include_concurrent_roots, bool _include_concurrent_code_roots);
 288 
 289   void roots_do(uint worker_id, OopClosure* oops);
 290 };
 291 
 292 // Update all roots at a safepoint
 293 class ShenandoahRootUpdater : 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<ShenandoahAllCodeRootsIterator>  _code_roots;
 304 
 305 public:
 306   ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 307 
 308   template<typename IsAlive, typename KeepAlive>
 309   void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive);
 310 };
 311 
 312 // Adjuster all roots at a safepoint during full gc
 313 class ShenandoahRootAdjuster : public ShenandoahRootProcessor {
 314 private:
 315   ShenandoahSerialRoots                                     _serial_roots;
 316   ShenandoahVMRoots<false /*concurrent*/>                   _vm_roots;
 317   ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
 318                                                             _cld_roots;
 319   ShenandoahThreadRoots                                     _thread_roots;
 320   ShenandoahSerialWeakRoots                                 _serial_weak_roots;
 321   ShenandoahWeakRoots<false /*concurrent*/>                 _weak_roots;
 322   ShenandoahStringDedupRoots                                _dedup_roots;
 323   ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator>  _code_roots;
 324 
 325 public:
 326   ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 327 
 328   void roots_do(uint worker_id, OopClosure* oops);
 329 };
 330 
 331 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP