Mercurial > hg > truffle
annotate src/share/vm/runtime/handles.hpp @ 4575:ccb5369481a2
Clarified mx help text on how to build/run [Graal|Client|Server].
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Mon, 13 Feb 2012 10:27:38 +0100 |
parents | 1d1603768966 |
children | d2a62e0f25eb |
rev | line source |
---|---|
0 | 1 /* |
2426
1d1603768966
7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents:
2177
diff
changeset
|
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
665
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
665
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
665
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_RUNTIME_HANDLES_HPP |
26 #define SHARE_VM_RUNTIME_HANDLES_HPP | |
27 | |
28 #include "oops/klass.hpp" | |
29 #include "oops/klassOop.hpp" | |
30 #include "utilities/top.hpp" | |
31 | |
0 | 32 //------------------------------------------------------------------------------------------------------------------------ |
33 // In order to preserve oops during garbage collection, they should be | |
34 // allocated and passed around via Handles within the VM. A handle is | |
35 // simply an extra indirection allocated in a thread local handle area. | |
36 // | |
37 // A handle is a ValueObj, so it can be passed around as a value, can | |
38 // be used as a parameter w/o using &-passing, and can be returned as a | |
39 // return value. | |
40 // | |
41 // oop parameters and return types should be Handles whenever feasible. | |
42 // | |
43 // Handles are declared in a straight-forward manner, e.g. | |
44 // | |
45 // oop obj = ...; | |
46 // Handle h1(obj); // allocate new handle | |
47 // Handle h2(thread, obj); // faster allocation when current thread is known | |
48 // Handle h3; // declare handle only, no allocation occurs | |
49 // ... | |
50 // h3 = h1; // make h3 refer to same indirection as h1 | |
51 // oop obj2 = h2(); // get handle value | |
52 // h1->print(); // invoking operation on oop | |
53 // | |
54 // Handles are specialized for different oop types to provide extra type | |
55 // information and avoid unnecessary casting. For each oop type xxxOop | |
56 // there is a corresponding handle called xxxHandle, e.g. | |
57 // | |
58 // oop Handle | |
59 // methodOop methodHandle | |
60 // instanceOop instanceHandle | |
61 // | |
62 // For klassOops, it is often useful to model the Klass hierarchy in order | |
63 // to get access to the klass_part without casting. For each xxxKlass there | |
64 // is a corresponding handle called xxxKlassHandle, e.g. | |
65 // | |
66 // klassOop Klass KlassHandle | |
67 // klassOop methodKlass methodKlassHandle | |
68 // klassOop instanceKlass instanceKlassHandle | |
69 // | |
70 | |
71 //------------------------------------------------------------------------------------------------------------------------ | |
72 // Base class for all handles. Provides overloading of frequently | |
73 // used operators for ease of use. | |
74 | |
75 class Handle VALUE_OBJ_CLASS_SPEC { | |
76 private: | |
77 oop* _handle; | |
78 | |
79 protected: | |
80 oop obj() const { return _handle == NULL ? (oop)NULL : *_handle; } | |
81 oop non_null_obj() const { assert(_handle != NULL, "resolving NULL handle"); return *_handle; } | |
82 | |
83 public: | |
84 // Constructors | |
85 Handle() { _handle = NULL; } | |
86 Handle(oop obj); | |
87 #ifndef ASSERT | |
88 Handle(Thread* thread, oop obj); | |
89 #else | |
90 // Don't inline body with assert for current thread | |
91 Handle(Thread* thread, oop obj); | |
92 #endif // ASSERT | |
93 | |
94 // General access | |
95 oop operator () () const { return obj(); } | |
96 oop operator -> () const { return non_null_obj(); } | |
97 bool operator == (oop o) const { return obj() == o; } | |
98 bool operator == (const Handle& h) const { return obj() == h.obj(); } | |
99 | |
100 // Null checks | |
101 bool is_null() const { return _handle == NULL; } | |
102 bool not_null() const { return _handle != NULL; } | |
103 | |
104 // Debugging | |
105 void print() { obj()->print(); } | |
106 | |
107 // Direct interface, use very sparingly. | |
108 // Used by JavaCalls to quickly convert handles and to create handles static data structures. | |
109 // Constructor takes a dummy argument to prevent unintentional type conversion in C++. | |
110 Handle(oop *handle, bool dummy) { _handle = handle; } | |
111 | |
112 // Raw handle access. Allows easy duplication of Handles. This can be very unsafe | |
113 // since duplicates is only valid as long as original handle is alive. | |
114 oop* raw_value() { return _handle; } | |
115 static oop raw_resolve(oop *handle) { return handle == NULL ? (oop)NULL : *handle; } | |
116 }; | |
117 | |
118 | |
119 //------------------------------------------------------------------------------------------------------------------------ | |
120 // Base class for Handles containing klassOops. Provides overloading of frequently | |
121 // used operators for ease of use and typed access to the Klass part. | |
122 class KlassHandle: public Handle { | |
123 protected: | |
124 klassOop obj() const { return (klassOop)Handle::obj(); } | |
125 klassOop non_null_obj() const { return (klassOop)Handle::non_null_obj(); } | |
126 Klass* as_klass() const { return non_null_obj()->klass_part(); } | |
127 | |
128 public: | |
129 // Constructors | |
130 KlassHandle () : Handle() {} | |
131 KlassHandle (oop obj) : Handle(obj) { | |
132 assert(SharedSkipVerify || is_null() || obj->is_klass(), "not a klassOop"); | |
133 } | |
134 KlassHandle (Klass* kl) : Handle(kl ? kl->as_klassOop() : (klassOop)NULL) { | |
135 assert(SharedSkipVerify || is_null() || obj()->is_klass(), "not a klassOop"); | |
136 } | |
137 | |
138 // Faster versions passing Thread | |
139 KlassHandle (Thread* thread, oop obj) : Handle(thread, obj) { | |
140 assert(SharedSkipVerify || is_null() || obj->is_klass(), "not a klassOop"); | |
141 } | |
142 KlassHandle (Thread *thread, Klass* kl) | |
143 : Handle(thread, kl ? kl->as_klassOop() : (klassOop)NULL) { | |
144 assert(is_null() || obj()->is_klass(), "not a klassOop"); | |
145 } | |
146 | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
147 // Direct interface, use very sparingly. |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
148 // Used by SystemDictionaryHandles to create handles on existing WKKs. |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
149 // The obj of such a klass handle may be null, because the handle is formed |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
150 // during system bootstrapping. |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
151 KlassHandle(klassOop *handle, bool dummy) : Handle((oop*)handle, dummy) { |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
152 assert(SharedSkipVerify || is_null() || obj() == NULL || obj()->is_klass(), "not a klassOop"); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
153 } |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
0
diff
changeset
|
154 |
0 | 155 // General access |
156 klassOop operator () () const { return obj(); } | |
157 Klass* operator -> () const { return as_klass(); } | |
158 }; | |
159 | |
160 | |
161 //------------------------------------------------------------------------------------------------------------------------ | |
162 // Specific Handles for different oop types | |
163 #define DEF_HANDLE(type, is_a) \ | |
164 class type##Handle; \ | |
165 class type##Handle: public Handle { \ | |
166 protected: \ | |
167 type##Oop obj() const { return (type##Oop)Handle::obj(); } \ | |
168 type##Oop non_null_obj() const { return (type##Oop)Handle::non_null_obj(); } \ | |
169 \ | |
170 public: \ | |
171 /* Constructors */ \ | |
172 type##Handle () : Handle() {} \ | |
173 type##Handle (type##Oop obj) : Handle((oop)obj) { \ | |
174 assert(SharedSkipVerify || is_null() || ((oop)obj)->is_a(), \ | |
175 "illegal type"); \ | |
176 } \ | |
177 type##Handle (Thread* thread, type##Oop obj) : Handle(thread, (oop)obj) { \ | |
178 assert(SharedSkipVerify || is_null() || ((oop)obj)->is_a(), "illegal type"); \ | |
179 } \ | |
180 \ | |
181 /* Special constructor, use sparingly */ \ | |
182 type##Handle (type##Oop *handle, bool dummy) : Handle((oop*)handle, dummy) {} \ | |
183 \ | |
184 /* Operators for ease of use */ \ | |
185 type##Oop operator () () const { return obj(); } \ | |
186 type##Oop operator -> () const { return non_null_obj(); } \ | |
187 }; | |
188 | |
189 | |
190 DEF_HANDLE(instance , is_instance ) | |
191 DEF_HANDLE(method , is_method ) | |
192 DEF_HANDLE(constMethod , is_constMethod ) | |
193 DEF_HANDLE(methodData , is_methodData ) | |
194 DEF_HANDLE(array , is_array ) | |
195 DEF_HANDLE(constantPool , is_constantPool ) | |
196 DEF_HANDLE(constantPoolCache, is_constantPoolCache) | |
197 DEF_HANDLE(objArray , is_objArray ) | |
198 DEF_HANDLE(typeArray , is_typeArray ) | |
199 | |
200 //------------------------------------------------------------------------------------------------------------------------ | |
201 // Specific KlassHandles for different Klass types | |
202 | |
203 #define DEF_KLASS_HANDLE(type, is_a) \ | |
204 class type##Handle : public KlassHandle { \ | |
205 public: \ | |
206 /* Constructors */ \ | |
207 type##Handle () : KlassHandle() {} \ | |
208 type##Handle (klassOop obj) : KlassHandle(obj) { \ | |
209 assert(SharedSkipVerify || is_null() || obj->klass_part()->is_a(), \ | |
210 "illegal type"); \ | |
211 } \ | |
212 type##Handle (Thread* thread, klassOop obj) : KlassHandle(thread, obj) { \ | |
213 assert(SharedSkipVerify || is_null() || obj->klass_part()->is_a(), \ | |
214 "illegal type"); \ | |
215 } \ | |
216 \ | |
217 /* Access to klass part */ \ | |
218 type* operator -> () const { return (type*)obj()->klass_part(); } \ | |
219 \ | |
220 static type##Handle cast(KlassHandle h) { return type##Handle(h()); } \ | |
221 \ | |
222 }; | |
223 | |
224 | |
225 DEF_KLASS_HANDLE(instanceKlass , oop_is_instance_slow ) | |
226 DEF_KLASS_HANDLE(methodKlass , oop_is_method ) | |
227 DEF_KLASS_HANDLE(constMethodKlass , oop_is_constMethod ) | |
228 DEF_KLASS_HANDLE(klassKlass , oop_is_klass ) | |
229 DEF_KLASS_HANDLE(arrayKlassKlass , oop_is_arrayKlass ) | |
230 DEF_KLASS_HANDLE(objArrayKlassKlass , oop_is_objArrayKlass ) | |
231 DEF_KLASS_HANDLE(typeArrayKlassKlass , oop_is_typeArrayKlass) | |
232 DEF_KLASS_HANDLE(arrayKlass , oop_is_array ) | |
233 DEF_KLASS_HANDLE(typeArrayKlass , oop_is_typeArray_slow) | |
234 DEF_KLASS_HANDLE(objArrayKlass , oop_is_objArray_slow ) | |
235 DEF_KLASS_HANDLE(constantPoolKlass , oop_is_constantPool ) | |
236 DEF_KLASS_HANDLE(constantPoolCacheKlass, oop_is_constantPool ) | |
237 | |
238 | |
239 //------------------------------------------------------------------------------------------------------------------------ | |
240 // Thread local handle area | |
241 | |
242 class HandleArea: public Arena { | |
243 friend class HandleMark; | |
244 friend class NoHandleMark; | |
245 friend class ResetNoHandleMark; | |
246 #ifdef ASSERT | |
247 int _handle_mark_nesting; | |
248 int _no_handle_mark_nesting; | |
249 #endif | |
250 HandleArea* _prev; // link to outer (older) area | |
251 public: | |
252 // Constructor | |
253 HandleArea(HandleArea* prev) { | |
254 debug_only(_handle_mark_nesting = 0); | |
255 debug_only(_no_handle_mark_nesting = 0); | |
256 _prev = prev; | |
257 } | |
258 | |
259 // Handle allocation | |
260 private: | |
261 oop* real_allocate_handle(oop obj) { | |
262 #ifdef ASSERT | |
263 oop* handle = (oop*) (UseMallocOnly ? internal_malloc_4(oopSize) : Amalloc_4(oopSize)); | |
264 #else | |
265 oop* handle = (oop*) Amalloc_4(oopSize); | |
266 #endif | |
267 *handle = obj; | |
268 return handle; | |
269 } | |
270 public: | |
271 #ifdef ASSERT | |
272 oop* allocate_handle(oop obj); | |
273 #else | |
274 oop* allocate_handle(oop obj) { return real_allocate_handle(obj); } | |
275 #endif | |
276 | |
277 // Garbage collection support | |
278 void oops_do(OopClosure* f); | |
279 | |
280 // Number of handles in use | |
281 size_t used() const { return Arena::used() / oopSize; } | |
282 | |
283 debug_only(bool no_handle_mark_active() { return _no_handle_mark_nesting > 0; }) | |
284 }; | |
285 | |
286 | |
287 //------------------------------------------------------------------------------------------------------------------------ | |
288 // Handles are allocated in a (growable) thread local handle area. Deallocation | |
289 // is managed using a HandleMark. It should normally not be necessary to use | |
290 // HandleMarks manually. | |
291 // | |
292 // A HandleMark constructor will record the current handle area top, and the | |
293 // desctructor will reset the top, destroying all handles allocated in between. | |
294 // The following code will therefore NOT work: | |
295 // | |
296 // Handle h; | |
297 // { | |
298 // HandleMark hm; | |
299 // h = Handle(obj); | |
300 // } | |
301 // h()->print(); // WRONG, h destroyed by HandleMark destructor. | |
302 // | |
303 // If h has to be preserved, it can be converted to an oop or a local JNI handle | |
304 // across the HandleMark boundary. | |
305 | |
306 // The base class of HandleMark should have been StackObj but we also heap allocate | |
307 // a HandleMark when a thread is created. | |
308 | |
309 class HandleMark { | |
310 private: | |
311 Thread *_thread; // thread that owns this mark | |
312 HandleArea *_area; // saved handle area | |
313 Chunk *_chunk; // saved arena chunk | |
314 char *_hwm, *_max; // saved arena info | |
315 NOT_PRODUCT(size_t _size_in_bytes;) // size of handle area | |
316 // Link to previous active HandleMark in thread | |
317 HandleMark* _previous_handle_mark; | |
318 | |
319 void initialize(Thread* thread); // common code for constructors | |
320 void set_previous_handle_mark(HandleMark* mark) { _previous_handle_mark = mark; } | |
321 HandleMark* previous_handle_mark() const { return _previous_handle_mark; } | |
322 | |
323 public: | |
324 HandleMark(); // see handles_inline.hpp | |
325 HandleMark(Thread* thread) { initialize(thread); } | |
326 ~HandleMark(); | |
327 | |
328 // Functions used by HandleMarkCleaner | |
329 // called in the constructor of HandleMarkCleaner | |
330 void push(); | |
331 // called in the destructor of HandleMarkCleaner | |
332 void pop_and_restore(); | |
333 }; | |
334 | |
335 //------------------------------------------------------------------------------------------------------------------------ | |
336 // A NoHandleMark stack object will verify that no handles are allocated | |
337 // in its scope. Enabled in debug mode only. | |
338 | |
339 class NoHandleMark: public StackObj { | |
340 public: | |
341 #ifdef ASSERT | |
342 NoHandleMark(); | |
343 ~NoHandleMark(); | |
344 #else | |
345 NoHandleMark() {} | |
346 ~NoHandleMark() {} | |
347 #endif | |
348 }; | |
349 | |
350 | |
351 class ResetNoHandleMark: public StackObj { | |
352 int _no_handle_mark_nesting; | |
353 public: | |
354 #ifdef ASSERT | |
355 ResetNoHandleMark(); | |
356 ~ResetNoHandleMark(); | |
357 #else | |
358 ResetNoHandleMark() {} | |
359 ~ResetNoHandleMark() {} | |
360 #endif | |
361 }; | |
1972 | 362 |
363 #endif // SHARE_VM_RUNTIME_HANDLES_HPP |