Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/runtime/handles.hpp
32285 views
1
/*
2
* Copyright (c) 1997, 2014, 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_VM_RUNTIME_HANDLES_HPP
26
#define SHARE_VM_RUNTIME_HANDLES_HPP
27
28
#include "oops/klass.hpp"
29
30
//------------------------------------------------------------------------------------------------------------------------
31
// In order to preserve oops during garbage collection, they should be
32
// allocated and passed around via Handles within the VM. A handle is
33
// simply an extra indirection allocated in a thread local handle area.
34
//
35
// A handle is a ValueObj, so it can be passed around as a value, can
36
// be used as a parameter w/o using &-passing, and can be returned as a
37
// return value.
38
//
39
// oop parameters and return types should be Handles whenever feasible.
40
//
41
// Handles are declared in a straight-forward manner, e.g.
42
//
43
// oop obj = ...;
44
// Handle h1(obj); // allocate new handle
45
// Handle h2(thread, obj); // faster allocation when current thread is known
46
// Handle h3; // declare handle only, no allocation occurs
47
// ...
48
// h3 = h1; // make h3 refer to same indirection as h1
49
// oop obj2 = h2(); // get handle value
50
// h1->print(); // invoking operation on oop
51
//
52
// Handles are specialized for different oop types to provide extra type
53
// information and avoid unnecessary casting. For each oop type xxxOop
54
// there is a corresponding handle called xxxHandle, e.g.
55
//
56
// oop Handle
57
// Method* methodHandle
58
// instanceOop instanceHandle
59
60
//------------------------------------------------------------------------------------------------------------------------
61
// Base class for all handles. Provides overloading of frequently
62
// used operators for ease of use.
63
64
class Handle VALUE_OBJ_CLASS_SPEC {
65
private:
66
oop* _handle;
67
68
protected:
69
oop obj() const { return _handle == NULL ? (oop)NULL : *_handle; }
70
oop non_null_obj() const { assert(_handle != NULL, "resolving NULL handle"); return *_handle; }
71
72
public:
73
// Constructors
74
Handle() { _handle = NULL; }
75
Handle(oop obj);
76
Handle(Thread* thread, oop obj);
77
78
// General access
79
oop operator () () const { return obj(); }
80
oop operator -> () const { return non_null_obj(); }
81
bool operator == (oop o) const { return obj() == o; }
82
bool operator == (const Handle& h) const { return obj() == h.obj(); }
83
84
// Null checks
85
bool is_null() const { return _handle == NULL; }
86
bool not_null() const { return _handle != NULL; }
87
88
// Debugging
89
void print() { obj()->print(); }
90
91
// Direct interface, use very sparingly.
92
// Used by JavaCalls to quickly convert handles and to create handles static data structures.
93
// Constructor takes a dummy argument to prevent unintentional type conversion in C++.
94
Handle(oop *handle, bool dummy) { _handle = handle; }
95
96
// Raw handle access. Allows easy duplication of Handles. This can be very unsafe
97
// since duplicates is only valid as long as original handle is alive.
98
oop* raw_value() { return _handle; }
99
static oop raw_resolve(oop *handle) { return handle == NULL ? (oop)NULL : *handle; }
100
};
101
102
// Specific Handles for different oop types
103
#define DEF_HANDLE(type, is_a) \
104
class type##Handle: public Handle { \
105
protected: \
106
type##Oop obj() const { return (type##Oop)Handle::obj(); } \
107
type##Oop non_null_obj() const { return (type##Oop)Handle::non_null_obj(); } \
108
\
109
public: \
110
/* Constructors */ \
111
type##Handle () : Handle() {} \
112
type##Handle (type##Oop obj) : Handle((oop)obj) { \
113
assert(is_null() || ((oop)obj)->is_a(), \
114
"illegal type"); \
115
} \
116
type##Handle (Thread* thread, type##Oop obj) : Handle(thread, (oop)obj) { \
117
assert(is_null() || ((oop)obj)->is_a(), "illegal type"); \
118
} \
119
\
120
/* Operators for ease of use */ \
121
type##Oop operator () () const { return obj(); } \
122
type##Oop operator -> () const { return non_null_obj(); } \
123
};
124
125
126
DEF_HANDLE(instance , is_instance )
127
DEF_HANDLE(array , is_array )
128
DEF_HANDLE(objArray , is_objArray )
129
DEF_HANDLE(typeArray , is_typeArray )
130
131
//------------------------------------------------------------------------------------------------------------------------
132
133
// Metadata Handles. Unlike oop Handles these are needed to prevent metadata
134
// from being reclaimed by RedefineClasses.
135
136
// Specific Handles for different oop types
137
#define DEF_METADATA_HANDLE(name, type) \
138
class name##Handle; \
139
class name##Handle : public StackObj { \
140
type* _value; \
141
Thread* _thread; \
142
protected: \
143
type* obj() const { return _value; } \
144
type* non_null_obj() const { assert(_value != NULL, "resolving NULL _value"); return _value; } \
145
\
146
public: \
147
/* Constructors */ \
148
name##Handle () : _value(NULL), _thread(NULL) {} \
149
name##Handle (type* obj); \
150
name##Handle (Thread* thread, type* obj); \
151
\
152
name##Handle (const name##Handle &h); \
153
name##Handle& operator=(const name##Handle &s); \
154
\
155
/* Destructor */ \
156
~name##Handle (); \
157
void remove(); \
158
\
159
/* Operators for ease of use */ \
160
type* operator () () const { return obj(); } \
161
type* operator -> () const { return non_null_obj(); } \
162
\
163
bool operator == (type* o) const { return obj() == o; } \
164
bool operator == (const name##Handle& h) const { return obj() == h.obj(); } \
165
\
166
/* Null checks */ \
167
bool is_null() const { return _value == NULL; } \
168
bool not_null() const { return _value != NULL; } \
169
};
170
171
172
DEF_METADATA_HANDLE(method, Method)
173
DEF_METADATA_HANDLE(constantPool, ConstantPool)
174
175
// Writing this class explicitly, since DEF_METADATA_HANDLE(klass) doesn't
176
// provide the necessary Klass* <-> Klass* conversions. This Klass
177
// could be removed when we don't have the Klass* typedef anymore.
178
class KlassHandle : public StackObj {
179
Klass* _value;
180
protected:
181
Klass* obj() const { return _value; }
182
Klass* non_null_obj() const { assert(_value != NULL, "resolving NULL _value"); return _value; }
183
184
public:
185
KlassHandle() : _value(NULL) {}
186
KlassHandle(const Klass* obj) : _value(const_cast<Klass *>(obj)) {};
187
KlassHandle(Thread* thread, const Klass* obj) : _value(const_cast<Klass *>(obj)) {};
188
189
Klass* operator () () const { return obj(); }
190
Klass* operator -> () const { return non_null_obj(); }
191
192
bool operator == (Klass* o) const { return obj() == o; }
193
bool operator == (const KlassHandle& h) const { return obj() == h.obj(); }
194
195
bool is_null() const { return _value == NULL; }
196
bool not_null() const { return _value != NULL; }
197
};
198
199
class instanceKlassHandle : public KlassHandle {
200
public:
201
/* Constructors */
202
instanceKlassHandle () : KlassHandle() {}
203
instanceKlassHandle (const Klass* k) : KlassHandle(k) {
204
assert(k == NULL || k->oop_is_instance(),
205
"illegal type");
206
}
207
instanceKlassHandle (Thread* thread, const Klass* k) : KlassHandle(thread, k) {
208
assert(k == NULL || k->oop_is_instance(),
209
"illegal type");
210
}
211
/* Access to klass part */
212
InstanceKlass* operator () () const { return (InstanceKlass*)obj(); }
213
InstanceKlass* operator -> () const { return (InstanceKlass*)obj(); }
214
};
215
216
217
//------------------------------------------------------------------------------------------------------------------------
218
// Thread local handle area
219
class HandleArea: public Arena {
220
friend class HandleMark;
221
friend class NoHandleMark;
222
friend class ResetNoHandleMark;
223
#ifdef ASSERT
224
int _handle_mark_nesting;
225
int _no_handle_mark_nesting;
226
#endif
227
HandleArea* _prev; // link to outer (older) area
228
public:
229
// Constructor
230
HandleArea(HandleArea* prev) : Arena(mtThread, Chunk::tiny_size) {
231
debug_only(_handle_mark_nesting = 0);
232
debug_only(_no_handle_mark_nesting = 0);
233
_prev = prev;
234
}
235
236
// Handle allocation
237
private:
238
oop* real_allocate_handle(oop obj) {
239
#ifdef ASSERT
240
oop* handle = (oop*) (UseMallocOnly ? internal_malloc_4(oopSize) : Amalloc_4(oopSize));
241
#else
242
oop* handle = (oop*) Amalloc_4(oopSize);
243
#endif
244
*handle = obj;
245
return handle;
246
}
247
public:
248
#ifdef ASSERT
249
oop* allocate_handle(oop obj);
250
#else
251
oop* allocate_handle(oop obj) { return real_allocate_handle(obj); }
252
#endif
253
254
// Garbage collection support
255
void oops_do(OopClosure* f);
256
257
// Number of handles in use
258
size_t used() const { return Arena::used() / oopSize; }
259
260
debug_only(bool no_handle_mark_active() { return _no_handle_mark_nesting > 0; })
261
};
262
263
264
//------------------------------------------------------------------------------------------------------------------------
265
// Handles are allocated in a (growable) thread local handle area. Deallocation
266
// is managed using a HandleMark. It should normally not be necessary to use
267
// HandleMarks manually.
268
//
269
// A HandleMark constructor will record the current handle area top, and the
270
// desctructor will reset the top, destroying all handles allocated in between.
271
// The following code will therefore NOT work:
272
//
273
// Handle h;
274
// {
275
// HandleMark hm;
276
// h = Handle(obj);
277
// }
278
// h()->print(); // WRONG, h destroyed by HandleMark destructor.
279
//
280
// If h has to be preserved, it can be converted to an oop or a local JNI handle
281
// across the HandleMark boundary.
282
283
// The base class of HandleMark should have been StackObj but we also heap allocate
284
// a HandleMark when a thread is created. The operator new is for this special case.
285
286
class HandleMark {
287
private:
288
Thread *_thread; // thread that owns this mark
289
HandleArea *_area; // saved handle area
290
Chunk *_chunk; // saved arena chunk
291
char *_hwm, *_max; // saved arena info
292
size_t _size_in_bytes; // size of handle area
293
// Link to previous active HandleMark in thread
294
HandleMark* _previous_handle_mark;
295
296
void initialize(Thread* thread); // common code for constructors
297
void set_previous_handle_mark(HandleMark* mark) { _previous_handle_mark = mark; }
298
HandleMark* previous_handle_mark() const { return _previous_handle_mark; }
299
300
size_t size_in_bytes() const { return _size_in_bytes; }
301
public:
302
HandleMark(); // see handles_inline.hpp
303
HandleMark(Thread* thread) { initialize(thread); }
304
~HandleMark();
305
306
// Functions used by HandleMarkCleaner
307
// called in the constructor of HandleMarkCleaner
308
void push();
309
// called in the destructor of HandleMarkCleaner
310
void pop_and_restore();
311
// overloaded operators
312
void* operator new(size_t size) throw();
313
void* operator new [](size_t size) throw();
314
void operator delete(void* p);
315
void operator delete[](void* p);
316
};
317
318
//------------------------------------------------------------------------------------------------------------------------
319
// A NoHandleMark stack object will verify that no handles are allocated
320
// in its scope. Enabled in debug mode only.
321
322
class NoHandleMark: public StackObj {
323
public:
324
#ifdef ASSERT
325
NoHandleMark();
326
~NoHandleMark();
327
#else
328
NoHandleMark() {}
329
~NoHandleMark() {}
330
#endif
331
};
332
333
334
class ResetNoHandleMark: public StackObj {
335
int _no_handle_mark_nesting;
336
public:
337
#ifdef ASSERT
338
ResetNoHandleMark();
339
~ResetNoHandleMark();
340
#else
341
ResetNoHandleMark() {}
342
~ResetNoHandleMark() {}
343
#endif
344
};
345
346
#endif // SHARE_VM_RUNTIME_HANDLES_HPP
347
348