1 /* 2 * Copyright (c) 2015, 2018, 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_VM_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP 25 #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP 26 27 #include "code/codeCache.hpp" 28 #include "gc_implementation/shenandoah/shenandoahCodeRoots.hpp" 29 #include "gc_implementation/shenandoah/shenandoahHeap.hpp" 30 #include "gc_implementation/shenandoah/shenandoahPhaseTimings.hpp" 31 #include "gc_implementation/shenandoah/shenandoahSynchronizerIterator.hpp" 32 #include "memory/allocation.hpp" 33 #include "memory/iterator.hpp" 34 #include "memory/sharedHeap.hpp" 35 #include "utilities/macros.hpp" 36 #include "utilities/workgroup.hpp" 37 38 39 class ShenandoahSerialRoot { 40 public: 41 typedef void (*OopsDo)(OopClosure*); 42 private: 43 volatile jint _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 const ShenandoahPhaseTimings::Phase _phase; 57 ShenandoahSerialRoot _universe_roots; 58 ShenandoahSerialRoot _management_roots; 59 ShenandoahSerialRoot _jvmti_roots; 60 ShenandoahSerialRoot _jni_handle_roots; 61 ShenandoahSerialRoot _flat_profiler_roots; 62 ShenandoahSynchronizerIterator _om_iterator; 63 public: 64 ShenandoahSerialRoots(ShenandoahPhaseTimings::Phase phase); 65 void oops_do(OopClosure* cl, uint worker_id); 66 }; 67 68 class ShenandoahSystemDictionaryRoots { 69 private: 70 const ShenandoahPhaseTimings::Phase _phase; 71 volatile int _claimed; 72 public: 73 ShenandoahSystemDictionaryRoots(ShenandoahPhaseTimings::Phase phase); 74 void strong_oops_do(OopClosure* oops, uint worker_id); 75 void oops_do(OopClosure* oops, uint worker_id); 76 }; 77 78 class ShenandoahStringTableRoots { 79 private: 80 const ShenandoahPhaseTimings::Phase _phase; 81 public: 82 ShenandoahStringTableRoots(ShenandoahPhaseTimings::Phase phase); 83 void oops_do(OopClosure* oops, uint worker_id); 84 }; 85 86 class ShenandoahThreadRoots { 87 private: 88 const ShenandoahPhaseTimings::Phase _phase; 89 public: 90 ShenandoahThreadRoots(ShenandoahPhaseTimings::Phase phase); 91 void oops_do(OopClosure* oops_cl, CLDClosure* cld_cl, CodeBlobClosure* code_cl, uint worker_id); 92 }; 93 94 class ShenandoahWeakRoot { 95 public: 96 typedef void (*WeakOopsDo)(BoolObjectClosure*, OopClosure*); 97 private: 98 const ShenandoahPhaseTimings::Phase _phase; 99 const ShenandoahPhaseTimings::ParPhase _par_phase; 100 volatile int _claimed; 101 const WeakOopsDo _weak_oops_do; 102 103 public: 104 ShenandoahWeakRoot(ShenandoahPhaseTimings::Phase phase, ShenandoahPhaseTimings::ParPhase par_phase, WeakOopsDo oops_do); 105 void oops_do(OopClosure* keep_alive, uint worker_id); 106 void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id); 107 }; 108 109 class ShenandoahWeakRoots { 110 private: 111 JFR_ONLY(ShenandoahWeakRoot _jfr_weak_roots;) 112 ShenandoahWeakRoot _jni_weak_roots; 113 public: 114 ShenandoahWeakRoots(ShenandoahPhaseTimings::Phase phase); 115 void oops_do(OopClosure* keep_alive, uint worker_id); 116 void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id); 117 }; 118 119 class ShenandoahStringDedupRoots { 120 private: 121 const ShenandoahPhaseTimings::Phase _phase; 122 public: 123 ShenandoahStringDedupRoots(ShenandoahPhaseTimings::Phase phase); 124 void oops_do(OopClosure* oops, uint worker_id); 125 }; 126 127 template <typename ITR> 128 class ShenandoahCodeCacheRoots { 129 private: 130 const ShenandoahPhaseTimings::Phase _phase; 131 ITR _coderoots_iterator; 132 public: 133 ShenandoahCodeCacheRoots(ShenandoahPhaseTimings::Phase phase); 134 void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id); 135 }; 136 137 class ShenandoahClassLoaderDataRoots { 138 private: 139 const ShenandoahPhaseTimings::Phase _phase; 140 public: 141 ShenandoahClassLoaderDataRoots(ShenandoahPhaseTimings::Phase phase); 142 143 void always_strong_cld_do(CLDClosure* clds, uint worker_id); 144 void cld_do(CLDClosure* clds, uint worker_id); 145 }; 146 147 class ShenandoahRootProcessor : public StackObj { 148 private: 149 SharedHeap::StrongRootsScope _srs; 150 ShenandoahHeap* const _heap; 151 const ShenandoahPhaseTimings::Phase _phase; 152 public: 153 ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase); 154 ~ShenandoahRootProcessor(); 155 156 ShenandoahHeap* heap() const { return _heap; } 157 }; 158 159 template <typename ITR> 160 class ShenandoahRootScanner : public ShenandoahRootProcessor { 161 private: 162 ShenandoahSerialRoots _serial_roots; 163 ShenandoahSystemDictionaryRoots _dict_roots; 164 ShenandoahClassLoaderDataRoots _cld_roots; 165 ShenandoahThreadRoots _thread_roots; 166 ShenandoahWeakRoots _weak_roots; 167 ShenandoahStringDedupRoots _dedup_roots; 168 ShenandoahStringTableRoots _string_table_roots; 169 ShenandoahCodeCacheRoots<ITR> _code_roots; 170 public: 171 ShenandoahRootScanner(ShenandoahPhaseTimings::Phase phase); 172 173 // Apply oops, clds and blobs to all strongly reachable roots in the system, 174 // during class unloading cycle 175 void strong_roots_do(uint worker_id, OopClosure* cl); 176 void strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code); 177 178 // Apply oops, clds and blobs to all strongly reachable roots and weakly reachable 179 // roots when class unloading is disabled during this cycle 180 void roots_do(uint worker_id, OopClosure* cl); 181 void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code); 182 }; 183 184 typedef ShenandoahRootScanner<ShenandoahAllCodeRootsIterator> ShenandoahAllRootScanner; 185 typedef ShenandoahRootScanner<ShenandoahCsetCodeRootsIterator> ShenandoahCSetRootScanner; 186 187 // This scanner is only for SH::object_iteration() and only supports single-threaded 188 // root scanning 189 class ShenandoahHeapIterationRootScanner : public ShenandoahRootProcessor { 190 private: 191 ShenandoahSerialRoots _serial_roots; 192 ShenandoahSystemDictionaryRoots _dict_roots; 193 ShenandoahThreadRoots _thread_roots; 194 ShenandoahClassLoaderDataRoots _cld_roots; 195 ShenandoahWeakRoots _weak_roots; 196 ShenandoahStringDedupRoots _dedup_roots; 197 ShenandoahStringTableRoots _string_table_roots; 198 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; 199 200 public: 201 ShenandoahHeapIterationRootScanner(); 202 203 void roots_do(OopClosure* cl); 204 }; 205 206 // Evacuate all roots at a safepoint 207 class ShenandoahRootEvacuator : public ShenandoahRootProcessor { 208 private: 209 ShenandoahSerialRoots _serial_roots; 210 ShenandoahSystemDictionaryRoots _dict_roots; 211 ShenandoahClassLoaderDataRoots _cld_roots; 212 ShenandoahThreadRoots _thread_roots; 213 ShenandoahWeakRoots _weak_roots; 214 ShenandoahStringDedupRoots _dedup_roots; 215 ShenandoahStringTableRoots _string_table_roots; 216 ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> 217 _code_roots; 218 219 public: 220 ShenandoahRootEvacuator(ShenandoahPhaseTimings::Phase phase); 221 222 void roots_do(uint worker_id, OopClosure* oops); 223 }; 224 225 // Update all roots at a safepoint 226 class ShenandoahRootUpdater : public ShenandoahRootProcessor { 227 private: 228 ShenandoahSerialRoots _serial_roots; 229 ShenandoahSystemDictionaryRoots _dict_roots; 230 ShenandoahClassLoaderDataRoots _cld_roots; 231 ShenandoahThreadRoots _thread_roots; 232 ShenandoahWeakRoots _weak_roots; 233 ShenandoahStringDedupRoots _dedup_roots; 234 ShenandoahStringTableRoots _string_table_roots; 235 ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> 236 _code_roots; 237 238 public: 239 ShenandoahRootUpdater(ShenandoahPhaseTimings::Phase phase); 240 void roots_do(uint worker_id, BoolObjectClosure* is_alive, OopClosure* keep_alive); 241 }; 242 243 // Adjuster all roots at a safepoint during full gc 244 class ShenandoahRootAdjuster : public ShenandoahRootProcessor { 245 private: 246 ShenandoahSerialRoots _serial_roots; 247 ShenandoahSystemDictionaryRoots _dict_roots; 248 ShenandoahClassLoaderDataRoots _cld_roots; 249 ShenandoahThreadRoots _thread_roots; 250 ShenandoahWeakRoots _weak_roots; 251 ShenandoahStringDedupRoots _dedup_roots; 252 ShenandoahStringTableRoots _string_table_roots; 253 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> 254 _code_roots; 255 256 public: 257 ShenandoahRootAdjuster(ShenandoahPhaseTimings::Phase phase); 258 259 void roots_do(uint worker_id, OopClosure* oops); 260 }; 261 262 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP