rev 55429 : 8226311: Shenandoah: Concurrent evacuation of OopStorage backed weak roots
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 volatile bool _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 ShenandoahWeakRoot { 97 private: 98 OopStorage::ParState<CONCURRENT, false /* is_const */> _itr; 99 const ShenandoahPhaseTimings::GCParPhases _phase; 100 public: 101 ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase); 102 103 template <typename Closure> 104 void oops_do(Closure* cl, uint worker_id); 105 }; 106 107 template <> 108 class ShenandoahWeakRoot<false /*concurrent*/> { 109 private: 110 OopStorage::ParState<false /*concurrent*/, false /*is_const*/> _itr; 111 const ShenandoahPhaseTimings::GCParPhases _phase; 112 113 public: 114 ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase); 115 116 template <typename IsAliveClosure, typename KeepAliveClosure> 117 void weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id); 118 }; 119 120 template <bool CONCURRENT> 121 class ShenandoahWeakRoots { 122 private: 123 ShenandoahWeakRoot<CONCURRENT> _jni_roots; 124 ShenandoahWeakRoot<CONCURRENT> _string_table_roots; 125 ShenandoahWeakRoot<CONCURRENT> _resolved_method_table_roots; 126 ShenandoahWeakRoot<CONCURRENT> _vm_roots; 127 128 public: 129 ShenandoahWeakRoots(); 130 131 template <typename Closure> 132 void oops_do(Closure* cl, uint worker_id = 0); 133 }; 134 135 template <> 136 class ShenandoahWeakRoots<false /*concurrent */> { 137 private: 138 ShenandoahWeakRoot<false /*concurrent*/> _jni_roots; 139 ShenandoahWeakRoot<false /*concurrent*/> _string_table_roots; 140 ShenandoahWeakRoot<false /*concurrent*/> _resolved_method_table_roots; 141 ShenandoahWeakRoot<false /*concurrent*/> _vm_roots; 142 public: 143 ShenandoahWeakRoots(); 144 145 template <typename Closure> 146 void oops_do(Closure* cl, uint worker_id = 0); 147 148 template <typename IsAliveClosure, typename KeepAliveClosure> 149 void weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id); 150 }; 151 152 template <bool CONCURRENT> 153 class ShenandoahJNIHandleRoots { 154 private: 155 OopStorage::ParState<CONCURRENT, false /*is_const*/> _itr; 156 public: 157 ShenandoahJNIHandleRoots(); 158 159 template <typename T> 160 void oops_do(T* cl, uint worker_id = 0); 161 }; 162 163 class ShenandoahThreadRoots { 164 private: 165 const bool _is_par; 166 public: 167 ShenandoahThreadRoots(bool is_par); 168 ~ShenandoahThreadRoots(); 169 170 void oops_do(OopClosure* oops_cl, CodeBlobClosure* code_cl, uint worker_id); 171 void threads_do(ThreadClosure* tc, uint worker_id); 172 }; 173 174 class ShenandoahStringDedupRoots { 175 public: 176 ShenandoahStringDedupRoots(); 177 ~ShenandoahStringDedupRoots(); 178 179 void oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id); 180 }; 181 182 template <typename ITR> 183 class ShenandoahCodeCacheRoots { 184 private: 185 ITR _coderoots_iterator; 186 public: 187 ShenandoahCodeCacheRoots(); 188 ~ShenandoahCodeCacheRoots(); 189 190 void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id); 191 }; 192 193 class ShenandoahClassLoaderDataRoots { 194 public: 195 ShenandoahClassLoaderDataRoots(); 196 197 void clds_do(CLDClosure* strong_clds, CLDClosure* weak_clds, uint worker_id); 198 }; 199 200 class ShenandoahRootProcessor : public StackObj { 201 private: 202 ShenandoahHeap* const _heap; 203 const ShenandoahPhaseTimings::Phase _phase; 204 public: 205 ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase); 206 ~ShenandoahRootProcessor(); 207 208 ShenandoahHeap* heap() const { return _heap; } 209 }; 210 211 template <typename ITR> 212 class ShenandoahRootScanner : public ShenandoahRootProcessor { 213 private: 214 ShenandoahSerialRoots _serial_roots; 215 ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots; 216 ShenandoahClassLoaderDataRoots _cld_roots; 217 ShenandoahThreadRoots _thread_roots; 218 ShenandoahCodeCacheRoots<ITR> _code_roots; 219 public: 220 ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase); 221 222 // Apply oops, clds and blobs to all strongly reachable roots in the system, 223 // during class unloading cycle 224 void strong_roots_do(uint worker_id, OopClosure* cl); 225 void strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); 226 227 // Apply oops, clds and blobs to all strongly reachable roots and weakly reachable 228 // roots when class unloading is disabled during this cycle 229 void roots_do(uint worker_id, OopClosure* cl); 230 void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); 231 // For heap object iteration 232 void roots_do_unchecked(OopClosure* cl); 233 void strong_roots_do_unchecked(OopClosure* cl); 234 }; 235 236 typedef ShenandoahRootScanner<ShenandoahAllCodeRootsIterator> ShenandoahAllRootScanner; 237 typedef ShenandoahRootScanner<ShenandoahCsetCodeRootsIterator> ShenandoahCSetRootScanner; 238 239 // Evacuate all roots at a safepoint 240 class ShenandoahRootEvacuator : public ShenandoahRootProcessor { 241 private: 242 ShenandoahSerialRoots _serial_roots; 243 ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots; 244 ShenandoahClassLoaderDataRoots _cld_roots; 245 ShenandoahThreadRoots _thread_roots; 246 ShenandoahSerialWeakRoots _serial_weak_roots; 247 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots; 248 ShenandoahStringDedupRoots _dedup_roots; 249 ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots; 250 bool _include_concurrent_roots; 251 252 public: 253 ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool include_concurrent_roots); 254 255 void roots_do(uint worker_id, OopClosure* oops); 256 }; 257 258 // Update all roots at a safepoint 259 class ShenandoahRootUpdater : public ShenandoahRootProcessor { 260 private: 261 ShenandoahSerialRoots _serial_roots; 262 ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots; 263 ShenandoahClassLoaderDataRoots _cld_roots; 264 ShenandoahThreadRoots _thread_roots; 265 ShenandoahSerialWeakRoots _serial_weak_roots; 266 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots; 267 ShenandoahStringDedupRoots _dedup_roots; 268 ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots; 269 const bool _update_code_cache; 270 271 public: 272 ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool update_code_cache); 273 274 template<typename IsAlive, typename KeepAlive> 275 void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive); 276 }; 277 278 // Adjuster all roots at a safepoint during full gc 279 class ShenandoahRootAdjuster : public ShenandoahRootProcessor { 280 private: 281 ShenandoahSerialRoots _serial_roots; 282 ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots; 283 ShenandoahClassLoaderDataRoots _cld_roots; 284 ShenandoahThreadRoots _thread_roots; 285 ShenandoahSerialWeakRoots _serial_weak_roots; 286 ShenandoahWeakRoots<false /*concurrent*/> _weak_roots; 287 ShenandoahStringDedupRoots _dedup_roots; 288 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; 289 290 public: 291 ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase); 292 293 void roots_do(uint worker_id, OopClosure* oops); 294 }; 295 296 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP --- EOF ---