1 /* 2 * Copyright (c) 2017, 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_VM_GC_SHENANDOAH_SHENANDOAHCODEROOTS_HPP 25 #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHCODEROOTS_HPP 26 27 #include "code/codeCache.hpp" 28 #include "gc/shenandoah/shenandoahSharedVariables.hpp" 29 #include "gc/shenandoah/shenandoahLock.hpp" 30 #include "gc/shenandoah/shenandoahPadding.hpp" 31 #include "memory/allocation.hpp" 32 #include "memory/iterator.hpp" 33 34 class ShenandoahHeap; 35 class ShenandoahHeapRegion; 36 37 class ShenandoahParallelCodeHeapIterator { 38 friend class CodeCache; 39 private: 40 CodeHeap* _heap; 41 shenandoah_padding(0); 42 volatile int _claimed_idx; 43 volatile bool _finished; 44 shenandoah_padding(1); 45 public: 46 ShenandoahParallelCodeHeapIterator(CodeHeap* heap); 47 void parallel_blobs_do(CodeBlobClosure* f); 48 }; 49 50 class ShenandoahParallelCodeCacheIterator { 51 friend class CodeCache; 52 private: 53 ShenandoahParallelCodeHeapIterator* _iters; 54 int _length; 55 56 private: 57 // Noncopyable. 58 ShenandoahParallelCodeCacheIterator(const ShenandoahParallelCodeCacheIterator& o); 59 ShenandoahParallelCodeCacheIterator& operator=(const ShenandoahParallelCodeCacheIterator& o); 60 public: 61 ShenandoahParallelCodeCacheIterator(const GrowableArray<CodeHeap*>* heaps); 62 ~ShenandoahParallelCodeCacheIterator(); 63 void parallel_blobs_do(CodeBlobClosure* f); 64 }; 65 66 // ShenandoahNMethod tuple records the internal locations of oop slots within the nmethod. 67 // This allows us to quickly scan the oops without doing the nmethod-internal scans, that 68 // sometimes involves parsing the machine code. Note it does not record the oops themselves, 69 // because it would then require handling these tuples as the new class of roots. 70 class ShenandoahNMethod : public CHeapObj<mtGC> { 71 private: 72 nmethod* _nm; 73 oop** _oops; 74 int _oops_count; 75 76 public: 77 ShenandoahNMethod(nmethod *nm, GrowableArray<oop*>* oops); 78 ~ShenandoahNMethod(); 79 80 nmethod* nm() { 81 return _nm; 82 } 83 84 bool has_cset_oops(ShenandoahHeap* heap); 85 86 void assert_alive_and_correct() NOT_DEBUG_RETURN; 87 void assert_same_oops(GrowableArray<oop*>* oops) NOT_DEBUG_RETURN; 88 89 static bool find_with_nmethod(void* nm, ShenandoahNMethod* other) { 90 return other->_nm == nm; 91 } 92 }; 93 94 class ShenandoahCodeRootsIterator { 95 friend class ShenandoahCodeRoots; 96 protected: 97 ShenandoahHeap* _heap; 98 ShenandoahParallelCodeCacheIterator _par_iterator; 99 ShenandoahSharedFlag _seq_claimed; 100 DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile size_t)); 101 volatile size_t _claimed; 102 DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0); 103 protected: 104 ShenandoahCodeRootsIterator(); 105 ~ShenandoahCodeRootsIterator(); 106 107 template<bool CSET_FILTER> 108 void dispatch_parallel_blobs_do(CodeBlobClosure *f); 109 110 template<bool CSET_FILTER> 111 void fast_parallel_blobs_do(CodeBlobClosure *f); 112 }; 113 114 class ShenandoahAllCodeRootsIterator : public ShenandoahCodeRootsIterator { 115 public: 116 ShenandoahAllCodeRootsIterator() : ShenandoahCodeRootsIterator() {}; 117 void possibly_parallel_blobs_do(CodeBlobClosure *f); 118 }; 119 120 class ShenandoahCsetCodeRootsIterator : public ShenandoahCodeRootsIterator { 121 public: 122 ShenandoahCsetCodeRootsIterator() : ShenandoahCodeRootsIterator() {}; 123 void possibly_parallel_blobs_do(CodeBlobClosure* f); 124 }; 125 126 class ShenandoahCodeRoots : public AllStatic { 127 friend class ShenandoahHeap; 128 friend class ShenandoahCodeRootsIterator; 129 130 public: 131 static void initialize(); 132 static void add_nmethod(nmethod* nm); 133 static void remove_nmethod(nmethod* nm); 134 135 private: 136 static GrowableArray<ShenandoahNMethod*>* _recorded_nms; 137 static ShenandoahLock _recorded_nms_lock; 138 }; 139 140 #endif //SHARE_VM_GC_SHENANDOAH_SHENANDOAHCODEROOTS_HPP