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 clds_do(CLDClosure* strong_clds, CLDClosure* weak_clds, uint worker_id); 116 }; 117 118 class ShenandoahRootProcessor : public StackObj { 119 private: 120 ShenandoahHeap* const _heap; 121 const ShenandoahPhaseTimings::Phase _phase; 122 public: 123 ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase); 124 ~ShenandoahRootProcessor(); 125 126 ShenandoahHeap* heap() const { return _heap; } 127 }; 128 129 template <typename ITR> 130 class ShenandoahRootScanner : public ShenandoahRootProcessor { 131 private: 132 ShenandoahSerialRoots _serial_roots; 133 ShenandoahJNIHandleRoots _jni_roots; 134 ShenandoahClassLoaderDataRoots _cld_roots; 135 ShenandoahThreadRoots _thread_roots; 136 ShenandoahCodeCacheRoots<ITR> _code_roots; 137 public: 138 ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase); 139 140 // Apply oops, clds and blobs to all strongly reachable roots in the system, 141 // during class unloading cycle 142 void strong_roots_do(uint worker_id, OopClosure* cl); 143 void strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); 144 145 // Apply oops, clds and blobs to all strongly reachable roots and weakly reachable 146 // roots when class unloading is disabled during this cycle 147 void roots_do(uint worker_id, OopClosure* cl); 148 void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL); 149 // For heap object iteration 150 void roots_do_unchecked(OopClosure* cl); 151 void strong_roots_do_unchecked(OopClosure* cl); 152 }; 153 154 typedef ShenandoahRootScanner<ShenandoahAllCodeRootsIterator> ShenandoahAllRootScanner; 155 typedef ShenandoahRootScanner<ShenandoahCsetCodeRootsIterator> ShenandoahCSetRootScanner; 156 157 // Evacuate all roots at a safepoint 158 class ShenandoahRootEvacuator : public ShenandoahRootProcessor { 159 private: 160 ShenandoahSerialRoots _serial_roots; 161 ShenandoahJNIHandleRoots _jni_roots; 162 ShenandoahClassLoaderDataRoots _cld_roots; 163 ShenandoahThreadRoots _thread_roots; 164 ShenandoahWeakRoots _weak_roots; 165 ShenandoahStringDedupRoots _dedup_roots; 166 ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots; 167 168 public: 169 ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase); 170 171 void roots_do(uint worker_id, OopClosure* oops); 172 }; 173 174 // Update all roots at a safepoint 175 class ShenandoahRootUpdater : public ShenandoahRootProcessor { 176 private: 177 ShenandoahSerialRoots _serial_roots; 178 ShenandoahJNIHandleRoots _jni_roots; 179 ShenandoahClassLoaderDataRoots _cld_roots; 180 ShenandoahThreadRoots _thread_roots; 181 ShenandoahWeakRoots _weak_roots; 182 ShenandoahStringDedupRoots _dedup_roots; 183 ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots; 184 const bool _update_code_cache; 185 186 public: 187 ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool update_code_cache); 188 189 template<typename IsAlive, typename KeepAlive> 190 void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive); 191 }; 192 193 // Adjuster all roots at a safepoint during full gc 194 class ShenandoahRootAdjuster : public ShenandoahRootProcessor { 195 private: 196 ShenandoahSerialRoots _serial_roots; 197 ShenandoahJNIHandleRoots _jni_roots; 198 ShenandoahClassLoaderDataRoots _cld_roots; 199 ShenandoahThreadRoots _thread_roots; 200 ShenandoahWeakRoots _weak_roots; 201 ShenandoahStringDedupRoots _dedup_roots; 202 ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots; 203 204 public: 205 ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase); 206 207 void roots_do(uint worker_id, OopClosure* oops); 208 }; 209 210 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_HPP