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/oopStorageSetParState.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 template <bool CONCURRENT> 38 class ShenandoahVMWeakRoots { 39 private: 40 OopStorageSetWeakParState<CONCURRENT, false /* is_const */> _weak_roots; 41 ShenandoahPhaseTimings::Phase _phase; 42 43 public: 44 ShenandoahVMWeakRoots(ShenandoahPhaseTimings::Phase phase); 45 46 template <typename T> 47 void oops_do(T* cl, uint worker_id); 48 49 template <typename IsAlive, typename KeepAlive> 50 void weak_oops_do(IsAlive* is_alive, KeepAlive* keep_alive, uint worker_id); 51 52 void report_num_dead(); 53 }; 54 55 template <bool CONCURRENT> 56 class ShenandoahVMRoots { 57 private: 58 OopStorageSetStrongParState<CONCURRENT, false /* is_const */> _strong_roots; 59 ShenandoahPhaseTimings::Phase _phase; 60 61 public: 62 ShenandoahVMRoots(ShenandoahPhaseTimings::Phase phase); 63 64 template <typename T> 65 void oops_do(T* cl, uint worker_id); 66 }; 67 68 class ShenandoahThreadRoots { 69 private: 70 ShenandoahPhaseTimings::Phase _phase; 71 const bool _is_par; 72 public: 73 ShenandoahThreadRoots(ShenandoahPhaseTimings::Phase phase, bool is_par); 74 ~ShenandoahThreadRoots(); 75 76 void oops_do(OopClosure* oops_cl, CodeBlobClosure* code_cl, uint worker_id); 77 void threads_do(ThreadClosure* tc, uint worker_id); 78 }; 79 80 class ShenandoahStringDedupRoots { 81 private: 82 ShenandoahPhaseTimings::Phase _phase; 83 public: 84 ShenandoahStringDedupRoots(ShenandoahPhaseTimings::Phase phase); 85 ~ShenandoahStringDedupRoots(); 86 87 void oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id); 88 }; 89 90 class ShenandoahConcurrentStringDedupRoots { 91 private: 92 ShenandoahPhaseTimings::Phase _phase; 93 94 public: 95 ShenandoahConcurrentStringDedupRoots(ShenandoahPhaseTimings::Phase phase); 96 97 void prologue(); 98 void epilogue(); 99 100 void oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id); 101 }; 102 103 class ShenandoahCodeCacheRoots { 104 private: 105 ShenandoahPhaseTimings::Phase _phase; 106 ShenandoahCodeRootsIterator _coderoots_iterator; 107 public: 108 ShenandoahCodeCacheRoots(ShenandoahPhaseTimings::Phase phase); 109 ~ShenandoahCodeCacheRoots(); 110 111 void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id); 112 }; 113 114 template <bool CONCURRENT, bool SINGLE_THREADED> 115 class ShenandoahClassLoaderDataRoots { 116 private: 117 ShenandoahSharedSemaphore _semaphore; 118 ShenandoahPhaseTimings::Phase _phase; 119 worker_count(uint n_workers)120 static uint worker_count(uint n_workers) { 121 if (SINGLE_THREADED) return 1u; 122 123 // Limit concurrency a bit, otherwise it wastes resources when workers are tripping 124 // over each other. This also leaves free workers to process other parts of the root 125 // set, while admitted workers are busy with doing the CLDG walk. 126 return MAX2(1u, MIN2(ShenandoahSharedSemaphore::max_tokens(), n_workers / 2)); 127 } 128 129 public: 130 ShenandoahClassLoaderDataRoots(ShenandoahPhaseTimings::Phase phase, uint n_workers); 131 ~ShenandoahClassLoaderDataRoots(); 132 133 void always_strong_cld_do(CLDClosure* clds, uint worker_id); 134 void cld_do(CLDClosure* clds, uint worker_id); 135 136 private: 137 typedef void (*CldDo)(CLDClosure*); 138 void cld_do_impl(CldDo f, CLDClosure* clds, uint worker_id); 139 }; 140 141 class ShenandoahRootProcessor : public StackObj { 142 private: 143 ShenandoahHeap* const _heap; 144 const ShenandoahPhaseTimings::Phase _phase; 145 const ShenandoahGCWorkerPhase _worker_phase; 146 public: 147 ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase); 148 heap() const149 ShenandoahHeap* heap() const { return _heap; } 150 }; 151 152 class ShenandoahRootScanner : public ShenandoahRootProcessor { 153 private: 154 ShenandoahThreadRoots _thread_roots; 155 156 public: 157 ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase); 158 ~ShenandoahRootScanner(); 159 160 void roots_do(uint worker_id, OopClosure* cl); 161 162 private: 163 void roots_do(uint worker_id, OopClosure* oops, CodeBlobClosure* code, ThreadClosure* tc = NULL); 164 }; 165 166 template <bool CONCURRENT> 167 class ShenandoahConcurrentRootScanner { 168 private: 169 ShenandoahVMRoots<CONCURRENT> _vm_roots; 170 ShenandoahClassLoaderDataRoots<CONCURRENT, false /* single-threaded*/> 171 _cld_roots; 172 ShenandoahNMethodTableSnapshot* _codecache_snapshot; 173 ShenandoahPhaseTimings::Phase _phase; 174 175 public: 176 ShenandoahConcurrentRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase); 177 ~ShenandoahConcurrentRootScanner(); 178 179 void oops_do(OopClosure* oops, uint worker_id); 180 }; 181 182 // This scanner is only for SH::object_iteration() and only supports single-threaded 183 // root scanning 184 class ShenandoahHeapIterationRootScanner : public ShenandoahRootProcessor { 185 private: 186 ShenandoahThreadRoots _thread_roots; 187 ShenandoahVMRoots<false /*concurrent*/> _vm_roots; 188 ShenandoahClassLoaderDataRoots<false /*concurrent*/, true /*single threaded*/> 189 _cld_roots; 190 ShenandoahVMWeakRoots<false /*concurrent*/> _weak_roots; 191 ShenandoahConcurrentStringDedupRoots _dedup_roots; 192 ShenandoahCodeCacheRoots _code_roots; 193 194 public: 195 ShenandoahHeapIterationRootScanner(); 196 ~ShenandoahHeapIterationRootScanner(); 197 198 void roots_do(OopClosure* cl); 199 }; 200 201 // Evacuate all roots at a safepoint 202 class ShenandoahRootEvacuator : public ShenandoahRootProcessor { 203 private: 204 ShenandoahThreadRoots _thread_roots; 205 public: 206 ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase); 207 ~ShenandoahRootEvacuator(); 208 209 void roots_do(uint worker_id, OopClosure* oops); 210 }; 211 212 // Update all roots at a safepoint 213 class ShenandoahRootUpdater : public ShenandoahRootProcessor { 214 private: 215 ShenandoahVMRoots<false /*concurrent*/> _vm_roots; 216 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/> 217 _cld_roots; 218 ShenandoahThreadRoots _thread_roots; 219 ShenandoahVMWeakRoots<false /*concurrent*/> _weak_roots; 220 ShenandoahStringDedupRoots _dedup_roots; 221 ShenandoahCodeCacheRoots _code_roots; 222 223 public: 224 ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase); 225 226 template<typename IsAlive, typename KeepAlive> 227 void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive); 228 }; 229 230 // Adjuster all roots at a safepoint during full gc 231 class ShenandoahRootAdjuster : public ShenandoahRootProcessor { 232 private: 233 ShenandoahVMRoots<false /*concurrent*/> _vm_roots; 234 ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/> 235 _cld_roots; 236 ShenandoahThreadRoots _thread_roots; 237 ShenandoahVMWeakRoots<false /*concurrent*/> _weak_roots; 238 ShenandoahStringDedupRoots _dedup_roots; 239 ShenandoahCodeCacheRoots _code_roots; 240 241 public: 242 ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase); 243 244 void roots_do(uint worker_id, OopClosure* oops); 245 }; 246 247 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP 248