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> 65 class ShenandoahJNIHandleRoots { 66 private: 67 OopStorage::ParState<CONCURRENT, false /* is_const */> _itr; 68 public: 69 ShenandoahJNIHandleRoots(); 70 71 template <typename T> 72 void oops_do(T* cl, uint worker_id = 0); 73 }; 74 75 class ShenandoahThreadRoots { 76 private: 77 const bool _is_par; 78 public: 79 ShenandoahThreadRoots(bool is_par); 80 ~ShenandoahThreadRoots(); 81 82 void oops_do(OopClosure* oops_cl, CodeBlobClosure* code_cl, uint worker_id); 83 void threads_do(ThreadClosure* tc, uint worker_id); 84 }; 85 86 class ShenandoahWeakRoots { 87 private: 88 WeakProcessorPhaseTimes _process_timings; 89 WeakProcessor::Task _task; 90 public: 91 ShenandoahWeakRoots(uint n_workers); 92 ~ShenandoahWeakRoots(); 93 94 template <typename IsAlive, typename KeepAlive> 95 void oops_do(IsAlive* is_alive, KeepAlive* keep_alive, uint worker_id); 96 }; 97 98 class ShenandoahStringDedupRoots { 99 public: 100 ShenandoahStringDedupRoots(); 101 ~ShenandoahStringDedupRoots(); 102 103 void oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id); 104 }; 105 106 template <typename ITR> 107 class ShenandoahCodeCacheRoots { 108 private: 109 ITR _coderoots_iterator; 110 public: 111 ShenandoahCodeCacheRoots(); 112 ~ShenandoahCodeCacheRoots(); 113 114 void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id); 115 }; 116 117 template <bool SINGLE_THREADED> 118 class ShenandoahClassLoaderDataRoots { 119 public: 120 ShenandoahClassLoaderDataRoots(); 121 122 void clds_do(CLDClosure* strong_clds, CLDClosure* weak_clds, uint worker_id); 123 }; 124 125 class ShenandoahRootProcessor : public StackObj { 126 private: 127 ShenandoahHeap* const _heap; 128 const ShenandoahPhaseTimings::Phase _phase; 129 public: 130 ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase); 131 ~ShenandoahRootProcessor(); 132 133 ShenandoahHeap* heap() const { return _heap; } 134 }; 135 136 template <typename ITR> 137 class ShenandoahRootScanner : public ShenandoahRootProcessor { 138 private: 139 ShenandoahSerialRoots _serial_roots; 140 ShenandoahThreadRoots _thread_roots; 141 ShenandoahCodeCacheRoots<ITR> _code_roots; 142 ShenandoahJNIHandleRoots<false /*concurrent*/ > _jni_roots; 143 ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots; 144 public: 145 ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase); 146 147 // Apply oops, clds and blobs to all strongly reachable roots in the system, 148 // during class unloading cycle 149 void strong_roots_do(uint worker_id, OopClosure* cl); 150 void strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); 151 152 // Apply oops, clds and blobs to all strongly reachable roots and weakly reachable 153 // roots when class unloading is disabled during this cycle 154 void roots_do(uint worker_id, OopClosure* cl); 155 void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); 156 }; 157 158 typedef ShenandoahRootScanner<ShenandoahAllCodeRootsIterator> ShenandoahAllRootScanner; 159 typedef ShenandoahRootScanner<ShenandoahCsetCodeRootsIterator> ShenandoahCSetRootScanner; 160 161 // This scanner is only for SH::object_iteration() and only supports single-threaded 162 // root scanning 163 class ShenandoahHeapIterationRootScanner : public ShenandoahRootProcessor { 164 private: 165 ShenandoahSerialRoots _serial_roots; 166 ShenandoahThreadRoots _thread_roots; 167 ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots; 168 ShenandoahClassLoaderDataRoots<true /*single threaded*/> _cld_roots; 169 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; 170 171 public: 172 ShenandoahHeapIterationRootScanner(); 173 174 void roots_do(OopClosure* cl); 175 void strong_roots_do(OopClosure* cl); 176 }; 177 178 // Evacuate all roots at a safepoint 179 class ShenandoahRootEvacuator : public ShenandoahRootProcessor { 180 private: 181 ShenandoahSerialRoots _serial_roots; 182 ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots; 183 ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots; 184 ShenandoahThreadRoots _thread_roots; 185 ShenandoahWeakRoots _weak_roots; 186 ShenandoahStringDedupRoots _dedup_roots; 187 ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots; 188 bool _include_concurrent_roots; 189 190 public: 191 ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool include_concurrent_roots); 192 193 void roots_do(uint worker_id, OopClosure* oops); 194 }; 195 196 // Update all roots at a safepoint 197 class ShenandoahRootUpdater : public ShenandoahRootProcessor { 198 private: 199 ShenandoahSerialRoots _serial_roots; 200 ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots; 201 ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots; 202 ShenandoahThreadRoots _thread_roots; 203 ShenandoahWeakRoots _weak_roots; 204 ShenandoahStringDedupRoots _dedup_roots; 205 ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots; 206 const bool _update_code_cache; 207 208 public: 209 ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool update_code_cache); 210 211 template<typename IsAlive, typename KeepAlive> 212 void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive); 213 }; 214 215 // Adjuster all roots at a safepoint during full gc 216 class ShenandoahRootAdjuster : public ShenandoahRootProcessor { 217 private: 218 ShenandoahSerialRoots _serial_roots; 219 ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots; 220 ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots; 221 ShenandoahThreadRoots _thread_roots; 222 ShenandoahWeakRoots _weak_roots; 223 ShenandoahStringDedupRoots _dedup_roots; 224 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; 225 226 public: 227 ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase); 228 229 void roots_do(uint worker_id, OopClosure* oops); 230 }; 231 232 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP