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