1 /* 2 * Copyright (c) 2015, 2020, 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_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP 25 #define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP 26 27 #include "code/codeCache.hpp" 28 #include "gc/shared/oopStorageParState.hpp" 29 #include "gc/shenandoah/shenandoahCodeRoots.hpp" 30 #include "gc/shenandoah/shenandoahHeap.hpp" 31 #include "gc/shenandoah/shenandoahPhaseTimings.hpp" 32 #include "gc/shenandoah/shenandoahSharedVariables.hpp" 33 #include "memory/iterator.hpp" 34 35 class ShenandoahSerialRoot { 36 public: 37 typedef void (*OopsDo)(OopClosure*); 38 private: 39 ShenandoahSharedFlag _claimed; 40 const OopsDo _oops_do; 41 const ShenandoahPhaseTimings::GCParPhases _phase; 42 43 public: 44 ShenandoahSerialRoot(OopsDo oops_do, ShenandoahPhaseTimings::GCParPhases); 45 void oops_do(OopClosure* cl, uint worker_id); 46 }; 47 48 class ShenandoahSerialRoots { 49 private: 50 ShenandoahSerialRoot _universe_root; 51 ShenandoahSerialRoot _object_synchronizer_root; 52 ShenandoahSerialRoot _management_root; 53 ShenandoahSerialRoot _system_dictionary_root; 54 ShenandoahSerialRoot _jvmti_root; 55 public: 56 ShenandoahSerialRoots(); 57 void oops_do(OopClosure* cl, uint worker_id); 58 }; 59 60 class ShenandoahWeakSerialRoot { 61 typedef void (*WeakOopsDo)(BoolObjectClosure*, OopClosure*); 62 private: 63 ShenandoahSharedFlag _claimed; 64 const WeakOopsDo _weak_oops_do; 65 const ShenandoahPhaseTimings::GCParPhases _phase; 66 67 public: 68 ShenandoahWeakSerialRoot(WeakOopsDo oops_do, ShenandoahPhaseTimings::GCParPhases); 69 void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id); 70 }; 71 72 #if INCLUDE_JVMTI 73 class ShenandoahJVMTIWeakRoot : public ShenandoahWeakSerialRoot { 74 public: 75 ShenandoahJVMTIWeakRoot(); 76 }; 77 #endif // INCLUDE_JVMTI 78 79 #if INCLUDE_JFR 80 class ShenandoahJFRWeakRoot : public ShenandoahWeakSerialRoot { 81 public: 82 ShenandoahJFRWeakRoot(); 83 }; 84 #endif // INCLUDE_JFR 85 86 class ShenandoahSerialWeakRoots { 87 private: 88 JVMTI_ONLY(ShenandoahJVMTIWeakRoot _jvmti_weak_roots;) 89 JFR_ONLY(ShenandoahJFRWeakRoot _jfr_weak_roots;) 90 public: 91 void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id); 92 void weak_oops_do(OopClosure* cl, uint worker_id); 93 }; 94 95 template <bool CONCURRENT> 96 class ShenandoahVMRoot { 97 private: 98 OopStorage::ParState<CONCURRENT, false /* is_const */> _itr; 99 const ShenandoahPhaseTimings::GCParPhases _phase; 100 public: 101 ShenandoahVMRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase); 102 103 template <typename Closure> 104 void oops_do(Closure* cl, uint worker_id); 105 }; 106 107 template <bool CONCURRENT> 108 class ShenandoahWeakRoot : public ShenandoahVMRoot<CONCURRENT> { 109 public: 110 ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase); 111 }; 112 113 template <> 114 class ShenandoahWeakRoot<false /*concurrent*/> { 115 private: 116 OopStorage::ParState<false /*concurrent*/, false /*is_const*/> _itr; 117 const ShenandoahPhaseTimings::GCParPhases _phase; 118 119 public: 120 ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase); 121 122 template <typename IsAliveClosure, typename KeepAliveClosure> 123 void weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id); 124 }; 125 126 template <bool CONCURRENT> 127 class ShenandoahWeakRoots { 128 private: 129 ShenandoahWeakRoot<CONCURRENT> _jni_roots; 130 ShenandoahWeakRoot<CONCURRENT> _string_table_roots; 131 ShenandoahWeakRoot<CONCURRENT> _resolved_method_table_roots; 132 ShenandoahWeakRoot<CONCURRENT> _vm_roots; 133 134 public: 135 ShenandoahWeakRoots(); 136 137 template <typename Closure> 138 void oops_do(Closure* cl, uint worker_id = 0); 139 }; 140 141 template <> 142 class ShenandoahWeakRoots<false /*concurrent */> { 143 private: 144 ShenandoahWeakRoot<false /*concurrent*/> _jni_roots; 145 ShenandoahWeakRoot<false /*concurrent*/> _string_table_roots; 146 ShenandoahWeakRoot<false /*concurrent*/> _resolved_method_table_roots; 147 ShenandoahWeakRoot<false /*concurrent*/> _vm_roots; 148 public: 149 ShenandoahWeakRoots(); 150 151 template <typename Closure> 152 void oops_do(Closure* cl, uint worker_id = 0); 153 154 template <typename IsAliveClosure, typename KeepAliveClosure> 155 void weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id); 156 }; 157 158 template <bool CONCURRENT> 159 class ShenandoahVMRoots { 160 private: 161 ShenandoahVMRoot<CONCURRENT> _jni_handle_roots; 162 ShenandoahVMRoot<CONCURRENT> _vm_global_roots; 163 164 public: 165 ShenandoahVMRoots(); 166 167 template <typename T> 168 void oops_do(T* cl, uint worker_id = 0); 169 }; 170 171 class ShenandoahThreadRoots { 172 private: 173 const bool _is_par; 174 public: 175 ShenandoahThreadRoots(bool is_par); 176 ~ShenandoahThreadRoots(); 177 178 void oops_do(OopClosure* oops_cl, CodeBlobClosure* code_cl, uint worker_id); 179 void threads_do(ThreadClosure* tc, uint worker_id); 180 }; 181 182 class ShenandoahStringDedupRoots { 183 public: 184 ShenandoahStringDedupRoots(); 185 ~ShenandoahStringDedupRoots(); 186 187 void oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id); 188 }; 189 190 template <typename ITR> 191 class ShenandoahCodeCacheRoots { 192 private: 193 ITR _coderoots_iterator; 194 public: 195 ShenandoahCodeCacheRoots(); 196 ~ShenandoahCodeCacheRoots(); 197 198 void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id); 199 }; 200 201 template <bool CONCURRENT, bool SINGLE_THREADED> 202 class ShenandoahClassLoaderDataRoots { 203 public: 204 ShenandoahClassLoaderDataRoots(); 205 ~ShenandoahClassLoaderDataRoots(); 206 207 void always_strong_cld_do(CLDClosure* clds, uint worker_id = 0); 208 void cld_do(CLDClosure* clds, uint worker_id = 0); 209 }; 210 211 class ShenandoahRootProcessor : public StackObj { 212 private: 213 ShenandoahHeap* const _heap; 214 const ShenandoahPhaseTimings::Phase _phase; 215 public: 216 ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase); 217 ~ShenandoahRootProcessor(); 218 219 ShenandoahHeap* heap() const { return _heap; } 220 }; 221 222 template <typename ITR> 223 class ShenandoahRootScanner : public ShenandoahRootProcessor { 224 private: 225 ShenandoahSerialRoots _serial_roots; 226 ShenandoahThreadRoots _thread_roots; 227 ShenandoahCodeCacheRoots<ITR> _code_roots; 228 ShenandoahVMRoots<false /*concurrent*/ > _vm_roots; 229 ShenandoahStringDedupRoots _dedup_roots; 230 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/> 231 _cld_roots; 232 public: 233 ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase); 234 235 // Apply oops, clds and blobs to all strongly reachable roots in the system, 236 // during class unloading cycle 237 void strong_roots_do(uint worker_id, OopClosure* cl); 238 void strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); 239 240 // Apply oops, clds and blobs to all strongly reachable roots and weakly reachable 241 // roots when class unloading is disabled during this cycle 242 void roots_do(uint worker_id, OopClosure* cl); 243 void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); 244 }; 245 246 typedef ShenandoahRootScanner<ShenandoahAllCodeRootsIterator> ShenandoahAllRootScanner; 247 typedef ShenandoahRootScanner<ShenandoahCsetCodeRootsIterator> ShenandoahCSetRootScanner; 248 249 // This scanner is only for SH::object_iteration() and only supports single-threaded 250 // root scanning 251 class ShenandoahHeapIterationRootScanner : public ShenandoahRootProcessor { 252 private: 253 ShenandoahSerialRoots _serial_roots; 254 ShenandoahThreadRoots _thread_roots; 255 ShenandoahVMRoots<false /*concurrent*/> _vm_roots; 256 ShenandoahClassLoaderDataRoots<false /*concurrent*/, true /*single threaded*/> 257 _cld_roots; 258 ShenandoahSerialWeakRoots _serial_weak_roots; 259 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots; 260 ShenandoahStringDedupRoots _dedup_roots; 261 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; 262 263 public: 264 ShenandoahHeapIterationRootScanner(); 265 266 void roots_do(OopClosure* cl); 267 }; 268 269 // Evacuate all roots at a safepoint 270 class ShenandoahRootEvacuator : public ShenandoahRootProcessor { 271 private: 272 ShenandoahSerialRoots _serial_roots; 273 ShenandoahVMRoots<false /*concurrent*/> _vm_roots; 274 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/> 275 _cld_roots; 276 ShenandoahThreadRoots _thread_roots; 277 ShenandoahSerialWeakRoots _serial_weak_roots; 278 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots; 279 ShenandoahStringDedupRoots _dedup_roots; 280 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; 281 bool _include_concurrent_roots; 282 bool _include_concurrent_code_roots; 283 public: 284 ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase, 285 bool include_concurrent_roots, bool _include_concurrent_code_roots); 286 287 void roots_do(uint worker_id, OopClosure* oops); 288 }; 289 290 // Update all roots at a safepoint 291 class ShenandoahRootUpdater : public ShenandoahRootProcessor { 292 private: 293 ShenandoahSerialRoots _serial_roots; 294 ShenandoahVMRoots<false /*concurrent*/> _vm_roots; 295 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/> 296 _cld_roots; 297 ShenandoahThreadRoots _thread_roots; 298 ShenandoahSerialWeakRoots _serial_weak_roots; 299 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots; 300 ShenandoahStringDedupRoots _dedup_roots; 301 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; 302 303 public: 304 ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase); 305 306 template<typename IsAlive, typename KeepAlive> 307 void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive); 308 309 void strong_roots_do(uint worker_id, OopClosure* oops_cl); 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