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 const static bool FixRelocations = true;
263 };
264
265 class MarkingNMethodClosure : public NMethodClosure {
266 OopClosure* _cl;
267
268 public:
269 MarkingNMethodClosure(OopClosure* cl) : _cl(cl) {}
270
271 // Called for each nmethod.
272 virtual void do_nmethod(nmethod* nm);
273 };
274
275 // MonitorClosure is used for iterating over monitors in the monitors cache
276
277 class ObjectMonitor;
278
279 class MonitorClosure : public StackObj {
280 public:
281 // called for each monitor in cache
282 virtual void do_monitor(ObjectMonitor* m) = 0;
283 };
284
285 // A closure that is applied without any arguments.
286 class VoidClosure : public StackObj {
287 public:
288 virtual void do_void() = 0;
289 };
290
291
292 // YieldClosure is intended for use by iteration loops
293 // to incrementalize their work, allowing interleaving
294 // of an interruptible task so as to allow other
295 // threads to run (which may not otherwise be able to access
296 // exclusive resources, for instance). Additionally, the
297 // closure also allows for aborting an ongoing iteration
298 // by means of checking the return value from the polling
299 // call.
300 class YieldClosure : public StackObj {
301 public:
302 virtual bool should_return() = 0;
303
304 // Yield on a fine-grain level. The check in case of not yielding should be very fast.
305 virtual bool should_return_fine_grain() { return false; }
306 };
307
308 class SymbolClosure : public StackObj {
309 public:
310 virtual void do_symbol(Symbol**) = 0;
311 };
312
313 template <typename E>
314 class CompareClosure : public Closure {
315 public:
316 virtual int do_compare(const E&, const E&) = 0;
317 };
318
319 class OopIteratorClosureDispatch {
320 public:
321 template <typename OopClosureType> static void oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass);
322 template <typename OopClosureType> static void oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass, MemRegion mr);
323 template <typename OopClosureType> static void oop_oop_iterate_backwards(OopClosureType* cl, oop obj, Klass* klass);
324 };
325
326 #endif // SHARE_MEMORY_ITERATOR_HPP