1 /*
  2  * Copyright (c) 1997, 2024, 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 
 25 #ifndef SHARE_MEMORY_ITERATOR_HPP
 26 #define SHARE_MEMORY_ITERATOR_HPP
 27 
 28 #include "memory/allocation.hpp"
 29 #include "memory/memRegion.hpp"
 30 #include "oops/oopsHierarchy.hpp"
 31 
 32 class CodeBlob;
 33 class nmethod;
 34 class ReferenceDiscoverer;
 35 class DataLayout;
 36 class KlassClosure;
 37 class ClassLoaderData;
 38 class Symbol;
 39 class Metadata;
 40 class Thread;
 41 
 42 // The following classes are C++ `closures` for iterating over objects, roots and spaces
 43 
 44 class Closure : public StackObj { };
 45 
 46 // Thread iterator
 47 class ThreadClosure {
 48  public:
 49   virtual void do_thread(Thread* thread) = 0;
 50 };
 51 
 52 // OopClosure is used for iterating through references to Java objects.
 53 class OopClosure : public Closure {
 54  public:
 55   virtual void do_oop(oop* o) = 0;
 56   virtual void do_oop(narrowOop* o) = 0;
 57   virtual void do_oop_no_buffering(oop* o) { do_oop(o); }
 58   virtual void do_oop_no_buffering(narrowOop* o) { do_oop(o); }
 59 };
 60 
 61 class DoNothingClosure : public OopClosure {
 62  public:
 63   virtual void do_oop(oop* p)       {}
 64   virtual void do_oop(narrowOop* p) {}
 65 };
 66 extern DoNothingClosure do_nothing_cl;
 67 
 68 // OopIterateClosure adds extra code to be run during oop iterations.
 69 // This is needed by the GC and is extracted to a separate type to not
 70 // pollute the OopClosure interface.
 71 class OopIterateClosure : public OopClosure {
 72  private:
 73   ReferenceDiscoverer* _ref_discoverer;
 74 
 75  protected:
 76   OopIterateClosure(ReferenceDiscoverer* rd) : _ref_discoverer(rd) { }
 77   OopIterateClosure() : _ref_discoverer(nullptr) { }
 78   ~OopIterateClosure() { }
 79 
 80   void set_ref_discoverer_internal(ReferenceDiscoverer* rd) { _ref_discoverer = rd; }
 81 
 82  public:
 83   ReferenceDiscoverer* ref_discoverer() const { return _ref_discoverer; }
 84 
 85   // Iteration of InstanceRefKlasses differ depending on the closure,
 86   // the below enum describes the different alternatives.
 87   enum ReferenceIterationMode {
 88     DO_DISCOVERY,                // Apply closure and discover references
 89     DO_FIELDS,                   // Apply closure to all fields
 90     DO_FIELDS_EXCEPT_REFERENT    // Apply closure to all fields except the referent field
 91   };
 92 
 93   // The default iteration mode is to do discovery.
 94   virtual ReferenceIterationMode reference_iteration_mode() { return DO_DISCOVERY; }
 95 
 96   // If the do_metadata functions return "true",
 97   // we invoke the following when running oop_iterate():
 98   //
 99   // 1) do_klass on the header klass pointer.
100   // 2) do_klass on the klass pointer in the mirrors.
101   // 3) do_cld   on the class loader data in class loaders.
102   //
103   // Used to determine metadata liveness for class unloading GCs.
104 
105   virtual bool do_metadata() = 0;
106   virtual void do_klass(Klass* k) = 0;
107   virtual void do_cld(ClassLoaderData* cld) = 0;
108 
109   // Class redefinition needs to get notified about methods from stackChunkOops
110   virtual void do_method(Method* m) = 0;
111   // The code cache unloading needs to get notified about methods from stackChunkOops
112   virtual void do_nmethod(nmethod* nm) = 0;
113 };
114 
115 // An OopIterateClosure that can be used when there's no need to visit the Metadata.
116 class BasicOopIterateClosure : public OopIterateClosure {
117 public:
118   BasicOopIterateClosure(ReferenceDiscoverer* rd = nullptr) : OopIterateClosure(rd) {}
119 
120   virtual bool do_metadata() { return false; }
121   virtual void do_klass(Klass* k) { ShouldNotReachHere(); }
122   virtual void do_cld(ClassLoaderData* cld) { ShouldNotReachHere(); }
123   virtual void do_method(Method* m) { ShouldNotReachHere(); }
124   virtual void do_nmethod(nmethod* nm) { ShouldNotReachHere(); }
125 };
126 
127 // Interface for applying an OopClosure to a set of oops.
128 class OopIterator {
129 public:
130   virtual void oops_do(OopClosure* cl) = 0;
131 };
132 
133 enum class derived_base : intptr_t;
134 enum class derived_pointer : intptr_t;
135 class DerivedOopClosure : public Closure {
136  public:
137   enum { SkipNull = true };
138   virtual void do_derived_oop(derived_base* base, derived_pointer* derived) = 0;
139 };
140 
141 class BufferedValueClosure : public Closure {
142 public:
143   virtual void do_buffered_value(oop* p) = 0;
144 };
145 
146 class KlassClosure : public Closure {
147  public:
148   virtual void do_klass(Klass* k) = 0;
149 };
150 
151 class CLDClosure : public Closure {
152  public:
153   virtual void do_cld(ClassLoaderData* cld) = 0;
154 };
155 
156 class MetadataClosure : public Closure {
157  public:
158   virtual void do_metadata(Metadata* md) = 0;
159 };
160 
161 
162 class CLDToOopClosure : public CLDClosure {
163   OopClosure*       _oop_closure;
164   int               _cld_claim;
165 
166  public:
167   CLDToOopClosure(OopClosure* oop_closure,
168                   int cld_claim) :
169       _oop_closure(oop_closure),
170       _cld_claim(cld_claim) {}
171 
172   void do_cld(ClassLoaderData* cld);
173 };
174 
175 template <int claim>
176 class ClaimingCLDToOopClosure : public CLDToOopClosure {
177 public:
178   ClaimingCLDToOopClosure(OopClosure* cl) : CLDToOopClosure(cl, claim) {}
179 };
180 
181 class ClaimMetadataVisitingOopIterateClosure : public OopIterateClosure {
182  protected:
183   const int _claim;
184 
185  public:
186   ClaimMetadataVisitingOopIterateClosure(int claim, ReferenceDiscoverer* rd = nullptr) :
187       OopIterateClosure(rd),
188       _claim(claim) { }
189 
190   virtual bool do_metadata() { return true; }
191   virtual void do_klass(Klass* k);
192   virtual void do_cld(ClassLoaderData* cld);
193   virtual void do_method(Method* m);
194   virtual void do_nmethod(nmethod* nm);
195 };
196 
197 // The base class for all concurrent marking closures,
198 // that participates in class unloading.
199 // It's used to proxy through the metadata to the oops defined in them.
200 class MetadataVisitingOopIterateClosure: public ClaimMetadataVisitingOopIterateClosure {
201  public:
202   MetadataVisitingOopIterateClosure(ReferenceDiscoverer* rd = nullptr);
203 };
204 
205 // ObjectClosure is used for iterating through an object space
206 
207 class ObjectClosure : public Closure {
208  public:
209   // Called for each object.
210   virtual void do_object(oop obj) = 0;
211 };
212 
213 class BoolObjectClosure : public Closure {
214  public:
215   virtual bool do_object_b(oop obj) = 0;
216 };
217 
218 class OopFieldClosure {
219 public:
220   virtual void do_field(oop base, oop* p) = 0;
221 };
222 
223 class AlwaysTrueClosure: public BoolObjectClosure {
224  public:
225   bool do_object_b(oop p) { return true; }
226 };
227 
228 class AlwaysFalseClosure : public BoolObjectClosure {
229  public:
230   bool do_object_b(oop p) { return false; }
231 };
232 
233 // Applies an oop closure to all ref fields in objects iterated over in an
234 // object iteration.
235 class ObjectToOopClosure: public ObjectClosure {
236   OopIterateClosure* _cl;
237 public:
238   void do_object(oop obj);
239   ObjectToOopClosure(OopIterateClosure* cl) : _cl(cl) {}
240 };
241 
242 // NMethodClosure is used for iterating through nmethods
243 // in the code cache or on thread stacks
244 
245 class NMethodClosure : public Closure {
246  public:
247   virtual void do_nmethod(nmethod* n) = 0;
248 };
249 
250 // Applies an oop closure to all ref fields in nmethods
251 // iterated over in an object iteration.
252 class NMethodToOopClosure : public NMethodClosure {
253  protected:
254   OopClosure* _cl;
255   bool _fix_relocations;
256  public:
257   // If fix_relocations(), then cl must copy objects to their new location immediately to avoid
258   // patching nmethods with the old locations.
259   NMethodToOopClosure(OopClosure* cl, bool fix_relocations) : _cl(cl), _fix_relocations(fix_relocations) {}
260   void do_nmethod(nmethod* nm) override;
261 
262   bool fix_relocations() const { return _fix_relocations; }
263   const static bool FixRelocations = true;
264 };
265 
266 class MarkingNMethodClosure : public NMethodToOopClosure {
267   bool _keepalive_nmethods;
268 
269  public:
270   MarkingNMethodClosure(OopClosure* cl, bool fix_relocations, bool keepalive_nmethods) :
271       NMethodToOopClosure(cl, fix_relocations),
272       _keepalive_nmethods(keepalive_nmethods) {}
273 
274   // Called for each nmethod.
275   virtual void do_nmethod(nmethod* nm);
276 };
277 
278 // MonitorClosure is used for iterating over monitors in the monitors cache
279 
280 class ObjectMonitor;
281 
282 class MonitorClosure : public StackObj {
283  public:
284   // called for each monitor in cache
285   virtual void do_monitor(ObjectMonitor* m) = 0;
286 };
287 
288 // A closure that is applied without any arguments.
289 class VoidClosure : public StackObj {
290  public:
291   virtual void do_void() = 0;
292 };
293 
294 
295 // YieldClosure is intended for use by iteration loops
296 // to incrementalize their work, allowing interleaving
297 // of an interruptible task so as to allow other
298 // threads to run (which may not otherwise be able to access
299 // exclusive resources, for instance). Additionally, the
300 // closure also allows for aborting an ongoing iteration
301 // by means of checking the return value from the polling
302 // call.
303 class YieldClosure : public StackObj {
304 public:
305  virtual bool should_return() = 0;
306 
307  // Yield on a fine-grain level. The check in case of not yielding should be very fast.
308  virtual bool should_return_fine_grain() { return false; }
309 };
310 
311 class SymbolClosure : public StackObj {
312  public:
313   virtual void do_symbol(Symbol**) = 0;
314 };
315 
316 template <typename E>
317 class CompareClosure : public Closure {
318 public:
319     virtual int do_compare(const E&, const E&) = 0;
320 };
321 
322 class OopIteratorClosureDispatch {
323  public:
324   template <typename OopClosureType> static void oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass);
325   template <typename OopClosureType> static void oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass, MemRegion mr);
326   template <typename OopClosureType> static void oop_oop_iterate_backwards(OopClosureType* cl, oop obj, Klass* klass);
327 };
328 
329 #endif // SHARE_MEMORY_ITERATOR_HPP
--- EOF ---