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