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 class ShenandoahJNIHandleRoots : public ShenandoahSerialRoot { 65 public: 66 ShenandoahJNIHandleRoots(); 67 }; 68 69 class ShenandoahThreadRoots { 70 private: 71 const bool _is_par; 72 public: 73 ShenandoahThreadRoots(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 ShenandoahWeakRoots { 81 private: 82 WeakProcessorPhaseTimes _process_timings; 83 WeakProcessor::Task _task; 84 public: 85 ShenandoahWeakRoots(uint n_workers); 86 ~ShenandoahWeakRoots(); 87 88 template <typename IsAlive, typename KeepAlive> 89 void oops_do(IsAlive* is_alive, KeepAlive* keep_alive, uint worker_id); 90 }; 91 92 class ShenandoahStringDedupRoots { 93 public: 94 ShenandoahStringDedupRoots(); 95 ~ShenandoahStringDedupRoots(); 96 97 void oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id); 98 }; 99 100 template <typename ITR> 101 class ShenandoahCodeCacheRoots { 102 private: 103 ITR _coderoots_iterator; 104 public: 105 ShenandoahCodeCacheRoots(); 106 ~ShenandoahCodeCacheRoots(); 107 108 void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id); 109 }; 110 111 class ShenandoahClassLoaderDataRoots { 112 public: 113 ShenandoahClassLoaderDataRoots(); 114 115 void always_strong_cld_do(CLDClosure* clds, uint worker_id); 116 void cld_do(CLDClosure* clds, uint worker_id); 117 }; 118 119 class ShenandoahRootProcessor : public StackObj { 120 private: 121 ShenandoahHeap* const _heap; 122 const ShenandoahPhaseTimings::Phase _phase; 123 public: 124 ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase); 125 ~ShenandoahRootProcessor(); 126 127 ShenandoahHeap* heap() const { return _heap; } 128 }; 129 130 template <typename ITR> 131 class ShenandoahRootScanner : public ShenandoahRootProcessor { 132 private: 133 ShenandoahSerialRoots _serial_roots; 134 ShenandoahJNIHandleRoots _jni_roots; 135 ShenandoahClassLoaderDataRoots _cld_roots; 136 ShenandoahThreadRoots _thread_roots; 137 ShenandoahCodeCacheRoots<ITR> _code_roots; 138 public: 139 ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase); 140 141 // Apply oops, clds and blobs to all strongly reachable roots in the system, 142 // during class unloading cycle 143 void strong_roots_do(uint worker_id, OopClosure* cl); 144 void strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); 145 146 // Apply oops, clds and blobs to all strongly reachable roots and weakly reachable 147 // roots when class unloading is disabled during this cycle 148 void roots_do(uint worker_id, OopClosure* cl); 149 void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); 150 // For heap object iteration 151 void roots_do_unchecked(OopClosure* cl); 152 void strong_roots_do_unchecked(OopClosure* cl); 153 }; 154 155 typedef ShenandoahRootScanner<ShenandoahAllCodeRootsIterator> ShenandoahAllRootScanner; 156 typedef ShenandoahRootScanner<ShenandoahCsetCodeRootsIterator> ShenandoahCSetRootScanner; 157 158 // Evacuate all roots at a safepoint 159 class ShenandoahRootEvacuator : public ShenandoahRootProcessor { 160 private: 161 ShenandoahSerialRoots _serial_roots; 162 ShenandoahJNIHandleRoots _jni_roots; 163 ShenandoahClassLoaderDataRoots _cld_roots; 164 ShenandoahThreadRoots _thread_roots; 165 ShenandoahWeakRoots _weak_roots; 166 ShenandoahStringDedupRoots _dedup_roots; 167 ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots; 168 169 public: 170 ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase); 171 172 void roots_do(uint worker_id, OopClosure* oops); 173 }; 174 175 // Update all roots at a safepoint 176 class ShenandoahRootUpdater : public ShenandoahRootProcessor { 177 private: 178 ShenandoahSerialRoots _serial_roots; 179 ShenandoahJNIHandleRoots _jni_roots; 180 ShenandoahClassLoaderDataRoots _cld_roots; 181 ShenandoahThreadRoots _thread_roots; 182 ShenandoahWeakRoots _weak_roots; 183 ShenandoahStringDedupRoots _dedup_roots; 184 ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots; 185 const bool _update_code_cache; 186 187 public: 188 ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool update_code_cache); 189 190 template<typename IsAlive, typename KeepAlive> 191 void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive); 192 }; 193 194 // Adjuster all roots at a safepoint during full gc 195 class ShenandoahRootAdjuster : public ShenandoahRootProcessor { 196 private: 197 ShenandoahSerialRoots _serial_roots; 198 ShenandoahJNIHandleRoots _jni_roots; 199 ShenandoahClassLoaderDataRoots _cld_roots; 200 ShenandoahThreadRoots _thread_roots; 201 ShenandoahWeakRoots _weak_roots; 202 ShenandoahStringDedupRoots _dedup_roots; 203 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; 204 205 public: 206 ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase); 207 208 void roots_do(uint worker_id, OopClosure* oops); 209 }; 210 211 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP