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