Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/memory/iterator.hpp
40949 views
1
/*
2
* Copyright (c) 1997, 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
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(NULL) { }
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
virtual bool do_metadata() = 0;
103
virtual void do_klass(Klass* k) = 0;
104
virtual void do_cld(ClassLoaderData* cld) = 0;
105
};
106
107
// An OopIterateClosure that can be used when there's no need to visit the Metadata.
108
class BasicOopIterateClosure : public OopIterateClosure {
109
public:
110
BasicOopIterateClosure(ReferenceDiscoverer* rd = NULL) : OopIterateClosure(rd) {}
111
112
virtual bool do_metadata() { return false; }
113
virtual void do_klass(Klass* k) { ShouldNotReachHere(); }
114
virtual void do_cld(ClassLoaderData* cld) { ShouldNotReachHere(); }
115
};
116
117
class KlassClosure : public Closure {
118
public:
119
virtual void do_klass(Klass* k) = 0;
120
};
121
122
class CLDClosure : public Closure {
123
public:
124
virtual void do_cld(ClassLoaderData* cld) = 0;
125
};
126
127
class MetadataClosure : public Closure {
128
public:
129
virtual void do_metadata(Metadata* md) = 0;
130
};
131
132
133
class CLDToOopClosure : public CLDClosure {
134
OopClosure* _oop_closure;
135
int _cld_claim;
136
137
public:
138
CLDToOopClosure(OopClosure* oop_closure,
139
int cld_claim) :
140
_oop_closure(oop_closure),
141
_cld_claim(cld_claim) {}
142
143
void do_cld(ClassLoaderData* cld);
144
};
145
146
template <int claim>
147
class ClaimingCLDToOopClosure : public CLDToOopClosure {
148
public:
149
ClaimingCLDToOopClosure(OopClosure* cl) : CLDToOopClosure(cl, claim) {}
150
};
151
152
class ClaimMetadataVisitingOopIterateClosure : public OopIterateClosure {
153
protected:
154
const int _claim;
155
156
public:
157
ClaimMetadataVisitingOopIterateClosure(int claim, ReferenceDiscoverer* rd = NULL) :
158
OopIterateClosure(rd),
159
_claim(claim) { }
160
161
virtual bool do_metadata() { return true; }
162
virtual void do_klass(Klass* k);
163
virtual void do_cld(ClassLoaderData* cld);
164
};
165
166
// The base class for all concurrent marking closures,
167
// that participates in class unloading.
168
// It's used to proxy through the metadata to the oops defined in them.
169
class MetadataVisitingOopIterateClosure: public ClaimMetadataVisitingOopIterateClosure {
170
public:
171
MetadataVisitingOopIterateClosure(ReferenceDiscoverer* rd = NULL);
172
};
173
174
// ObjectClosure is used for iterating through an object space
175
176
class ObjectClosure : public Closure {
177
public:
178
// Called for each object.
179
virtual void do_object(oop obj) = 0;
180
};
181
182
183
class BoolObjectClosure : public Closure {
184
public:
185
virtual bool do_object_b(oop obj) = 0;
186
};
187
188
class AlwaysTrueClosure: public BoolObjectClosure {
189
public:
190
bool do_object_b(oop p) { return true; }
191
};
192
193
class AlwaysFalseClosure : public BoolObjectClosure {
194
public:
195
bool do_object_b(oop p) { return false; }
196
};
197
198
// Applies an oop closure to all ref fields in objects iterated over in an
199
// object iteration.
200
class ObjectToOopClosure: public ObjectClosure {
201
OopIterateClosure* _cl;
202
public:
203
void do_object(oop obj);
204
ObjectToOopClosure(OopIterateClosure* cl) : _cl(cl) {}
205
};
206
207
// SpaceClosure is used for iterating over spaces
208
209
class Space;
210
class CompactibleSpace;
211
212
class SpaceClosure : public StackObj {
213
public:
214
// Called for each space
215
virtual void do_space(Space* s) = 0;
216
};
217
218
class CompactibleSpaceClosure : public StackObj {
219
public:
220
// Called for each compactible space
221
virtual void do_space(CompactibleSpace* s) = 0;
222
};
223
224
225
// CodeBlobClosure is used for iterating through code blobs
226
// in the code cache or on thread stacks
227
228
class CodeBlobClosure : public Closure {
229
public:
230
// Called for each code blob.
231
virtual void do_code_blob(CodeBlob* cb) = 0;
232
};
233
234
// Applies an oop closure to all ref fields in code blobs
235
// iterated over in an object iteration.
236
class CodeBlobToOopClosure : public CodeBlobClosure {
237
OopClosure* _cl;
238
bool _fix_relocations;
239
protected:
240
void do_nmethod(nmethod* nm);
241
public:
242
// If fix_relocations(), then cl must copy objects to their new location immediately to avoid
243
// patching nmethods with the old locations.
244
CodeBlobToOopClosure(OopClosure* cl, bool fix_relocations) : _cl(cl), _fix_relocations(fix_relocations) {}
245
virtual void do_code_blob(CodeBlob* cb);
246
247
bool fix_relocations() const { return _fix_relocations; }
248
const static bool FixRelocations = true;
249
};
250
251
class MarkingCodeBlobClosure : public CodeBlobToOopClosure {
252
public:
253
MarkingCodeBlobClosure(OopClosure* cl, bool fix_relocations) : CodeBlobToOopClosure(cl, fix_relocations) {}
254
// Called for each code blob, but at most once per unique blob.
255
256
virtual void do_code_blob(CodeBlob* cb);
257
};
258
259
class NMethodClosure : public Closure {
260
public:
261
virtual void do_nmethod(nmethod* n) = 0;
262
};
263
264
class CodeBlobToNMethodClosure : public CodeBlobClosure {
265
NMethodClosure* const _nm_cl;
266
267
public:
268
CodeBlobToNMethodClosure(NMethodClosure* nm_cl) : _nm_cl(nm_cl) {}
269
270
virtual void do_code_blob(CodeBlob* cb);
271
};
272
273
// MonitorClosure is used for iterating over monitors in the monitors cache
274
275
class ObjectMonitor;
276
277
class MonitorClosure : public StackObj {
278
public:
279
// called for each monitor in cache
280
virtual void do_monitor(ObjectMonitor* m) = 0;
281
};
282
283
// A closure that is applied without any arguments.
284
class VoidClosure : public StackObj {
285
public:
286
// I would have liked to declare this a pure virtual, but that breaks
287
// in mysterious ways, for unknown reasons.
288
virtual void do_void();
289
};
290
291
292
// YieldClosure is intended for use by iteration loops
293
// to incrementalize their work, allowing interleaving
294
// of an interruptable 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
// Abstract closure for serializing data (read or write).
309
310
class SerializeClosure : public Closure {
311
public:
312
// Return bool indicating whether closure implements read or write.
313
virtual bool reading() const = 0;
314
315
// Read/write the void pointer pointed to by p.
316
virtual void do_ptr(void** p) = 0;
317
318
// Read/write the 32-bit unsigned integer pointed to by p.
319
virtual void do_u4(u4* p) = 0;
320
321
// Read/write the bool pointed to by p.
322
virtual void do_bool(bool* p) = 0;
323
324
// Read/write the region specified.
325
virtual void do_region(u_char* start, size_t size) = 0;
326
327
// Check/write the tag. If reading, then compare the tag against
328
// the passed in value and fail is they don't match. This allows
329
// for verification that sections of the serialized data are of the
330
// correct length.
331
virtual void do_tag(int tag) = 0;
332
333
// Read/write the oop
334
virtual void do_oop(oop* o) = 0;
335
336
bool writing() {
337
return !reading();
338
}
339
};
340
341
class SymbolClosure : public StackObj {
342
public:
343
virtual void do_symbol(Symbol**) = 0;
344
345
// Clear LSB in symbol address; it can be set by CPSlot.
346
static Symbol* load_symbol(Symbol** p) {
347
return (Symbol*)(intptr_t(*p) & ~1);
348
}
349
350
// Store symbol, adjusting new pointer if the original pointer was adjusted
351
// (symbol references in constant pool slots have their LSB set to 1).
352
static void store_symbol(Symbol** p, Symbol* sym) {
353
*p = (Symbol*)(intptr_t(sym) | (intptr_t(*p) & 1));
354
}
355
};
356
357
template <typename E>
358
class CompareClosure : public Closure {
359
public:
360
virtual int do_compare(const E&, const E&) = 0;
361
};
362
363
// Dispatches to the non-virtual functions if OopClosureType has
364
// a concrete implementation, otherwise a virtual call is taken.
365
class Devirtualizer {
366
public:
367
template <typename OopClosureType, typename T> static void do_oop(OopClosureType* closure, T* p);
368
template <typename OopClosureType> static void do_klass(OopClosureType* closure, Klass* k);
369
template <typename OopClosureType> static void do_cld(OopClosureType* closure, ClassLoaderData* cld);
370
template <typename OopClosureType> static bool do_metadata(OopClosureType* closure);
371
};
372
373
class OopIteratorClosureDispatch {
374
public:
375
template <typename OopClosureType> static void oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass);
376
template <typename OopClosureType> static void oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass, MemRegion mr);
377
template <typename OopClosureType> static void oop_oop_iterate_backwards(OopClosureType* cl, oop obj, Klass* klass);
378
};
379
380
#endif // SHARE_MEMORY_ITERATOR_HPP
381
382