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