1 /*
  2  * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 #ifndef SHARE_GC_Z_ZROOTSITERATOR_HPP
 25 #define SHARE_GC_Z_ZROOTSITERATOR_HPP
 26 
 27 #include "gc/shared/oopStorageParState.hpp"
 28 #include "gc/shared/oopStorageSetParState.hpp"
 29 #include "gc/shared/suspendibleThreadSet.hpp"
 30 #include "memory/allocation.hpp"
 31 #include "memory/iterator.hpp"
 32 #include "runtime/thread.hpp"
 33 #include "runtime/threadSMR.hpp"
 34 #include "utilities/globalDefinitions.hpp"
 35 
 36 class ZRootsIteratorClosure;
 37 
 38 typedef OopStorage::ParState<true /* concurrent */, false /* is_const */> ZOopStorageIterator;
 39 typedef OopStorageSetStrongParState<true /* concurrent */, false /* is_const */> ZOopStorageSetStrongIterator;
 40 typedef OopStorageSetWeakParState<true /* concurrent */, false /* is_const */> ZOopStorageSetWeakIterator;
 41 
 42 template <typename T, void (T::*F)(ZRootsIteratorClosure*)>
 43 class ZSerialOopsDo {
 44 private:
 45   T* const      _iter;
 46   volatile bool _claimed;
 47 
 48 public:
 49   ZSerialOopsDo(T* iter);
 50   void oops_do(ZRootsIteratorClosure* cl);
 51 };
 52 
 53 template <typename T, void (T::*F)(ZRootsIteratorClosure*)>
 54 class ZParallelOopsDo {
 55 private:
 56   T* const      _iter;
 57   volatile bool _completed;
 58 
 59 public:
 60   ZParallelOopsDo(T* iter);
 61   void oops_do(ZRootsIteratorClosure* cl);
 62 };
 63 
 64 template <typename T, void (T::*F)(BoolObjectClosure*, ZRootsIteratorClosure*)>
 65 class ZSerialWeakOopsDo {
 66 private:
 67   T* const      _iter;
 68   volatile bool _claimed;
 69 
 70 public:
 71   ZSerialWeakOopsDo(T* iter);
 72   void weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl);
 73 };
 74 
 75 template <typename T, void (T::*F)(BoolObjectClosure*, ZRootsIteratorClosure*)>
 76 class ZParallelWeakOopsDo {
 77 private:
 78   T* const      _iter;
 79   volatile bool _completed;
 80 
 81 public:
 82   ZParallelWeakOopsDo(T* iter);
 83   void weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl);
 84 };
 85 
 86 class ZRootsIteratorClosure : public OopClosure {
 87 public:
 88   virtual void do_thread(Thread* thread) {}
 89 
 90   virtual bool should_disarm_nmethods() const {
 91     return false;
 92   }
 93 };
 94 
 95 class ZJavaThreadsIterator {
 96 private:
 97   ThreadsListHandle _threads;
 98   volatile uint     _claimed;
 99 
100   uint claim();
101 
102 public:
103   ZJavaThreadsIterator();
104 
105   void threads_do(ThreadClosure* cl);
106 };
107 
108 class ZRootsIterator {
109 private:
110   const bool           _visit_jvmti_weak_export;
111   ZJavaThreadsIterator _java_threads_iter;
112 
113   void do_universe(ZRootsIteratorClosure* cl);
114   void do_object_synchronizer(ZRootsIteratorClosure* cl);
115   void do_management(ZRootsIteratorClosure* cl);
116   void do_jvmti_export(ZRootsIteratorClosure* cl);
117   void do_jvmti_weak_export(ZRootsIteratorClosure* cl);
118   void do_vm_thread(ZRootsIteratorClosure* cl);
119   void do_java_threads(ZRootsIteratorClosure* cl);
120   void do_code_cache(ZRootsIteratorClosure* cl);
121 
122   ZSerialOopsDo<ZRootsIterator, &ZRootsIterator::do_universe>            _universe;
123   ZSerialOopsDo<ZRootsIterator, &ZRootsIterator::do_object_synchronizer> _object_synchronizer;
124   ZSerialOopsDo<ZRootsIterator, &ZRootsIterator::do_management>          _management;
125   ZSerialOopsDo<ZRootsIterator, &ZRootsIterator::do_jvmti_export>        _jvmti_export;
126   ZSerialOopsDo<ZRootsIterator, &ZRootsIterator::do_jvmti_weak_export>   _jvmti_weak_export;
127   ZSerialOopsDo<ZRootsIterator, &ZRootsIterator::do_vm_thread>           _vm_thread;
128   ZParallelOopsDo<ZRootsIterator, &ZRootsIterator::do_java_threads>      _java_threads;
129   ZParallelOopsDo<ZRootsIterator, &ZRootsIterator::do_code_cache>        _code_cache;
130 
131 public:
132   ZRootsIterator(bool visit_jvmti_weak_export = false);
133   ~ZRootsIterator();
134 
135   void oops_do(ZRootsIteratorClosure* cl);
136 };
137 
138 class ZConcurrentRootsIterator {
139 private:
140   ZOopStorageSetStrongIterator _oop_storage_set_iter;
141   const int                    _cld_claim;
142 
143   void do_oop_storage_set(ZRootsIteratorClosure* cl);
144   void do_class_loader_data_graph(ZRootsIteratorClosure* cl);
145 
146   ZParallelOopsDo<ZConcurrentRootsIterator, &ZConcurrentRootsIterator::do_oop_storage_set>         _oop_storage_set;
147   ZParallelOopsDo<ZConcurrentRootsIterator, &ZConcurrentRootsIterator::do_class_loader_data_graph> _class_loader_data_graph;
148 
149 public:
150   ZConcurrentRootsIterator(int cld_claim);
151   ~ZConcurrentRootsIterator();
152 
153   void oops_do(ZRootsIteratorClosure* cl);
154 };
155 
156 class ZConcurrentRootsIteratorClaimStrong : public ZConcurrentRootsIterator {
157 public:
158   ZConcurrentRootsIteratorClaimStrong() :
159       ZConcurrentRootsIterator(ClassLoaderData::_claim_strong) {}
160 };
161 
162 class ZConcurrentRootsIteratorClaimOther : public ZConcurrentRootsIterator {
163 public:
164   ZConcurrentRootsIteratorClaimOther() :
165       ZConcurrentRootsIterator(ClassLoaderData::_claim_other) {}
166 };
167 
168 class ZConcurrentRootsIteratorClaimNone : public ZConcurrentRootsIterator {
169 public:
170   ZConcurrentRootsIteratorClaimNone() :
171       ZConcurrentRootsIterator(ClassLoaderData::_claim_none) {}
172 };
173 
174 class ZWeakRootsIterator {
175 private:
176   void do_jvmti_weak_export(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl);
177   void do_jfr_weak(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl);
178 
179   ZSerialWeakOopsDo<ZWeakRootsIterator, &ZWeakRootsIterator::do_jvmti_weak_export> _jvmti_weak_export;
180   ZSerialWeakOopsDo<ZWeakRootsIterator, &ZWeakRootsIterator::do_jfr_weak>          _jfr_weak;
181 
182 public:
183   ZWeakRootsIterator();
184   ~ZWeakRootsIterator();
185 
186   void weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl);
187   void oops_do(ZRootsIteratorClosure* cl);
188 };
189 
190 class ZConcurrentWeakRootsIterator {
191 private:
192   ZOopStorageSetWeakIterator _oop_storage_set_iter;
193 
194   void do_oop_storage_set(ZRootsIteratorClosure* cl);
195 
196   ZParallelOopsDo<ZConcurrentWeakRootsIterator, &ZConcurrentWeakRootsIterator::do_oop_storage_set> _oop_storage_set;
197 
198 public:
199   ZConcurrentWeakRootsIterator();
200 
201   void oops_do(ZRootsIteratorClosure* cl);
202 
203   void notify();
204 };
205 
206 #endif // SHARE_GC_Z_ZROOTSITERATOR_HPP