1 /*
   2  * Copyright (c) 2015, 2020, Red Hat, Inc. All rights reserved.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.
   7  *
   8  * This code is distributed in the hope that it will be useful, but WITHOUT
   9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  11  * version 2 for more details (a copy is included in the LICENSE file that
  12  * accompanied this code).
  13  *
  14  * You should have received a copy of the GNU General Public License version
  15  * 2 along with this work; if not, write to the Free Software Foundation,
  16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  17  *
  18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  19  * or visit www.oracle.com if you need additional information or have any
  20  * questions.
  21  *
  22  */
  23 
  24 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP
  25 #define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP
  26 
  27 #include "code/codeCache.hpp"
  28 #include "gc/shared/oopStorageParState.hpp"
  29 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
  30 #include "gc/shenandoah/shenandoahHeap.hpp"
  31 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
  32 #include "gc/shenandoah/shenandoahUtils.hpp"
  33 #include "gc/shared/strongRootsScope.hpp"
  34 #include "gc/shared/weakProcessor.hpp"
  35 #include "gc/shared/workgroup.hpp"
  36 #include "memory/allocation.hpp"
  37 #include "memory/iterator.hpp"
  38 
  39 class ShenandoahSerialRoot {
  40 public:
  41   typedef void (*OopsDo)(OopClosure*);
  42 private:
  43   ShenandoahSharedFlag                   _claimed;
  44   const OopsDo                           _oops_do;
  45   const ShenandoahPhaseTimings::Phase    _phase;
  46   const ShenandoahPhaseTimings::ParPhase _par_phase;
  47 
  48 public:
  49   ShenandoahSerialRoot(OopsDo oops_do,
  50           ShenandoahPhaseTimings::Phase phase, ShenandoahPhaseTimings::ParPhase par_phase);
  51   void oops_do(OopClosure* cl, uint worker_id);
  52 };
  53 
  54 class ShenandoahSerialRoots {
  55 private:
  56   ShenandoahSerialRoot  _universe_root;
  57   ShenandoahSerialRoot  _object_synchronizer_root;
  58   ShenandoahSerialRoot  _management_root;
  59   ShenandoahSerialRoot  _system_dictionary_root;
  60   ShenandoahSerialRoot  _jvmti_root;
  61 
  62   // Proxy to make weird Universe::oops_do() signature match OopsDo
  63   static void universe_oops_do(OopClosure* cl) { Universe::oops_do(cl); }
  64 
  65 public:
  66   ShenandoahSerialRoots(ShenandoahPhaseTimings::Phase phase);
  67   void oops_do(OopClosure* cl, uint worker_id);
  68 };
  69 
  70 class ShenandoahJNIHandleRoots : public ShenandoahSerialRoot {
  71 public:
  72   ShenandoahJNIHandleRoots(ShenandoahPhaseTimings::Phase phase);
  73 };
  74 
  75 class ShenandoahThreadRoots {
  76 private:
  77   ShenandoahPhaseTimings::Phase _phase;
  78   const bool _is_par;
  79 public:
  80   ShenandoahThreadRoots(ShenandoahPhaseTimings::Phase phase, bool is_par);
  81   ~ShenandoahThreadRoots();
  82 
  83   void oops_do(OopClosure* oops_cl, CodeBlobClosure* code_cl, uint worker_id);
  84   void threads_do(ThreadClosure* tc, uint worker_id);
  85 };
  86 
  87 class ShenandoahWeakRoots {
  88   ShenandoahPhaseTimings::Phase      _phase;
  89   OopStorage::ParState<false, false> _par_state_string;
  90   volatile bool                      _claimed;
  91 
  92 public:
  93   ShenandoahWeakRoots(ShenandoahPhaseTimings::Phase phase, uint n_workers);
  94   ~ShenandoahWeakRoots();
  95 
  96   template <typename IsAlive, typename KeepAlive>
  97   void oops_do(IsAlive* is_alive, KeepAlive* keep_alive, uint worker_id);
  98 };
  99 
 100 class ShenandoahStringDedupRoots {
 101 private:
 102   ShenandoahPhaseTimings::Phase _phase;
 103 public:
 104   ShenandoahStringDedupRoots(ShenandoahPhaseTimings::Phase phase);
 105   ~ShenandoahStringDedupRoots();
 106 
 107   void oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id);
 108 };
 109 
 110 template <typename ITR>
 111 class ShenandoahCodeCacheRoots {
 112 private:
 113   ShenandoahPhaseTimings::Phase _phase;
 114   ITR _coderoots_iterator;
 115 public:
 116   ShenandoahCodeCacheRoots(ShenandoahPhaseTimings::Phase phase);
 117   ~ShenandoahCodeCacheRoots();
 118 
 119   void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id);
 120 };
 121 
 122 template <bool SINGLE_THREADED>
 123 class ShenandoahClassLoaderDataRoots {
 124 private:
 125   ShenandoahPhaseTimings::Phase _phase;
 126 public:
 127   ShenandoahClassLoaderDataRoots(ShenandoahPhaseTimings::Phase phase);
 128 
 129   void always_strong_cld_do(CLDClosure* clds, uint worker_id);
 130   void cld_do(CLDClosure* clds, uint worker_id);
 131 };
 132 
 133 class ShenandoahRootProcessor : public StackObj {
 134 private:
 135   ShenandoahHeap* const               _heap;
 136   const ShenandoahPhaseTimings::Phase _phase;
 137   const ShenandoahGCWorkerPhase       _worker_phase;
 138 public:
 139   ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase);
 140 
 141   ShenandoahHeap* heap() const { return _heap; }
 142 };
 143 
 144 template <typename ITR>
 145 class ShenandoahRootScanner : public ShenandoahRootProcessor {
 146 private:
 147   ShenandoahSerialRoots                                     _serial_roots;
 148   ShenandoahThreadRoots                                     _thread_roots;
 149   ShenandoahCodeCacheRoots<ITR>                             _code_roots;
 150   ShenandoahJNIHandleRoots                                  _jni_roots;
 151   ShenandoahStringDedupRoots                                _dedup_roots;
 152   ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots;
 153 public:
 154   ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 155 
 156   // Apply oops, clds and blobs to all strongly reachable roots in the system,
 157   // during class unloading cycle
 158   void strong_roots_do(uint worker_id, OopClosure* cl);
 159   void strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL);
 160 
 161   // Apply oops, clds and blobs to all strongly reachable roots and weakly reachable
 162   // roots when class unloading is disabled during this cycle
 163   void roots_do(uint worker_id, OopClosure* cl);
 164   void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL);
 165 };
 166 
 167 typedef ShenandoahRootScanner<ShenandoahAllCodeRootsIterator> ShenandoahAllRootScanner;
 168 typedef ShenandoahRootScanner<ShenandoahCsetCodeRootsIterator> ShenandoahCSetRootScanner;
 169 
 170 // This scanner is only for SH::object_iteration() and only supports single-threaded
 171 // root scanning
 172 class ShenandoahHeapIterationRootScanner : public ShenandoahRootProcessor {
 173 private:
 174   ShenandoahSerialRoots                                    _serial_roots;
 175   ShenandoahThreadRoots                                    _thread_roots;
 176   ShenandoahJNIHandleRoots                                 _jni_roots;
 177   ShenandoahClassLoaderDataRoots<true /*single threaded*/> _cld_roots;
 178   ShenandoahWeakRoots                                      _weak_roots;
 179   ShenandoahStringDedupRoots                               _dedup_roots;
 180   ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots;
 181 
 182 public:
 183   ShenandoahHeapIterationRootScanner();
 184 
 185   void roots_do(OopClosure* cl);
 186 };
 187 
 188 // Evacuate all roots at a safepoint
 189 class ShenandoahRootEvacuator : public ShenandoahRootProcessor {
 190 private:
 191   ShenandoahSerialRoots                                     _serial_roots;
 192   ShenandoahJNIHandleRoots                                  _jni_roots;
 193   ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots;
 194   ShenandoahThreadRoots                                     _thread_roots;
 195   ShenandoahWeakRoots                                       _weak_roots;
 196   ShenandoahStringDedupRoots                                _dedup_roots;
 197   ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots;
 198 
 199 public:
 200   ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 201 
 202   void roots_do(uint worker_id, OopClosure* oops);
 203 };
 204 
 205 // Update all roots at a safepoint
 206 class ShenandoahRootUpdater : public ShenandoahRootProcessor {
 207 private:
 208   ShenandoahSerialRoots                                     _serial_roots;
 209   ShenandoahJNIHandleRoots                                  _jni_roots;
 210   ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots;
 211   ShenandoahThreadRoots                                     _thread_roots;
 212   ShenandoahWeakRoots                                       _weak_roots;
 213   ShenandoahStringDedupRoots                                _dedup_roots;
 214   ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots;
 215   const bool                                                _update_code_cache;
 216 
 217 public:
 218   ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool update_code_cache);
 219 
 220   template<typename IsAlive, typename KeepAlive>
 221   void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive);
 222 };
 223 
 224 // Adjuster all roots at a safepoint during full gc
 225 class ShenandoahRootAdjuster : public ShenandoahRootProcessor {
 226 private:
 227   ShenandoahSerialRoots                                     _serial_roots;
 228   ShenandoahJNIHandleRoots                                  _jni_roots;
 229   ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots;
 230   ShenandoahThreadRoots                                     _thread_roots;
 231   ShenandoahWeakRoots                                       _weak_roots;
 232   ShenandoahStringDedupRoots                                _dedup_roots;
 233   ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator>  _code_roots;
 234 
 235 public:
 236   ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 237 
 238   void roots_do(uint worker_id, OopClosure* oops);
 239 };
 240 
 241 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP