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