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 #if INCLUDE_TSAN 88 class ShenandoahTSANWeakRoot : public ShenandoahWeakSerialRoot { 89 public: 90 ShenandoahTSANWeakRoot(); 91 }; 92 #endif // INCLUDE_TSAN 93 94 class ShenandoahSerialWeakRoots { 95 private: 96 JVMTI_ONLY(ShenandoahJVMTIWeakRoot _jvmti_weak_roots;) 97 JFR_ONLY(ShenandoahJFRWeakRoot _jfr_weak_roots;) 98 TSAN_ONLY(ShenandoahTSANWeakRoot _tsan_weak_roots;) 99 public: 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::GCParPhases _phase; 109 public: 110 ShenandoahVMRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase); 111 112 template <typename Closure> 113 void oops_do(Closure* cl, uint worker_id); 114 }; 115 116 template <bool CONCURRENT> 117 class ShenandoahWeakRoot : public ShenandoahVMRoot<CONCURRENT> { 118 public: 119 ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase); 120 }; 121 122 template <> 123 class ShenandoahWeakRoot<false /*concurrent*/> { 124 private: 125 OopStorage::ParState<false /*concurrent*/, false /*is_const*/> _itr; 126 const ShenandoahPhaseTimings::GCParPhases _phase; 127 128 public: 129 ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase); 130 131 template <typename IsAliveClosure, typename KeepAliveClosure> 132 void weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id); 133 }; 134 135 template <bool CONCURRENT> 136 class ShenandoahWeakRoots { 137 private: 138 ShenandoahWeakRoot<CONCURRENT> _jni_roots; 139 ShenandoahWeakRoot<CONCURRENT> _string_table_roots; 140 ShenandoahWeakRoot<CONCURRENT> _resolved_method_table_roots; 141 ShenandoahWeakRoot<CONCURRENT> _vm_roots; 142 143 public: 144 ShenandoahWeakRoots(); 145 146 template <typename Closure> 147 void oops_do(Closure* cl, uint worker_id = 0); 148 }; 149 150 template <> 151 class ShenandoahWeakRoots<false /*concurrent */> { 152 private: 153 ShenandoahWeakRoot<false /*concurrent*/> _jni_roots; 154 ShenandoahWeakRoot<false /*concurrent*/> _string_table_roots; 155 ShenandoahWeakRoot<false /*concurrent*/> _resolved_method_table_roots; 156 ShenandoahWeakRoot<false /*concurrent*/> _vm_roots; 157 public: 158 ShenandoahWeakRoots(); 159 160 template <typename Closure> 161 void oops_do(Closure* cl, uint worker_id = 0); 162 163 template <typename IsAliveClosure, typename KeepAliveClosure> 164 void weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id); 165 }; 166 167 template <bool CONCURRENT> 168 class ShenandoahVMRoots { 169 private: 170 ShenandoahVMRoot<CONCURRENT> _jni_handle_roots; 171 ShenandoahVMRoot<CONCURRENT> _vm_global_roots; 172 173 public: 174 ShenandoahVMRoots(); 175 176 template <typename T> 177 void oops_do(T* cl, uint worker_id = 0); 178 }; 179 180 class ShenandoahThreadRoots { 181 private: 182 const bool _is_par; 183 public: 184 ShenandoahThreadRoots(bool is_par); 185 ~ShenandoahThreadRoots(); 186 187 void oops_do(OopClosure* oops_cl, CodeBlobClosure* code_cl, uint worker_id); 188 void threads_do(ThreadClosure* tc, uint worker_id); 189 }; 190 191 class ShenandoahStringDedupRoots { 192 public: 193 ShenandoahStringDedupRoots(); 194 ~ShenandoahStringDedupRoots(); 195 196 void oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id); 197 }; 198 199 class ShenandoahConcurrentStringDedupRoots { 200 public: 201 ShenandoahConcurrentStringDedupRoots(); 202 ~ShenandoahConcurrentStringDedupRoots(); 203 204 void oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id); 205 }; 206 207 template <typename ITR> 208 class ShenandoahCodeCacheRoots { 209 private: 210 ITR _coderoots_iterator; 211 public: 212 ShenandoahCodeCacheRoots(); 213 ~ShenandoahCodeCacheRoots(); 214 215 void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id); 216 }; 217 218 template <bool CONCURRENT, bool SINGLE_THREADED> 219 class ShenandoahClassLoaderDataRoots { 220 public: 221 ShenandoahClassLoaderDataRoots(); 222 ~ShenandoahClassLoaderDataRoots(); 223 224 void always_strong_cld_do(CLDClosure* clds, uint worker_id = 0); 225 void cld_do(CLDClosure* clds, uint worker_id = 0); 226 }; 227 228 class ShenandoahRootProcessor : public StackObj { 229 private: 230 ShenandoahHeap* const _heap; 231 const ShenandoahPhaseTimings::Phase _phase; 232 public: 233 ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase); 234 ~ShenandoahRootProcessor(); 235 236 ShenandoahHeap* heap() const { return _heap; } 237 }; 238 239 template <typename ITR> 240 class ShenandoahRootScanner : public ShenandoahRootProcessor { 241 private: 242 ShenandoahSerialRoots _serial_roots; 243 ShenandoahThreadRoots _thread_roots; 244 ShenandoahCodeCacheRoots<ITR> _code_roots; 245 ShenandoahVMRoots<false /*concurrent*/ > _vm_roots; 246 ShenandoahStringDedupRoots _dedup_roots; 247 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/> 248 _cld_roots; 249 public: 250 ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase); 251 252 // Apply oops, clds and blobs to all strongly reachable roots in the system, 253 // during class unloading cycle 254 void strong_roots_do(uint worker_id, OopClosure* cl); 255 void strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); 256 257 // Apply oops, clds and blobs to all strongly reachable roots and weakly reachable 258 // roots when class unloading is disabled during this cycle 259 void roots_do(uint worker_id, OopClosure* cl); 260 void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); 261 }; 262 263 typedef ShenandoahRootScanner<ShenandoahAllCodeRootsIterator> ShenandoahAllRootScanner; 264 typedef ShenandoahRootScanner<ShenandoahCsetCodeRootsIterator> ShenandoahCSetRootScanner; 265 266 // This scanner is only for SH::object_iteration() and only supports single-threaded 267 // root scanning 268 class ShenandoahHeapIterationRootScanner : public ShenandoahRootProcessor { 269 private: 270 ShenandoahSerialRoots _serial_roots; 271 ShenandoahThreadRoots _thread_roots; 272 ShenandoahVMRoots<false /*concurrent*/> _vm_roots; 273 ShenandoahClassLoaderDataRoots<false /*concurrent*/, true /*single threaded*/> 274 _cld_roots; 275 ShenandoahSerialWeakRoots _serial_weak_roots; 276 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots; 277 ShenandoahConcurrentStringDedupRoots _dedup_roots; 278 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; 279 280 public: 281 ShenandoahHeapIterationRootScanner(); 282 283 void roots_do(OopClosure* cl); 284 void strong_roots_do(OopClosure* cl); 285 }; 286 287 // Evacuate all roots at a safepoint 288 class ShenandoahRootEvacuator : public ShenandoahRootProcessor { 289 private: 290 ShenandoahSerialRoots _serial_roots; 291 ShenandoahVMRoots<false /*concurrent*/> _vm_roots; 292 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/> 293 _cld_roots; 294 ShenandoahThreadRoots _thread_roots; 295 ShenandoahSerialWeakRoots _serial_weak_roots; 296 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots; 297 ShenandoahStringDedupRoots _dedup_roots; 298 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; 299 bool _include_concurrent_roots; 300 bool _include_concurrent_code_roots; 301 public: 302 ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase, 303 bool include_concurrent_roots, bool _include_concurrent_code_roots); 304 305 void roots_do(uint worker_id, OopClosure* oops); 306 }; 307 308 // Update all roots at a safepoint 309 class ShenandoahRootUpdater : public ShenandoahRootProcessor { 310 private: 311 ShenandoahSerialRoots _serial_roots; 312 ShenandoahVMRoots<false /*concurrent*/> _vm_roots; 313 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/> 314 _cld_roots; 315 ShenandoahThreadRoots _thread_roots; 316 ShenandoahSerialWeakRoots _serial_weak_roots; 317 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots; 318 ShenandoahStringDedupRoots _dedup_roots; 319 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; 320 321 public: 322 ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase); 323 324 template<typename IsAlive, typename KeepAlive> 325 void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive); 326 }; 327 328 // Adjuster all roots at a safepoint during full gc 329 class ShenandoahRootAdjuster : public ShenandoahRootProcessor { 330 private: 331 ShenandoahSerialRoots _serial_roots; 332 ShenandoahVMRoots<false /*concurrent*/> _vm_roots; 333 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/> 334 _cld_roots; 335 ShenandoahThreadRoots _thread_roots; 336 ShenandoahSerialWeakRoots _serial_weak_roots; 337 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots; 338 ShenandoahStringDedupRoots _dedup_roots; 339 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; 340 341 public: 342 ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase); 343 344 void roots_do(uint worker_id, OopClosure* oops); 345 }; 346 347 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP