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/shared/strongRootsScope.hpp" 33 #include "gc/shared/weakProcessor.hpp" 34 #include "gc/shared/weakProcessorPhaseTimes.hpp" 35 #include "gc/shared/workgroup.hpp" 36 #include "memory/allocation.hpp" 37 #include "memory/iterator.hpp" 38 39 class ShenandoahSerialRoot { 40 public: 41 typedef void (*OopsDo)(OopClosure*); 42 private: 43 volatile bool _claimed; 44 const OopsDo _oops_do; 45 const ShenandoahPhaseTimings::GCParPhases _phase; 46 47 public: 48 ShenandoahSerialRoot(OopsDo oops_do, ShenandoahPhaseTimings::GCParPhases); 49 void oops_do(OopClosure* cl, uint worker_id); 50 }; 51 52 class ShenandoahSerialRoots { 53 private: 54 ShenandoahSerialRoot _universe_root; 55 ShenandoahSerialRoot _object_synchronizer_root; 56 ShenandoahSerialRoot _management_root; 57 ShenandoahSerialRoot _system_dictionary_root; 58 ShenandoahSerialRoot _jvmti_root; 59 public: 60 ShenandoahSerialRoots(); 61 void oops_do(OopClosure* cl, uint worker_id); 62 }; 63 64 template <bool CONCURRENT = false> 65 class ShenandoahJNIHandleRoots { 66 private: 67 volatile bool _claimed; 68 OopStorage::ParState<CONCURRENT, false /* is_const */> _itr; 69 public: 70 ShenandoahJNIHandleRoots(); 71 72 template <typename T> 73 void oops_do(T* cl, uint worker_id = 0); 74 }; 75 76 class ShenandoahThreadRoots { 77 private: 78 const bool _is_par; 79 public: 80 ShenandoahThreadRoots(bool is_par); 81 ~ShenandoahThreadRoots(); 82 83 void oops_do(OopClosure* oops_cl, CodeBlobClosure* code_cl, uint worker_id); 84 void threads_do(ThreadClosure* tc, uint worker_id); 85 }; 86 87 class ShenandoahWeakRoots { 88 private: 89 WeakProcessorPhaseTimes _process_timings; 90 WeakProcessor::Task _task; 91 public: 92 ShenandoahWeakRoots(uint n_workers); 93 ~ShenandoahWeakRoots(); 94 95 template <typename IsAlive, typename KeepAlive> 96 void oops_do(IsAlive* is_alive, KeepAlive* keep_alive, uint worker_id); 97 }; 98 99 class ShenandoahStringDedupRoots { 100 public: 101 ShenandoahStringDedupRoots(); 102 ~ShenandoahStringDedupRoots(); 103 104 void oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id); 105 }; 106 107 template <typename ITR> 108 class ShenandoahCodeCacheRoots { 109 private: 110 ITR _coderoots_iterator; 111 public: 112 ShenandoahCodeCacheRoots(); 113 ~ShenandoahCodeCacheRoots(); 114 115 void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id); 116 }; 117 118 template <bool CONCURRENT = false> 119 class ShenandoahClassLoaderDataRoots { 120 public: 121 ShenandoahClassLoaderDataRoots(); 122 ~ShenandoahClassLoaderDataRoots(); 123 124 void always_strong_cld_do(CLDClosure* clds, uint worker_id = 0); 125 void cld_do(CLDClosure* clds, uint worker_id = 0); 126 }; 127 128 class ShenandoahRootProcessor : public StackObj { 129 private: 130 ShenandoahHeap* const _heap; 131 const ShenandoahPhaseTimings::Phase _phase; 132 public: 133 ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase); 134 ~ShenandoahRootProcessor(); 135 136 ShenandoahHeap* heap() const { return _heap; } 137 }; 138 139 template <typename ITR> 140 class ShenandoahRootScanner : public ShenandoahRootProcessor { 141 private: 142 ShenandoahSerialRoots _serial_roots; 143 ShenandoahJNIHandleRoots<> _jni_roots; 144 ShenandoahClassLoaderDataRoots<> _cld_roots; 145 ShenandoahThreadRoots _thread_roots; 146 ShenandoahCodeCacheRoots<ITR> _code_roots; 147 public: 148 ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase); 149 150 // Apply oops, clds and blobs to all strongly reachable roots in the system, 151 // during class unloading cycle 152 void strong_roots_do(uint worker_id, OopClosure* cl); 153 void strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); 154 155 // Apply oops, clds and blobs to all strongly reachable roots and weakly reachable 156 // roots when class unloading is disabled during this cycle 157 void roots_do(uint worker_id, OopClosure* cl); 158 void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); 159 // For heap object iteration 160 void roots_do_unchecked(OopClosure* cl); 161 void strong_roots_do_unchecked(OopClosure* cl); 162 }; 163 164 typedef ShenandoahRootScanner<ShenandoahAllCodeRootsIterator> ShenandoahAllRootScanner; 165 typedef ShenandoahRootScanner<ShenandoahCsetCodeRootsIterator> ShenandoahCSetRootScanner; 166 167 // Evacuate all roots at a safepoint 168 class ShenandoahRootEvacuator : public ShenandoahRootProcessor { 169 private: 170 ShenandoahSerialRoots _serial_roots; 171 ShenandoahJNIHandleRoots<> _jni_roots; 172 ShenandoahClassLoaderDataRoots<> _cld_roots; 173 ShenandoahThreadRoots _thread_roots; 174 ShenandoahWeakRoots _weak_roots; 175 ShenandoahStringDedupRoots _dedup_roots; 176 ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots; 177 bool _include_concurrent_roots; 178 179 public: 180 ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool include_concurrent_roots); 181 182 void roots_do(uint worker_id, OopClosure* oops); 183 }; 184 185 // Update all roots at a safepoint 186 class ShenandoahRootUpdater : public ShenandoahRootProcessor { 187 private: 188 ShenandoahSerialRoots _serial_roots; 189 ShenandoahJNIHandleRoots<> _jni_roots; 190 ShenandoahClassLoaderDataRoots<> _cld_roots; 191 ShenandoahThreadRoots _thread_roots; 192 ShenandoahWeakRoots _weak_roots; 193 ShenandoahStringDedupRoots _dedup_roots; 194 ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots; 195 const bool _update_code_cache; 196 197 public: 198 ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool update_code_cache); 199 200 template<typename IsAlive, typename KeepAlive> 201 void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive); 202 }; 203 204 // Adjuster all roots at a safepoint during full gc 205 class ShenandoahRootAdjuster : public ShenandoahRootProcessor { 206 private: 207 ShenandoahSerialRoots _serial_roots; 208 ShenandoahJNIHandleRoots<> _jni_roots; 209 ShenandoahClassLoaderDataRoots<> _cld_roots; 210 ShenandoahThreadRoots _thread_roots; 211 ShenandoahWeakRoots _weak_roots; 212 ShenandoahStringDedupRoots _dedup_roots; 213 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; 214 215 public: 216 ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase); 217 218 void roots_do(uint worker_id, OopClosure* oops); 219 }; 220 221 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP