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 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 ShenandoahJNIHandleRoots<> _jni_roots; 141 ShenandoahClassLoaderDataRoots _cld_roots; 142 ShenandoahThreadRoots _thread_roots; 143 ShenandoahCodeCacheRoots<ITR> _code_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 // For heap object iteration 157 void roots_do_unchecked(OopClosure* cl); 158 void strong_roots_do_unchecked(OopClosure* cl); 159 }; 160 161 typedef ShenandoahRootScanner<ShenandoahAllCodeRootsIterator> ShenandoahAllRootScanner; 162 typedef ShenandoahRootScanner<ShenandoahCsetCodeRootsIterator> ShenandoahCSetRootScanner; 163 164 // Evacuate all roots at a safepoint 165 class ShenandoahRootEvacuator : public ShenandoahRootProcessor { 166 private: 167 ShenandoahSerialRoots _serial_roots; 168 ShenandoahJNIHandleRoots<> _jni_roots; 169 ShenandoahClassLoaderDataRoots _cld_roots; 170 ShenandoahThreadRoots _thread_roots; 171 ShenandoahWeakRoots _weak_roots; 172 ShenandoahStringDedupRoots _dedup_roots; 173 ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots; 174 bool _include_concurrent_roots; 175 176 public: 177 ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool include_concurrent_roots); 178 179 void roots_do(uint worker_id, OopClosure* oops); 180 }; 181 182 // Update all roots at a safepoint 183 class ShenandoahRootUpdater : public ShenandoahRootProcessor { 184 private: 185 ShenandoahSerialRoots _serial_roots; 186 ShenandoahJNIHandleRoots<> _jni_roots; 187 ShenandoahClassLoaderDataRoots _cld_roots; 188 ShenandoahThreadRoots _thread_roots; 189 ShenandoahWeakRoots _weak_roots; 190 ShenandoahStringDedupRoots _dedup_roots; 191 ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots; 192 const bool _update_code_cache; 193 194 public: 195 ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool update_code_cache); 196 197 template<typename IsAlive, typename KeepAlive> 198 void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive); 199 }; 200 201 // Adjuster all roots at a safepoint during full gc 202 class ShenandoahRootAdjuster : public ShenandoahRootProcessor { 203 private: 204 ShenandoahSerialRoots _serial_roots; 205 ShenandoahJNIHandleRoots<> _jni_roots; 206 ShenandoahClassLoaderDataRoots _cld_roots; 207 ShenandoahThreadRoots _thread_roots; 208 ShenandoahWeakRoots _weak_roots; 209 ShenandoahStringDedupRoots _dedup_roots; 210 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; 211 212 public: 213 ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase); 214 215 void roots_do(uint worker_id, OopClosure* oops); 216 }; 217 218 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP