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