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