1 /* 2 * Copyright (c) 2015, 2019, 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 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/> 230 _cld_roots; 231 public: 232 ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase); 233 234 // Apply oops, clds and blobs to all strongly reachable roots in the system, 235 // during class unloading cycle 236 void strong_roots_do(uint worker_id, OopClosure* cl); 237 void strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); 238 239 // Apply oops, clds and blobs to all strongly reachable roots and weakly reachable 240 // roots when class unloading is disabled during this cycle 241 void roots_do(uint worker_id, OopClosure* cl); 242 void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); 243 }; 244 245 typedef ShenandoahRootScanner<ShenandoahAllCodeRootsIterator> ShenandoahAllRootScanner; 246 typedef ShenandoahRootScanner<ShenandoahCsetCodeRootsIterator> ShenandoahCSetRootScanner; 247 248 // This scanner is only for SH::object_iteration() and only supports single-threaded 249 // root scanning 250 class ShenandoahHeapIterationRootScanner : public ShenandoahRootProcessor { 251 private: 252 ShenandoahSerialRoots _serial_roots; 253 ShenandoahThreadRoots _thread_roots; 254 ShenandoahVMRoots<false /*concurrent*/> _vm_roots; 255 ShenandoahClassLoaderDataRoots<false /*concurrent*/, true /*single threaded*/> 256 _cld_roots; 257 ShenandoahSerialWeakRoots _serial_weak_roots; 258 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots; 259 ShenandoahStringDedupRoots _dedup_roots; 260 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; 261 262 public: 263 ShenandoahHeapIterationRootScanner(); 264 265 void roots_do(OopClosure* cl); 266 void strong_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<ShenandoahCsetCodeRootsIterator> _code_roots; 281 bool _include_concurrent_roots; 282 283 public: 284 ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool include_concurrent_roots); 285 286 void roots_do(uint worker_id, OopClosure* oops); 287 }; 288 289 // Update all roots at a safepoint 290 class ShenandoahRootUpdater : public ShenandoahRootProcessor { 291 private: 292 ShenandoahSerialRoots _serial_roots; 293 ShenandoahVMRoots<false /*concurrent*/> _vm_roots; 294 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/> 295 _cld_roots; 296 ShenandoahThreadRoots _thread_roots; 297 ShenandoahSerialWeakRoots _serial_weak_roots; 298 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots; 299 ShenandoahStringDedupRoots _dedup_roots; 300 ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots; 301 302 public: 303 ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase); 304 305 template<typename IsAlive, typename KeepAlive> 306 void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive); 307 }; 308 309 // Adjuster all roots at a safepoint during full gc 310 class ShenandoahRootAdjuster : public ShenandoahRootProcessor { 311 private: 312 ShenandoahSerialRoots _serial_roots; 313 ShenandoahVMRoots<false /*concurrent*/> _vm_roots; 314 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/> 315 _cld_roots; 316 ShenandoahThreadRoots _thread_roots; 317 ShenandoahSerialWeakRoots _serial_weak_roots; 318 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots; 319 ShenandoahStringDedupRoots _dedup_roots; 320 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; 321 322 public: 323 ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase); 324 325 void roots_do(uint worker_id, OopClosure* oops); 326 }; 327 328 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP