Mercurial > hg > truffle
annotate src/share/vm/prims/unsafe.cpp @ 1716:be3f9c242c9d
6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
Summary: GC workers now recognize an intermediate transient state of blocks which are allocated but have not yet completed initialization. blk_start() calls do not attempt to determine the size of a block in the transient state, rather waiting for the block to become initialized so that it is safe to query its size. Audited and ensured the order of initialization of object fields (klass, free bit and size) to respect block state transition protocol. Also included some new assertion checking code enabled in debug mode.
Reviewed-by: chrisphi, johnc, poonam
author | ysr |
---|---|
date | Mon, 16 Aug 2010 15:58:42 -0700 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1324
diff
changeset
|
2 * Copyright (c) 2000, 2008, 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:
1324
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1324
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:
1324
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 /* | |
26 * Implementation of class sun.misc.Unsafe | |
27 */ | |
28 | |
29 #include "incls/_precompiled.incl" | |
30 #include "incls/_unsafe.cpp.incl" | |
31 | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
845
diff
changeset
|
32 HS_DTRACE_PROBE_DECL3(hotspot, thread__park__begin, uintptr_t, int, long long); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
845
diff
changeset
|
33 HS_DTRACE_PROBE_DECL1(hotspot, thread__park__end, uintptr_t); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
845
diff
changeset
|
34 HS_DTRACE_PROBE_DECL1(hotspot, thread__unpark, uintptr_t); |
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
845
diff
changeset
|
35 |
0 | 36 #define MAX_OBJECT_SIZE \ |
37 ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \ | |
38 + ((julong)max_jint * sizeof(double)) ) | |
39 | |
40 | |
41 #define UNSAFE_ENTRY(result_type, header) \ | |
42 JVM_ENTRY(result_type, header) | |
43 | |
44 // Can't use UNSAFE_LEAF because it has the signature of a straight | |
45 // call into the runtime (just like JVM_LEAF, funny that) but it's | |
46 // called like a Java Native and thus the wrapper built for it passes | |
47 // arguments like a JNI call. It expects those arguments to be popped | |
48 // from the stack on Intel like all good JNI args are, and adjusts the | |
49 // stack according. Since the JVM_LEAF call expects no extra | |
50 // arguments the stack isn't popped in the C code, is pushed by the | |
51 // wrapper and we get sick. | |
52 //#define UNSAFE_LEAF(result_type, header) \ | |
53 // JVM_LEAF(result_type, header) | |
54 | |
55 #define UNSAFE_END JVM_END | |
56 | |
57 #define UnsafeWrapper(arg) /*nothing, for the present*/ | |
58 | |
59 | |
60 inline void* addr_from_java(jlong addr) { | |
61 // This assert fails in a variety of ways on 32-bit systems. | |
62 // It is impossible to predict whether native code that converts | |
63 // pointers to longs will sign-extend or zero-extend the addresses. | |
64 //assert(addr == (uintptr_t)addr, "must not be odd high bits"); | |
65 return (void*)(uintptr_t)addr; | |
66 } | |
67 | |
68 inline jlong addr_to_java(void* p) { | |
69 assert(p == (void*)(uintptr_t)p, "must not be odd high bits"); | |
70 return (uintptr_t)p; | |
71 } | |
72 | |
73 | |
74 // Note: The VM's obj_field and related accessors use byte-scaled | |
75 // ("unscaled") offsets, just as the unsafe methods do. | |
76 | |
77 // However, the method Unsafe.fieldOffset explicitly declines to | |
78 // guarantee this. The field offset values manipulated by the Java user | |
79 // through the Unsafe API are opaque cookies that just happen to be byte | |
80 // offsets. We represent this state of affairs by passing the cookies | |
81 // through conversion functions when going between the VM and the Unsafe API. | |
82 // The conversion functions just happen to be no-ops at present. | |
83 | |
84 inline jlong field_offset_to_byte_offset(jlong field_offset) { | |
85 return field_offset; | |
86 } | |
87 | |
88 inline jlong field_offset_from_byte_offset(jlong byte_offset) { | |
89 return byte_offset; | |
90 } | |
91 | |
92 inline jint invocation_key_from_method_slot(jint slot) { | |
93 return slot; | |
94 } | |
95 | |
96 inline jint invocation_key_to_method_slot(jint key) { | |
97 return key; | |
98 } | |
99 | |
100 inline void* index_oop_from_field_offset_long(oop p, jlong field_offset) { | |
101 jlong byte_offset = field_offset_to_byte_offset(field_offset); | |
102 #ifdef ASSERT | |
103 if (p != NULL) { | |
104 assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset"); | |
105 if (byte_offset == (jint)byte_offset) { | |
106 void* ptr_plus_disp = (address)p + byte_offset; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
107 assert((void*)p->obj_field_addr<oop>((jint)byte_offset) == ptr_plus_disp, |
0 | 108 "raw [ptr+disp] must be consistent with oop::field_base"); |
109 } | |
110 } | |
111 #endif | |
112 if (sizeof(char*) == sizeof(jint)) // (this constant folds!) | |
113 return (address)p + (jint) byte_offset; | |
114 else | |
115 return (address)p + byte_offset; | |
116 } | |
117 | |
118 // Externally callable versions: | |
119 // (Use these in compiler intrinsics which emulate unsafe primitives.) | |
120 jlong Unsafe_field_offset_to_byte_offset(jlong field_offset) { | |
121 return field_offset; | |
122 } | |
123 jlong Unsafe_field_offset_from_byte_offset(jlong byte_offset) { | |
124 return byte_offset; | |
125 } | |
126 jint Unsafe_invocation_key_from_method_slot(jint slot) { | |
127 return invocation_key_from_method_slot(slot); | |
128 } | |
129 jint Unsafe_invocation_key_to_method_slot(jint key) { | |
130 return invocation_key_to_method_slot(key); | |
131 } | |
132 | |
133 | |
134 ///// Data in the Java heap. | |
135 | |
136 #define GET_FIELD(obj, offset, type_name, v) \ | |
137 oop p = JNIHandles::resolve(obj); \ | |
138 type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset) | |
139 | |
140 #define SET_FIELD(obj, offset, type_name, x) \ | |
141 oop p = JNIHandles::resolve(obj); \ | |
142 *(type_name*)index_oop_from_field_offset_long(p, offset) = x | |
143 | |
144 #define GET_FIELD_VOLATILE(obj, offset, type_name, v) \ | |
145 oop p = JNIHandles::resolve(obj); \ | |
146 volatile type_name v = *(volatile type_name*)index_oop_from_field_offset_long(p, offset) | |
147 | |
148 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \ | |
149 oop p = JNIHandles::resolve(obj); \ | |
150 *(volatile type_name*)index_oop_from_field_offset_long(p, offset) = x; \ | |
151 OrderAccess::fence(); | |
152 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
153 // Macros for oops that check UseCompressedOops |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
154 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
155 #define GET_OOP_FIELD(obj, offset, v) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
156 oop p = JNIHandles::resolve(obj); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
157 oop v; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
158 if (UseCompressedOops) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
159 narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
160 v = oopDesc::decode_heap_oop(n); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
161 } else { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
162 v = *(oop*)index_oop_from_field_offset_long(p, offset); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
163 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
164 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
165 #define GET_OOP_FIELD_VOLATILE(obj, offset, v) \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
166 oop p = JNIHandles::resolve(obj); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
167 volatile oop v; \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
168 if (UseCompressedOops) { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
169 volatile narrowOop n = *(volatile narrowOop*)index_oop_from_field_offset_long(p, offset); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
170 v = oopDesc::decode_heap_oop(n); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
171 } else { \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
172 v = *(volatile oop*)index_oop_from_field_offset_long(p, offset); \ |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
173 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
174 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
175 |
0 | 176 // Get/SetObject must be special-cased, since it works with handles. |
177 | |
178 // The xxx140 variants for backward compatibility do not allow a full-width offset. | |
179 UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset)) | |
180 UnsafeWrapper("Unsafe_GetObject"); | |
181 if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException()); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
182 GET_OOP_FIELD(obj, offset, v) |
0 | 183 return JNIHandles::make_local(env, v); |
184 UNSAFE_END | |
185 | |
186 UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h)) | |
187 UnsafeWrapper("Unsafe_SetObject"); | |
188 if (obj == NULL) THROW(vmSymbols::java_lang_NullPointerException()); | |
189 oop x = JNIHandles::resolve(x_h); | |
190 //SET_FIELD(obj, offset, oop, x); | |
191 oop p = JNIHandles::resolve(obj); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
192 if (UseCompressedOops) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
193 if (x != NULL) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
194 // If there is a heap base pointer, we are obliged to emit a store barrier. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
195 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
196 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
197 narrowOop n = oopDesc::encode_heap_oop_not_null(x); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
198 *(narrowOop*)index_oop_from_field_offset_long(p, offset) = n; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
199 } |
0 | 200 } else { |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
201 if (x != NULL) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
202 // If there is a heap base pointer, we are obliged to emit a store barrier. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
203 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
204 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
205 *(oop*)index_oop_from_field_offset_long(p, offset) = x; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
206 } |
0 | 207 } |
208 UNSAFE_END | |
209 | |
210 // The normal variants allow a null base pointer with an arbitrary address. | |
211 // But if the base pointer is non-null, the offset should make some sense. | |
212 // That is, it should be in the range [0, MAX_OBJECT_SIZE]. | |
213 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) | |
214 UnsafeWrapper("Unsafe_GetObject"); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
215 GET_OOP_FIELD(obj, offset, v) |
0 | 216 return JNIHandles::make_local(env, v); |
217 UNSAFE_END | |
218 | |
219 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) | |
220 UnsafeWrapper("Unsafe_SetObject"); | |
221 oop x = JNIHandles::resolve(x_h); | |
222 oop p = JNIHandles::resolve(obj); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
223 if (UseCompressedOops) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
224 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
225 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
226 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
227 } |
0 | 228 UNSAFE_END |
229 | |
230 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) | |
231 UnsafeWrapper("Unsafe_GetObjectVolatile"); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
232 GET_OOP_FIELD_VOLATILE(obj, offset, v) |
0 | 233 return JNIHandles::make_local(env, v); |
234 UNSAFE_END | |
235 | |
236 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) | |
237 UnsafeWrapper("Unsafe_SetObjectVolatile"); | |
238 oop x = JNIHandles::resolve(x_h); | |
239 oop p = JNIHandles::resolve(obj); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
240 if (UseCompressedOops) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
241 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
242 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
243 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
244 } |
0 | 245 OrderAccess::fence(); |
246 UNSAFE_END | |
247 | |
248 // Volatile long versions must use locks if !VM_Version::supports_cx8(). | |
249 // support_cx8 is a surrogate for 'supports atomic long memory ops'. | |
250 | |
251 UNSAFE_ENTRY(jlong, Unsafe_GetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) | |
252 UnsafeWrapper("Unsafe_GetLongVolatile"); | |
253 { | |
254 if (VM_Version::supports_cx8()) { | |
255 GET_FIELD_VOLATILE(obj, offset, jlong, v); | |
256 return v; | |
257 } | |
258 else { | |
259 Handle p (THREAD, JNIHandles::resolve(obj)); | |
260 jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); | |
261 ObjectLocker ol(p, THREAD); | |
262 jlong value = *addr; | |
263 return value; | |
264 } | |
265 } | |
266 UNSAFE_END | |
267 | |
268 UNSAFE_ENTRY(void, Unsafe_SetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x)) | |
269 UnsafeWrapper("Unsafe_SetLongVolatile"); | |
270 { | |
271 if (VM_Version::supports_cx8()) { | |
272 SET_FIELD_VOLATILE(obj, offset, jlong, x); | |
273 } | |
274 else { | |
275 Handle p (THREAD, JNIHandles::resolve(obj)); | |
276 jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); | |
277 ObjectLocker ol(p, THREAD); | |
278 *addr = x; | |
279 } | |
280 } | |
281 UNSAFE_END | |
282 | |
283 | |
284 #define DEFINE_GETSETOOP(jboolean, Boolean) \ | |
285 \ | |
286 UNSAFE_ENTRY(jboolean, Unsafe_Get##Boolean##140(JNIEnv *env, jobject unsafe, jobject obj, jint offset)) \ | |
287 UnsafeWrapper("Unsafe_Get"#Boolean); \ | |
288 if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException()); \ | |
289 GET_FIELD(obj, offset, jboolean, v); \ | |
290 return v; \ | |
291 UNSAFE_END \ | |
292 \ | |
293 UNSAFE_ENTRY(void, Unsafe_Set##Boolean##140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jboolean x)) \ | |
294 UnsafeWrapper("Unsafe_Set"#Boolean); \ | |
295 if (obj == NULL) THROW(vmSymbols::java_lang_NullPointerException()); \ | |
296 SET_FIELD(obj, offset, jboolean, x); \ | |
297 UNSAFE_END \ | |
298 \ | |
299 UNSAFE_ENTRY(jboolean, Unsafe_Get##Boolean(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) \ | |
300 UnsafeWrapper("Unsafe_Get"#Boolean); \ | |
301 GET_FIELD(obj, offset, jboolean, v); \ | |
302 return v; \ | |
303 UNSAFE_END \ | |
304 \ | |
305 UNSAFE_ENTRY(void, Unsafe_Set##Boolean(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jboolean x)) \ | |
306 UnsafeWrapper("Unsafe_Set"#Boolean); \ | |
307 SET_FIELD(obj, offset, jboolean, x); \ | |
308 UNSAFE_END \ | |
309 \ | |
310 // END DEFINE_GETSETOOP. | |
311 | |
312 | |
313 #define DEFINE_GETSETOOP_VOLATILE(jboolean, Boolean) \ | |
314 \ | |
315 UNSAFE_ENTRY(jboolean, Unsafe_Get##Boolean##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) \ | |
316 UnsafeWrapper("Unsafe_Get"#Boolean); \ | |
317 GET_FIELD_VOLATILE(obj, offset, jboolean, v); \ | |
318 return v; \ | |
319 UNSAFE_END \ | |
320 \ | |
321 UNSAFE_ENTRY(void, Unsafe_Set##Boolean##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jboolean x)) \ | |
322 UnsafeWrapper("Unsafe_Set"#Boolean); \ | |
323 SET_FIELD_VOLATILE(obj, offset, jboolean, x); \ | |
324 UNSAFE_END \ | |
325 \ | |
326 // END DEFINE_GETSETOOP_VOLATILE. | |
327 | |
328 DEFINE_GETSETOOP(jboolean, Boolean) | |
329 DEFINE_GETSETOOP(jbyte, Byte) | |
330 DEFINE_GETSETOOP(jshort, Short); | |
331 DEFINE_GETSETOOP(jchar, Char); | |
332 DEFINE_GETSETOOP(jint, Int); | |
333 DEFINE_GETSETOOP(jlong, Long); | |
334 DEFINE_GETSETOOP(jfloat, Float); | |
335 DEFINE_GETSETOOP(jdouble, Double); | |
336 | |
337 DEFINE_GETSETOOP_VOLATILE(jboolean, Boolean) | |
338 DEFINE_GETSETOOP_VOLATILE(jbyte, Byte) | |
339 DEFINE_GETSETOOP_VOLATILE(jshort, Short); | |
340 DEFINE_GETSETOOP_VOLATILE(jchar, Char); | |
341 DEFINE_GETSETOOP_VOLATILE(jint, Int); | |
342 // no long -- handled specially | |
343 DEFINE_GETSETOOP_VOLATILE(jfloat, Float); | |
344 DEFINE_GETSETOOP_VOLATILE(jdouble, Double); | |
345 | |
346 #undef DEFINE_GETSETOOP | |
347 | |
348 // The non-intrinsified versions of setOrdered just use setVolatile | |
349 | |
350 UNSAFE_ENTRY(void, Unsafe_SetOrderedInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint x)) \ | |
351 UnsafeWrapper("Unsafe_SetOrderedInt"); \ | |
352 SET_FIELD_VOLATILE(obj, offset, jint, x); \ | |
353 UNSAFE_END | |
354 | |
355 UNSAFE_ENTRY(void, Unsafe_SetOrderedObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) | |
356 UnsafeWrapper("Unsafe_SetOrderedObject"); | |
357 oop x = JNIHandles::resolve(x_h); | |
358 oop p = JNIHandles::resolve(obj); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
359 if (UseCompressedOops) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
360 oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
361 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
362 oop_store((oop*)index_oop_from_field_offset_long(p, offset), x); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
363 } |
0 | 364 OrderAccess::fence(); |
365 UNSAFE_END | |
366 | |
367 UNSAFE_ENTRY(void, Unsafe_SetOrderedLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x)) | |
368 UnsafeWrapper("Unsafe_SetOrderedLong"); | |
369 { | |
370 if (VM_Version::supports_cx8()) { | |
371 SET_FIELD_VOLATILE(obj, offset, jlong, x); | |
372 } | |
373 else { | |
374 Handle p (THREAD, JNIHandles::resolve(obj)); | |
375 jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); | |
376 ObjectLocker ol(p, THREAD); | |
377 *addr = x; | |
378 } | |
379 } | |
380 UNSAFE_END | |
381 | |
382 ////// Data in the C heap. | |
383 | |
384 // Note: These do not throw NullPointerException for bad pointers. | |
385 // They just crash. Only a oop base pointer can generate a NullPointerException. | |
386 // | |
387 #define DEFINE_GETSETNATIVE(java_type, Type, native_type) \ | |
388 \ | |
389 UNSAFE_ENTRY(java_type, Unsafe_GetNative##Type(JNIEnv *env, jobject unsafe, jlong addr)) \ | |
390 UnsafeWrapper("Unsafe_GetNative"#Type); \ | |
391 void* p = addr_from_java(addr); \ | |
392 JavaThread* t = JavaThread::current(); \ | |
393 t->set_doing_unsafe_access(true); \ | |
394 java_type x = *(volatile native_type*)p; \ | |
395 t->set_doing_unsafe_access(false); \ | |
396 return x; \ | |
397 UNSAFE_END \ | |
398 \ | |
399 UNSAFE_ENTRY(void, Unsafe_SetNative##Type(JNIEnv *env, jobject unsafe, jlong addr, java_type x)) \ | |
400 UnsafeWrapper("Unsafe_SetNative"#Type); \ | |
401 JavaThread* t = JavaThread::current(); \ | |
402 t->set_doing_unsafe_access(true); \ | |
403 void* p = addr_from_java(addr); \ | |
404 *(volatile native_type*)p = x; \ | |
405 t->set_doing_unsafe_access(false); \ | |
406 UNSAFE_END \ | |
407 \ | |
408 // END DEFINE_GETSETNATIVE. | |
409 | |
410 DEFINE_GETSETNATIVE(jbyte, Byte, signed char) | |
411 DEFINE_GETSETNATIVE(jshort, Short, signed short); | |
412 DEFINE_GETSETNATIVE(jchar, Char, unsigned short); | |
413 DEFINE_GETSETNATIVE(jint, Int, jint); | |
414 // no long -- handled specially | |
415 DEFINE_GETSETNATIVE(jfloat, Float, float); | |
416 DEFINE_GETSETNATIVE(jdouble, Double, double); | |
417 | |
418 #undef DEFINE_GETSETNATIVE | |
419 | |
420 UNSAFE_ENTRY(jlong, Unsafe_GetNativeLong(JNIEnv *env, jobject unsafe, jlong addr)) | |
421 UnsafeWrapper("Unsafe_GetNativeLong"); | |
422 JavaThread* t = JavaThread::current(); | |
423 // We do it this way to avoid problems with access to heap using 64 | |
424 // bit loads, as jlong in heap could be not 64-bit aligned, and on | |
425 // some CPUs (SPARC) it leads to SIGBUS. | |
426 t->set_doing_unsafe_access(true); | |
427 void* p = addr_from_java(addr); | |
428 jlong x; | |
429 if (((intptr_t)p & 7) == 0) { | |
430 // jlong is aligned, do a volatile access | |
431 x = *(volatile jlong*)p; | |
432 } else { | |
433 jlong_accessor acc; | |
434 acc.words[0] = ((volatile jint*)p)[0]; | |
435 acc.words[1] = ((volatile jint*)p)[1]; | |
436 x = acc.long_value; | |
437 } | |
438 t->set_doing_unsafe_access(false); | |
439 return x; | |
440 UNSAFE_END | |
441 | |
442 UNSAFE_ENTRY(void, Unsafe_SetNativeLong(JNIEnv *env, jobject unsafe, jlong addr, jlong x)) | |
443 UnsafeWrapper("Unsafe_SetNativeLong"); | |
444 JavaThread* t = JavaThread::current(); | |
445 // see comment for Unsafe_GetNativeLong | |
446 t->set_doing_unsafe_access(true); | |
447 void* p = addr_from_java(addr); | |
448 if (((intptr_t)p & 7) == 0) { | |
449 // jlong is aligned, do a volatile access | |
450 *(volatile jlong*)p = x; | |
451 } else { | |
452 jlong_accessor acc; | |
453 acc.long_value = x; | |
454 ((volatile jint*)p)[0] = acc.words[0]; | |
455 ((volatile jint*)p)[1] = acc.words[1]; | |
456 } | |
457 t->set_doing_unsafe_access(false); | |
458 UNSAFE_END | |
459 | |
460 | |
461 UNSAFE_ENTRY(jlong, Unsafe_GetNativeAddress(JNIEnv *env, jobject unsafe, jlong addr)) | |
462 UnsafeWrapper("Unsafe_GetNativeAddress"); | |
463 void* p = addr_from_java(addr); | |
464 return addr_to_java(*(void**)p); | |
465 UNSAFE_END | |
466 | |
467 UNSAFE_ENTRY(void, Unsafe_SetNativeAddress(JNIEnv *env, jobject unsafe, jlong addr, jlong x)) | |
468 UnsafeWrapper("Unsafe_SetNativeAddress"); | |
469 void* p = addr_from_java(addr); | |
470 *(void**)p = addr_from_java(x); | |
471 UNSAFE_END | |
472 | |
473 | |
474 ////// Allocation requests | |
475 | |
476 UNSAFE_ENTRY(jobject, Unsafe_AllocateInstance(JNIEnv *env, jobject unsafe, jclass cls)) | |
477 UnsafeWrapper("Unsafe_AllocateInstance"); | |
478 { | |
479 ThreadToNativeFromVM ttnfv(thread); | |
480 return env->AllocObject(cls); | |
481 } | |
482 UNSAFE_END | |
483 | |
484 UNSAFE_ENTRY(jlong, Unsafe_AllocateMemory(JNIEnv *env, jobject unsafe, jlong size)) | |
485 UnsafeWrapper("Unsafe_AllocateMemory"); | |
486 size_t sz = (size_t)size; | |
487 if (sz != (julong)size || size < 0) { | |
488 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
489 } | |
490 if (sz == 0) { | |
491 return 0; | |
492 } | |
493 sz = round_to(sz, HeapWordSize); | |
494 void* x = os::malloc(sz); | |
495 if (x == NULL) { | |
496 THROW_0(vmSymbols::java_lang_OutOfMemoryError()); | |
497 } | |
498 //Copy::fill_to_words((HeapWord*)x, sz / HeapWordSize); | |
499 return addr_to_java(x); | |
500 UNSAFE_END | |
501 | |
502 UNSAFE_ENTRY(jlong, Unsafe_ReallocateMemory(JNIEnv *env, jobject unsafe, jlong addr, jlong size)) | |
503 UnsafeWrapper("Unsafe_ReallocateMemory"); | |
504 void* p = addr_from_java(addr); | |
505 size_t sz = (size_t)size; | |
506 if (sz != (julong)size || size < 0) { | |
507 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
508 } | |
509 if (sz == 0) { | |
510 os::free(p); | |
511 return 0; | |
512 } | |
513 sz = round_to(sz, HeapWordSize); | |
514 void* x = (p == NULL) ? os::malloc(sz) : os::realloc(p, sz); | |
515 if (x == NULL) { | |
516 THROW_0(vmSymbols::java_lang_OutOfMemoryError()); | |
517 } | |
518 return addr_to_java(x); | |
519 UNSAFE_END | |
520 | |
521 UNSAFE_ENTRY(void, Unsafe_FreeMemory(JNIEnv *env, jobject unsafe, jlong addr)) | |
522 UnsafeWrapper("Unsafe_FreeMemory"); | |
523 void* p = addr_from_java(addr); | |
524 if (p == NULL) { | |
525 return; | |
526 } | |
527 os::free(p); | |
528 UNSAFE_END | |
529 | |
530 UNSAFE_ENTRY(void, Unsafe_SetMemory(JNIEnv *env, jobject unsafe, jlong addr, jlong size, jbyte value)) | |
531 UnsafeWrapper("Unsafe_SetMemory"); | |
532 size_t sz = (size_t)size; | |
533 if (sz != (julong)size || size < 0) { | |
534 THROW(vmSymbols::java_lang_IllegalArgumentException()); | |
535 } | |
536 char* p = (char*) addr_from_java(addr); | |
537 Copy::fill_to_memory_atomic(p, sz, value); | |
538 UNSAFE_END | |
539 | |
540 UNSAFE_ENTRY(void, Unsafe_SetMemory2(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong size, jbyte value)) | |
541 UnsafeWrapper("Unsafe_SetMemory"); | |
542 size_t sz = (size_t)size; | |
543 if (sz != (julong)size || size < 0) { | |
544 THROW(vmSymbols::java_lang_IllegalArgumentException()); | |
545 } | |
546 oop base = JNIHandles::resolve(obj); | |
547 void* p = index_oop_from_field_offset_long(base, offset); | |
548 Copy::fill_to_memory_atomic(p, sz, value); | |
549 UNSAFE_END | |
550 | |
551 UNSAFE_ENTRY(void, Unsafe_CopyMemory(JNIEnv *env, jobject unsafe, jlong srcAddr, jlong dstAddr, jlong size)) | |
552 UnsafeWrapper("Unsafe_CopyMemory"); | |
553 if (size == 0) { | |
554 return; | |
555 } | |
556 size_t sz = (size_t)size; | |
557 if (sz != (julong)size || size < 0) { | |
558 THROW(vmSymbols::java_lang_IllegalArgumentException()); | |
559 } | |
560 void* src = addr_from_java(srcAddr); | |
561 void* dst = addr_from_java(dstAddr); | |
562 Copy::conjoint_memory_atomic(src, dst, sz); | |
563 UNSAFE_END | |
564 | |
565 UNSAFE_ENTRY(void, Unsafe_CopyMemory2(JNIEnv *env, jobject unsafe, jobject srcObj, jlong srcOffset, jobject dstObj, jlong dstOffset, jlong size)) | |
566 UnsafeWrapper("Unsafe_CopyMemory"); | |
567 if (size == 0) { | |
568 return; | |
569 } | |
570 size_t sz = (size_t)size; | |
571 if (sz != (julong)size || size < 0) { | |
572 THROW(vmSymbols::java_lang_IllegalArgumentException()); | |
573 } | |
574 oop srcp = JNIHandles::resolve(srcObj); | |
575 oop dstp = JNIHandles::resolve(dstObj); | |
576 if (dstp != NULL && !dstp->is_typeArray()) { | |
577 // NYI: This works only for non-oop arrays at present. | |
578 // Generalizing it would be reasonable, but requires card marking. | |
579 // Also, autoboxing a Long from 0L in copyMemory(x,y, 0L,z, n) would be bad. | |
580 THROW(vmSymbols::java_lang_IllegalArgumentException()); | |
581 } | |
582 void* src = index_oop_from_field_offset_long(srcp, srcOffset); | |
583 void* dst = index_oop_from_field_offset_long(dstp, dstOffset); | |
584 Copy::conjoint_memory_atomic(src, dst, sz); | |
585 UNSAFE_END | |
586 | |
587 | |
588 ////// Random queries | |
589 | |
590 // See comment at file start about UNSAFE_LEAF | |
591 //UNSAFE_LEAF(jint, Unsafe_AddressSize()) | |
592 UNSAFE_ENTRY(jint, Unsafe_AddressSize(JNIEnv *env, jobject unsafe)) | |
593 UnsafeWrapper("Unsafe_AddressSize"); | |
594 return sizeof(void*); | |
595 UNSAFE_END | |
596 | |
597 // See comment at file start about UNSAFE_LEAF | |
598 //UNSAFE_LEAF(jint, Unsafe_PageSize()) | |
599 UNSAFE_ENTRY(jint, Unsafe_PageSize(JNIEnv *env, jobject unsafe)) | |
600 UnsafeWrapper("Unsafe_PageSize"); | |
601 return os::vm_page_size(); | |
602 UNSAFE_END | |
603 | |
604 jint find_field_offset(jobject field, int must_be_static, TRAPS) { | |
605 if (field == NULL) { | |
606 THROW_0(vmSymbols::java_lang_NullPointerException()); | |
607 } | |
608 | |
609 oop reflected = JNIHandles::resolve_non_null(field); | |
610 oop mirror = java_lang_reflect_Field::clazz(reflected); | |
611 klassOop k = java_lang_Class::as_klassOop(mirror); | |
612 int slot = java_lang_reflect_Field::slot(reflected); | |
613 int modifiers = java_lang_reflect_Field::modifiers(reflected); | |
614 | |
615 if (must_be_static >= 0) { | |
616 int really_is_static = ((modifiers & JVM_ACC_STATIC) != 0); | |
617 if (must_be_static != really_is_static) { | |
618 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
619 } | |
620 } | |
621 | |
622 int offset = instanceKlass::cast(k)->offset_from_fields(slot); | |
623 return field_offset_from_byte_offset(offset); | |
624 } | |
625 | |
626 UNSAFE_ENTRY(jlong, Unsafe_ObjectFieldOffset(JNIEnv *env, jobject unsafe, jobject field)) | |
627 UnsafeWrapper("Unsafe_ObjectFieldOffset"); | |
628 return find_field_offset(field, 0, THREAD); | |
629 UNSAFE_END | |
630 | |
631 UNSAFE_ENTRY(jlong, Unsafe_StaticFieldOffset(JNIEnv *env, jobject unsafe, jobject field)) | |
632 UnsafeWrapper("Unsafe_StaticFieldOffset"); | |
633 return find_field_offset(field, 1, THREAD); | |
634 UNSAFE_END | |
635 | |
636 UNSAFE_ENTRY(jobject, Unsafe_StaticFieldBaseFromField(JNIEnv *env, jobject unsafe, jobject field)) | |
637 UnsafeWrapper("Unsafe_StaticFieldBase"); | |
638 // Note: In this VM implementation, a field address is always a short | |
639 // offset from the base of a a klass metaobject. Thus, the full dynamic | |
640 // range of the return type is never used. However, some implementations | |
641 // might put the static field inside an array shared by many classes, | |
642 // or even at a fixed address, in which case the address could be quite | |
643 // large. In that last case, this function would return NULL, since | |
644 // the address would operate alone, without any base pointer. | |
645 | |
646 if (field == NULL) THROW_0(vmSymbols::java_lang_NullPointerException()); | |
647 | |
648 oop reflected = JNIHandles::resolve_non_null(field); | |
649 oop mirror = java_lang_reflect_Field::clazz(reflected); | |
650 int modifiers = java_lang_reflect_Field::modifiers(reflected); | |
651 | |
652 if ((modifiers & JVM_ACC_STATIC) == 0) { | |
653 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
654 } | |
655 | |
656 return JNIHandles::make_local(env, java_lang_Class::as_klassOop(mirror)); | |
657 UNSAFE_END | |
658 | |
659 //@deprecated | |
660 UNSAFE_ENTRY(jint, Unsafe_FieldOffset(JNIEnv *env, jobject unsafe, jobject field)) | |
661 UnsafeWrapper("Unsafe_FieldOffset"); | |
662 // tries (but fails) to be polymorphic between static and non-static: | |
663 jlong offset = find_field_offset(field, -1, THREAD); | |
664 guarantee(offset == (jint)offset, "offset fits in 32 bits"); | |
665 return (jint)offset; | |
666 UNSAFE_END | |
667 | |
668 //@deprecated | |
669 UNSAFE_ENTRY(jobject, Unsafe_StaticFieldBaseFromClass(JNIEnv *env, jobject unsafe, jobject clazz)) | |
670 UnsafeWrapper("Unsafe_StaticFieldBase"); | |
671 if (clazz == NULL) { | |
672 THROW_0(vmSymbols::java_lang_NullPointerException()); | |
673 } | |
674 return JNIHandles::make_local(env, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz))); | |
675 UNSAFE_END | |
676 | |
677 UNSAFE_ENTRY(void, Unsafe_EnsureClassInitialized(JNIEnv *env, jobject unsafe, jobject clazz)) | |
678 UnsafeWrapper("Unsafe_EnsureClassInitialized"); | |
679 if (clazz == NULL) { | |
680 THROW(vmSymbols::java_lang_NullPointerException()); | |
681 } | |
682 oop mirror = JNIHandles::resolve_non_null(clazz); | |
683 instanceKlass* k = instanceKlass::cast(java_lang_Class::as_klassOop(mirror)); | |
684 if (k != NULL) { | |
685 k->initialize(CHECK); | |
686 } | |
687 UNSAFE_END | |
688 | |
689 static void getBaseAndScale(int& base, int& scale, jclass acls, TRAPS) { | |
690 if (acls == NULL) { | |
691 THROW(vmSymbols::java_lang_NullPointerException()); | |
692 } | |
693 oop mirror = JNIHandles::resolve_non_null(acls); | |
694 klassOop k = java_lang_Class::as_klassOop(mirror); | |
695 if (k == NULL || !k->klass_part()->oop_is_array()) { | |
696 THROW(vmSymbols::java_lang_InvalidClassException()); | |
697 } else if (k->klass_part()->oop_is_objArray()) { | |
698 base = arrayOopDesc::base_offset_in_bytes(T_OBJECT); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
699 scale = heapOopSize; |
0 | 700 } else if (k->klass_part()->oop_is_typeArray()) { |
701 typeArrayKlass* tak = typeArrayKlass::cast(k); | |
702 base = tak->array_header_in_bytes(); | |
703 assert(base == arrayOopDesc::base_offset_in_bytes(tak->element_type()), "array_header_size semantics ok"); | |
704 scale = (1 << tak->log2_element_size()); | |
705 } else { | |
706 ShouldNotReachHere(); | |
707 } | |
708 } | |
709 | |
710 UNSAFE_ENTRY(jint, Unsafe_ArrayBaseOffset(JNIEnv *env, jobject unsafe, jclass acls)) | |
711 UnsafeWrapper("Unsafe_ArrayBaseOffset"); | |
712 int base, scale; | |
713 getBaseAndScale(base, scale, acls, CHECK_0); | |
714 return field_offset_from_byte_offset(base); | |
715 UNSAFE_END | |
716 | |
717 | |
718 UNSAFE_ENTRY(jint, Unsafe_ArrayIndexScale(JNIEnv *env, jobject unsafe, jclass acls)) | |
719 UnsafeWrapper("Unsafe_ArrayIndexScale"); | |
720 int base, scale; | |
721 getBaseAndScale(base, scale, acls, CHECK_0); | |
722 // This VM packs both fields and array elements down to the byte. | |
723 // But watch out: If this changes, so that array references for | |
724 // a given primitive type (say, T_BOOLEAN) use different memory units | |
725 // than fields, this method MUST return zero for such arrays. | |
726 // For example, the VM used to store sub-word sized fields in full | |
727 // words in the object layout, so that accessors like getByte(Object,int) | |
728 // did not really do what one might expect for arrays. Therefore, | |
729 // this function used to report a zero scale factor, so that the user | |
730 // would know not to attempt to access sub-word array elements. | |
731 // // Code for unpacked fields: | |
732 // if (scale < wordSize) return 0; | |
733 | |
734 // The following allows for a pretty general fieldOffset cookie scheme, | |
735 // but requires it to be linear in byte offset. | |
736 return field_offset_from_byte_offset(scale) - field_offset_from_byte_offset(0); | |
737 UNSAFE_END | |
738 | |
739 | |
740 static inline void throw_new(JNIEnv *env, const char *ename) { | |
741 char buf[100]; | |
742 strcpy(buf, "java/lang/"); | |
743 strcat(buf, ename); | |
744 jclass cls = env->FindClass(buf); | |
745 char* msg = NULL; | |
746 env->ThrowNew(cls, msg); | |
747 } | |
748 | |
749 static jclass Unsafe_DefineClass(JNIEnv *env, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd) { | |
750 { | |
751 // Code lifted from JDK 1.3 ClassLoader.c | |
752 | |
753 jbyte *body; | |
754 char *utfName; | |
755 jclass result = 0; | |
756 char buf[128]; | |
757 | |
758 if (UsePerfData) { | |
759 ClassLoader::unsafe_defineClassCallCounter()->inc(); | |
760 } | |
761 | |
762 if (data == NULL) { | |
763 throw_new(env, "NullPointerException"); | |
764 return 0; | |
765 } | |
766 | |
767 /* Work around 4153825. malloc crashes on Solaris when passed a | |
768 * negative size. | |
769 */ | |
770 if (length < 0) { | |
771 throw_new(env, "ArrayIndexOutOfBoundsException"); | |
772 return 0; | |
773 } | |
774 | |
775 body = NEW_C_HEAP_ARRAY(jbyte, length); | |
776 | |
777 if (body == 0) { | |
778 throw_new(env, "OutOfMemoryError"); | |
779 return 0; | |
780 } | |
781 | |
782 env->GetByteArrayRegion(data, offset, length, body); | |
783 | |
784 if (env->ExceptionOccurred()) | |
785 goto free_body; | |
786 | |
787 if (name != NULL) { | |
788 uint len = env->GetStringUTFLength(name); | |
789 int unicode_len = env->GetStringLength(name); | |
790 if (len >= sizeof(buf)) { | |
791 utfName = NEW_C_HEAP_ARRAY(char, len + 1); | |
792 if (utfName == NULL) { | |
793 throw_new(env, "OutOfMemoryError"); | |
794 goto free_body; | |
795 } | |
796 } else { | |
797 utfName = buf; | |
798 } | |
799 env->GetStringUTFRegion(name, 0, unicode_len, utfName); | |
800 //VerifyFixClassname(utfName); | |
801 for (uint i = 0; i < len; i++) { | |
802 if (utfName[i] == '.') utfName[i] = '/'; | |
803 } | |
804 } else { | |
805 utfName = NULL; | |
806 } | |
807 | |
808 result = JVM_DefineClass(env, utfName, loader, body, length, pd); | |
809 | |
810 if (utfName && utfName != buf) | |
811 FREE_C_HEAP_ARRAY(char, utfName); | |
812 | |
813 free_body: | |
814 FREE_C_HEAP_ARRAY(jbyte, body); | |
815 return result; | |
816 } | |
817 } | |
818 | |
819 | |
820 UNSAFE_ENTRY(jclass, Unsafe_DefineClass0(JNIEnv *env, jobject unsafe, jstring name, jbyteArray data, int offset, int length)) | |
821 UnsafeWrapper("Unsafe_DefineClass"); | |
822 { | |
823 ThreadToNativeFromVM ttnfv(thread); | |
824 | |
825 int depthFromDefineClass0 = 1; | |
826 jclass caller = JVM_GetCallerClass(env, depthFromDefineClass0); | |
827 jobject loader = (caller == NULL) ? NULL : JVM_GetClassLoader(env, caller); | |
828 jobject pd = (caller == NULL) ? NULL : JVM_GetProtectionDomain(env, caller); | |
829 | |
830 return Unsafe_DefineClass(env, name, data, offset, length, loader, pd); | |
831 } | |
832 UNSAFE_END | |
833 | |
834 | |
835 UNSAFE_ENTRY(jclass, Unsafe_DefineClass1(JNIEnv *env, jobject unsafe, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd)) | |
836 UnsafeWrapper("Unsafe_DefineClass"); | |
837 { | |
838 ThreadToNativeFromVM ttnfv(thread); | |
839 | |
840 return Unsafe_DefineClass(env, name, data, offset, length, loader, pd); | |
841 } | |
842 UNSAFE_END | |
843 | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
844 #define DAC_Args CLS"[B["OBJ |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
845 // define a class but do not make it known to the class loader or system dictionary |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
846 // - host_class: supplies context for linkage, access control, protection domain, and class loader |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
847 // - data: bytes of a class file, a raw memory address (length gives the number of bytes) |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
848 // - cp_patches: where non-null entries exist, they replace corresponding CP entries in data |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
849 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
850 // When you load an anonymous class U, it works as if you changed its name just before loading, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
851 // to a name that you will never use again. Since the name is lost, no other class can directly |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
852 // link to any member of U. Just after U is loaded, the only way to use it is reflectively, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
853 // through java.lang.Class methods like Class.newInstance. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
854 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
855 // Access checks for linkage sites within U continue to follow the same rules as for named classes. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
856 // The package of an anonymous class is given by the package qualifier on the name under which it was loaded. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
857 // An anonymous class also has special privileges to access any member of its host class. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
858 // This is the main reason why this loading operation is unsafe. The purpose of this is to |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
859 // allow language implementations to simulate "open classes"; a host class in effect gets |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
860 // new code when an anonymous class is loaded alongside it. A less convenient but more |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
861 // standard way to do this is with reflection, which can also be set to ignore access |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
862 // restrictions. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
863 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
864 // Access into an anonymous class is possible only through reflection. Therefore, there |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
865 // are no special access rules for calling into an anonymous class. The relaxed access |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
866 // rule for the host class is applied in the opposite direction: A host class reflectively |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
867 // access one of its anonymous classes. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
868 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
869 // If you load the same bytecodes twice, you get two different classes. You can reload |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
870 // the same bytecodes with or without varying CP patches. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
871 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
872 // By using the CP patching array, you can have a new anonymous class U2 refer to an older one U1. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
873 // The bytecodes for U2 should refer to U1 by a symbolic name (doesn't matter what the name is). |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
874 // The CONSTANT_Class entry for that name can be patched to refer directly to U1. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
875 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
876 // This allows, for example, U2 to use U1 as a superclass or super-interface, or as |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
877 // an outer class (so that U2 is an anonymous inner class of anonymous U1). |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
878 // It is not possible for a named class, or an older anonymous class, to refer by |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
879 // name (via its CP) to a newer anonymous class. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
880 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
881 // CP patching may also be used to modify (i.e., hack) the names of methods, classes, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
882 // or type descriptors used in the loaded anonymous class. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
883 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
884 // Finally, CP patching may be used to introduce "live" objects into the constant pool, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
885 // instead of "dead" strings. A compiled statement like println((Object)"hello") can |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
886 // be changed to println(greeting), where greeting is an arbitrary object created before |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
887 // the anonymous class is loaded. This is useful in dynamic languages, in which |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
888 // various kinds of metaobjects must be introduced as constants into bytecode. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
889 // Note the cast (Object), which tells the verifier to expect an arbitrary object, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
890 // not just a literal string. For such ldc instructions, the verifier uses the |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
891 // type Object instead of String, if the loaded constant is not in fact a String. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
892 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
893 static oop |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
894 Unsafe_DefineAnonymousClass_impl(JNIEnv *env, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
895 jclass host_class, jbyteArray data, jobjectArray cp_patches_jh, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
896 HeapWord* *temp_alloc, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
897 TRAPS) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
898 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
899 if (UsePerfData) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
900 ClassLoader::unsafe_defineClassCallCounter()->inc(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
901 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
902 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
903 if (data == NULL) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
904 THROW_0(vmSymbols::java_lang_NullPointerException()); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
905 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
906 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
907 jint length = typeArrayOop(JNIHandles::resolve_non_null(data))->length(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
908 jint word_length = (length + sizeof(HeapWord)-1) / sizeof(HeapWord); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
909 HeapWord* body = NEW_C_HEAP_ARRAY(HeapWord, word_length); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
910 if (body == NULL) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
911 THROW_0(vmSymbols::java_lang_OutOfMemoryError()); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
912 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
913 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
914 // caller responsible to free it: |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
915 (*temp_alloc) = body; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
916 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
917 { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
918 jbyte* array_base = typeArrayOop(JNIHandles::resolve_non_null(data))->byte_at_addr(0); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
919 Copy::conjoint_words((HeapWord*) array_base, body, word_length); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
920 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
921 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
922 u1* class_bytes = (u1*) body; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
923 int class_bytes_length = (int) length; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
924 if (class_bytes_length < 0) class_bytes_length = 0; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
925 if (class_bytes == NULL |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
926 || host_class == NULL |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
927 || length != class_bytes_length) |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
928 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
929 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
930 objArrayHandle cp_patches_h; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
931 if (cp_patches_jh != NULL) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
932 oop p = JNIHandles::resolve_non_null(cp_patches_jh); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
933 if (!p->is_objArray()) |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
934 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
935 cp_patches_h = objArrayHandle(THREAD, (objArrayOop)p); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
936 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
937 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
938 KlassHandle host_klass(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(host_class))); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
939 const char* host_source = host_klass->external_name(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
940 Handle host_loader(THREAD, host_klass->class_loader()); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
941 Handle host_domain(THREAD, host_klass->protection_domain()); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
942 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
943 GrowableArray<Handle>* cp_patches = NULL; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
944 if (cp_patches_h.not_null()) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
945 int alen = cp_patches_h->length(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
946 for (int i = alen-1; i >= 0; i--) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
947 oop p = cp_patches_h->obj_at(i); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
948 if (p != NULL) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
949 Handle patch(THREAD, p); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
950 if (cp_patches == NULL) |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
951 cp_patches = new GrowableArray<Handle>(i+1, i+1, Handle()); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
952 cp_patches->at_put(i, patch); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
953 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
954 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
955 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
956 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
957 ClassFileStream st(class_bytes, class_bytes_length, (char*) host_source); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
958 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
959 instanceKlassHandle anon_klass; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
960 { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
961 symbolHandle no_class_name; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
962 klassOop anonk = SystemDictionary::parse_stream(no_class_name, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
963 host_loader, host_domain, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
964 &st, host_klass, cp_patches, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
965 CHECK_NULL); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
966 if (anonk == NULL) return NULL; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
967 anon_klass = instanceKlassHandle(THREAD, anonk); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
968 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
969 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
970 // let caller initialize it as needed... |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
971 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
972 return anon_klass->java_mirror(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
973 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
974 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
975 UNSAFE_ENTRY(jclass, Unsafe_DefineAnonymousClass(JNIEnv *env, jobject unsafe, jclass host_class, jbyteArray data, jobjectArray cp_patches_jh)) |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
976 { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
977 UnsafeWrapper("Unsafe_DefineAnonymousClass"); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
978 ResourceMark rm(THREAD); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
979 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
980 HeapWord* temp_alloc = NULL; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
981 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
982 jobject res_jh = NULL; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
983 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
984 { oop res_oop = Unsafe_DefineAnonymousClass_impl(env, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
985 host_class, data, cp_patches_jh, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
986 &temp_alloc, THREAD); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
987 if (res_oop != NULL) |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
988 res_jh = JNIHandles::make_local(env, res_oop); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
989 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
990 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
991 // try/finally clause: |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
992 if (temp_alloc != NULL) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
993 FREE_C_HEAP_ARRAY(HeapWord, temp_alloc); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
994 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
995 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
996 return (jclass) res_jh; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
997 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
998 UNSAFE_END |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
999 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1000 |
0 | 1001 |
1002 UNSAFE_ENTRY(void, Unsafe_MonitorEnter(JNIEnv *env, jobject unsafe, jobject jobj)) | |
1003 UnsafeWrapper("Unsafe_MonitorEnter"); | |
1004 { | |
1005 if (jobj == NULL) { | |
1006 THROW(vmSymbols::java_lang_NullPointerException()); | |
1007 } | |
1008 Handle obj(thread, JNIHandles::resolve_non_null(jobj)); | |
1009 ObjectSynchronizer::jni_enter(obj, CHECK); | |
1010 } | |
1011 UNSAFE_END | |
1012 | |
1013 | |
1014 UNSAFE_ENTRY(jboolean, Unsafe_TryMonitorEnter(JNIEnv *env, jobject unsafe, jobject jobj)) | |
1015 UnsafeWrapper("Unsafe_TryMonitorEnter"); | |
1016 { | |
1017 if (jobj == NULL) { | |
1018 THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE); | |
1019 } | |
1020 Handle obj(thread, JNIHandles::resolve_non_null(jobj)); | |
1021 bool res = ObjectSynchronizer::jni_try_enter(obj, CHECK_0); | |
1022 return (res ? JNI_TRUE : JNI_FALSE); | |
1023 } | |
1024 UNSAFE_END | |
1025 | |
1026 | |
1027 UNSAFE_ENTRY(void, Unsafe_MonitorExit(JNIEnv *env, jobject unsafe, jobject jobj)) | |
1028 UnsafeWrapper("Unsafe_MonitorExit"); | |
1029 { | |
1030 if (jobj == NULL) { | |
1031 THROW(vmSymbols::java_lang_NullPointerException()); | |
1032 } | |
1033 Handle obj(THREAD, JNIHandles::resolve_non_null(jobj)); | |
1034 ObjectSynchronizer::jni_exit(obj(), CHECK); | |
1035 } | |
1036 UNSAFE_END | |
1037 | |
1038 | |
1039 UNSAFE_ENTRY(void, Unsafe_ThrowException(JNIEnv *env, jobject unsafe, jthrowable thr)) | |
1040 UnsafeWrapper("Unsafe_ThrowException"); | |
1041 { | |
1042 ThreadToNativeFromVM ttnfv(thread); | |
1043 env->Throw(thr); | |
1044 } | |
1045 UNSAFE_END | |
1046 | |
1047 // JSR166 ------------------------------------------------------------------ | |
1048 | |
1049 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h)) | |
1050 UnsafeWrapper("Unsafe_CompareAndSwapObject"); | |
1051 oop x = JNIHandles::resolve(x_h); | |
1052 oop e = JNIHandles::resolve(e_h); | |
1053 oop p = JNIHandles::resolve(obj); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1054 HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
431
diff
changeset
|
1055 if (UseCompressedOops) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
431
diff
changeset
|
1056 update_barrier_set_pre((narrowOop*)addr, e); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
431
diff
changeset
|
1057 } else { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
431
diff
changeset
|
1058 update_barrier_set_pre((oop*)addr, e); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
431
diff
changeset
|
1059 } |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1060 oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1061 jboolean success = (res == e); |
0 | 1062 if (success) |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1063 update_barrier_set((void*)addr, x); |
0 | 1064 return success; |
1065 UNSAFE_END | |
1066 | |
1067 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) | |
1068 UnsafeWrapper("Unsafe_CompareAndSwapInt"); | |
1069 oop p = JNIHandles::resolve(obj); | |
1070 jint* addr = (jint *) index_oop_from_field_offset_long(p, offset); | |
1071 return (jint)(Atomic::cmpxchg(x, addr, e)) == e; | |
1072 UNSAFE_END | |
1073 | |
1074 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) | |
1075 UnsafeWrapper("Unsafe_CompareAndSwapLong"); | |
1076 Handle p (THREAD, JNIHandles::resolve(obj)); | |
1077 jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); | |
1078 if (VM_Version::supports_cx8()) | |
1079 return (jlong)(Atomic::cmpxchg(x, addr, e)) == e; | |
1080 else { | |
1081 jboolean success = false; | |
1082 ObjectLocker ol(p, THREAD); | |
1083 if (*addr == e) { *addr = x; success = true; } | |
1084 return success; | |
1085 } | |
1086 UNSAFE_END | |
1087 | |
1088 UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time)) | |
1089 UnsafeWrapper("Unsafe_Park"); | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
845
diff
changeset
|
1090 HS_DTRACE_PROBE3(hotspot, thread__park__begin, thread->parker(), (int) isAbsolute, time); |
0 | 1091 JavaThreadParkedState jtps(thread, time != 0); |
1092 thread->parker()->park(isAbsolute != 0, time); | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
845
diff
changeset
|
1093 HS_DTRACE_PROBE1(hotspot, thread__park__end, thread->parker()); |
0 | 1094 UNSAFE_END |
1095 | |
1096 UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread)) | |
1097 UnsafeWrapper("Unsafe_Unpark"); | |
1098 Parker* p = NULL; | |
1099 if (jthread != NULL) { | |
1100 oop java_thread = JNIHandles::resolve_non_null(jthread); | |
1101 if (java_thread != NULL) { | |
1102 jlong lp = java_lang_Thread::park_event(java_thread); | |
1103 if (lp != 0) { | |
1104 // This cast is OK even though the jlong might have been read | |
1105 // non-atomically on 32bit systems, since there, one word will | |
1106 // always be zero anyway and the value set is always the same | |
1107 p = (Parker*)addr_from_java(lp); | |
1108 } else { | |
1109 // Grab lock if apparently null or using older version of library | |
1110 MutexLocker mu(Threads_lock); | |
1111 java_thread = JNIHandles::resolve_non_null(jthread); | |
1112 if (java_thread != NULL) { | |
1113 JavaThread* thr = java_lang_Thread::thread(java_thread); | |
1114 if (thr != NULL) { | |
1115 p = thr->parker(); | |
1116 if (p != NULL) { // Bind to Java thread for next time. | |
1117 java_lang_Thread::set_park_event(java_thread, addr_to_java(p)); | |
1118 } | |
1119 } | |
1120 } | |
1121 } | |
1122 } | |
1123 } | |
1124 if (p != NULL) { | |
1324
e392695de029
6935224: Adding new DTrace probes to work with Palantir
fparain
parents:
845
diff
changeset
|
1125 HS_DTRACE_PROBE1(hotspot, thread__unpark, p); |
0 | 1126 p->unpark(); |
1127 } | |
1128 UNSAFE_END | |
1129 | |
1130 UNSAFE_ENTRY(jint, Unsafe_Loadavg(JNIEnv *env, jobject unsafe, jdoubleArray loadavg, jint nelem)) | |
1131 UnsafeWrapper("Unsafe_Loadavg"); | |
1132 const int max_nelem = 3; | |
1133 double la[max_nelem]; | |
1134 jint ret; | |
1135 | |
1136 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(loadavg)); | |
1137 assert(a->is_typeArray(), "must be type array"); | |
1138 | |
1139 if (nelem < 0 || nelem > max_nelem || a->length() < nelem) { | |
1140 ThreadToNativeFromVM ttnfv(thread); | |
1141 throw_new(env, "ArrayIndexOutOfBoundsException"); | |
1142 return -1; | |
1143 } | |
1144 | |
1145 ret = os::loadavg(la, nelem); | |
1146 if (ret == -1) return -1; | |
1147 | |
1148 // if successful, ret is the number of samples actually retrieved. | |
1149 assert(ret >= 0 && ret <= max_nelem, "Unexpected loadavg return value"); | |
1150 switch(ret) { | |
1151 case 3: a->double_at_put(2, (jdouble)la[2]); // fall through | |
1152 case 2: a->double_at_put(1, (jdouble)la[1]); // fall through | |
1153 case 1: a->double_at_put(0, (jdouble)la[0]); break; | |
1154 } | |
1155 return ret; | |
1156 UNSAFE_END | |
1157 | |
1158 UNSAFE_ENTRY(void, Unsafe_PrefetchRead(JNIEnv* env, jclass ignored, jobject obj, jlong offset)) | |
1159 UnsafeWrapper("Unsafe_PrefetchRead"); | |
1160 oop p = JNIHandles::resolve(obj); | |
1161 void* addr = index_oop_from_field_offset_long(p, 0); | |
1162 Prefetch::read(addr, (intx)offset); | |
1163 UNSAFE_END | |
1164 | |
1165 UNSAFE_ENTRY(void, Unsafe_PrefetchWrite(JNIEnv* env, jclass ignored, jobject obj, jlong offset)) | |
1166 UnsafeWrapper("Unsafe_PrefetchWrite"); | |
1167 oop p = JNIHandles::resolve(obj); | |
1168 void* addr = index_oop_from_field_offset_long(p, 0); | |
1169 Prefetch::write(addr, (intx)offset); | |
1170 UNSAFE_END | |
1171 | |
1172 | |
1173 /// JVM_RegisterUnsafeMethods | |
1174 | |
1175 #define ADR "J" | |
1176 | |
1177 #define LANG "Ljava/lang/" | |
1178 | |
1179 #define OBJ LANG"Object;" | |
1180 #define CLS LANG"Class;" | |
1181 #define CTR LANG"reflect/Constructor;" | |
1182 #define FLD LANG"reflect/Field;" | |
1183 #define MTH LANG"reflect/Method;" | |
1184 #define THR LANG"Throwable;" | |
1185 | |
1186 #define DC0_Args LANG"String;[BII" | |
1187 #define DC1_Args DC0_Args LANG"ClassLoader;" "Ljava/security/ProtectionDomain;" | |
1188 | |
1189 #define CC (char*) /*cast a literal from (const char*)*/ | |
1190 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f) | |
1191 | |
1192 // define deprecated accessors for compabitility with 1.4.0 | |
1193 #define DECLARE_GETSETOOP_140(Boolean, Z) \ | |
1194 {CC"get"#Boolean, CC"("OBJ"I)"#Z, FN_PTR(Unsafe_Get##Boolean##140)}, \ | |
1195 {CC"put"#Boolean, CC"("OBJ"I"#Z")V", FN_PTR(Unsafe_Set##Boolean##140)} | |
1196 | |
1197 // Note: In 1.4.1, getObject and kin take both int and long offsets. | |
1198 #define DECLARE_GETSETOOP_141(Boolean, Z) \ | |
1199 {CC"get"#Boolean, CC"("OBJ"J)"#Z, FN_PTR(Unsafe_Get##Boolean)}, \ | |
1200 {CC"put"#Boolean, CC"("OBJ"J"#Z")V", FN_PTR(Unsafe_Set##Boolean)} | |
1201 | |
1202 // Note: In 1.5.0, there are volatile versions too | |
1203 #define DECLARE_GETSETOOP(Boolean, Z) \ | |
1204 {CC"get"#Boolean, CC"("OBJ"J)"#Z, FN_PTR(Unsafe_Get##Boolean)}, \ | |
1205 {CC"put"#Boolean, CC"("OBJ"J"#Z")V", FN_PTR(Unsafe_Set##Boolean)}, \ | |
1206 {CC"get"#Boolean"Volatile", CC"("OBJ"J)"#Z, FN_PTR(Unsafe_Get##Boolean##Volatile)}, \ | |
1207 {CC"put"#Boolean"Volatile", CC"("OBJ"J"#Z")V", FN_PTR(Unsafe_Set##Boolean##Volatile)} | |
1208 | |
1209 | |
1210 #define DECLARE_GETSETNATIVE(Byte, B) \ | |
1211 {CC"get"#Byte, CC"("ADR")"#B, FN_PTR(Unsafe_GetNative##Byte)}, \ | |
1212 {CC"put"#Byte, CC"("ADR#B")V", FN_PTR(Unsafe_SetNative##Byte)} | |
1213 | |
1214 | |
1215 | |
1216 // %%% These are temporarily supported until the SDK sources | |
1217 // contain the necessarily updated Unsafe.java. | |
1218 static JNINativeMethod methods_140[] = { | |
1219 | |
1220 {CC"getObject", CC"("OBJ"I)"OBJ"", FN_PTR(Unsafe_GetObject140)}, | |
1221 {CC"putObject", CC"("OBJ"I"OBJ")V", FN_PTR(Unsafe_SetObject140)}, | |
1222 | |
1223 DECLARE_GETSETOOP_140(Boolean, Z), | |
1224 DECLARE_GETSETOOP_140(Byte, B), | |
1225 DECLARE_GETSETOOP_140(Short, S), | |
1226 DECLARE_GETSETOOP_140(Char, C), | |
1227 DECLARE_GETSETOOP_140(Int, I), | |
1228 DECLARE_GETSETOOP_140(Long, J), | |
1229 DECLARE_GETSETOOP_140(Float, F), | |
1230 DECLARE_GETSETOOP_140(Double, D), | |
1231 | |
1232 DECLARE_GETSETNATIVE(Byte, B), | |
1233 DECLARE_GETSETNATIVE(Short, S), | |
1234 DECLARE_GETSETNATIVE(Char, C), | |
1235 DECLARE_GETSETNATIVE(Int, I), | |
1236 DECLARE_GETSETNATIVE(Long, J), | |
1237 DECLARE_GETSETNATIVE(Float, F), | |
1238 DECLARE_GETSETNATIVE(Double, D), | |
1239 | |
1240 {CC"getAddress", CC"("ADR")"ADR, FN_PTR(Unsafe_GetNativeAddress)}, | |
1241 {CC"putAddress", CC"("ADR""ADR")V", FN_PTR(Unsafe_SetNativeAddress)}, | |
1242 | |
1243 {CC"allocateMemory", CC"(J)"ADR, FN_PTR(Unsafe_AllocateMemory)}, | |
1244 {CC"reallocateMemory", CC"("ADR"J)"ADR, FN_PTR(Unsafe_ReallocateMemory)}, | |
1245 // {CC"setMemory", CC"("ADR"JB)V", FN_PTR(Unsafe_SetMemory)}, | |
1246 // {CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)}, | |
1247 {CC"freeMemory", CC"("ADR")V", FN_PTR(Unsafe_FreeMemory)}, | |
1248 | |
1249 {CC"fieldOffset", CC"("FLD")I", FN_PTR(Unsafe_FieldOffset)}, //deprecated | |
1250 {CC"staticFieldBase", CC"("CLS")"OBJ, FN_PTR(Unsafe_StaticFieldBaseFromClass)}, //deprecated | |
1251 {CC"ensureClassInitialized",CC"("CLS")V", FN_PTR(Unsafe_EnsureClassInitialized)}, | |
1252 {CC"arrayBaseOffset", CC"("CLS")I", FN_PTR(Unsafe_ArrayBaseOffset)}, | |
1253 {CC"arrayIndexScale", CC"("CLS")I", FN_PTR(Unsafe_ArrayIndexScale)}, | |
1254 {CC"addressSize", CC"()I", FN_PTR(Unsafe_AddressSize)}, | |
1255 {CC"pageSize", CC"()I", FN_PTR(Unsafe_PageSize)}, | |
1256 | |
1257 {CC"defineClass", CC"("DC0_Args")"CLS, FN_PTR(Unsafe_DefineClass0)}, | |
1258 {CC"defineClass", CC"("DC1_Args")"CLS, FN_PTR(Unsafe_DefineClass1)}, | |
1259 {CC"allocateInstance", CC"("CLS")"OBJ, FN_PTR(Unsafe_AllocateInstance)}, | |
1260 {CC"monitorEnter", CC"("OBJ")V", FN_PTR(Unsafe_MonitorEnter)}, | |
1261 {CC"monitorExit", CC"("OBJ")V", FN_PTR(Unsafe_MonitorExit)}, | |
1262 {CC"throwException", CC"("THR")V", FN_PTR(Unsafe_ThrowException)} | |
1263 }; | |
1264 | |
1265 // These are the old methods prior to the JSR 166 changes in 1.5.0 | |
1266 static JNINativeMethod methods_141[] = { | |
1267 | |
1268 {CC"getObject", CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObject)}, | |
1269 {CC"putObject", CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObject)}, | |
1270 | |
1271 DECLARE_GETSETOOP_141(Boolean, Z), | |
1272 DECLARE_GETSETOOP_141(Byte, B), | |
1273 DECLARE_GETSETOOP_141(Short, S), | |
1274 DECLARE_GETSETOOP_141(Char, C), | |
1275 DECLARE_GETSETOOP_141(Int, I), | |
1276 DECLARE_GETSETOOP_141(Long, J), | |
1277 DECLARE_GETSETOOP_141(Float, F), | |
1278 DECLARE_GETSETOOP_141(Double, D), | |
1279 | |
1280 DECLARE_GETSETNATIVE(Byte, B), | |
1281 DECLARE_GETSETNATIVE(Short, S), | |
1282 DECLARE_GETSETNATIVE(Char, C), | |
1283 DECLARE_GETSETNATIVE(Int, I), | |
1284 DECLARE_GETSETNATIVE(Long, J), | |
1285 DECLARE_GETSETNATIVE(Float, F), | |
1286 DECLARE_GETSETNATIVE(Double, D), | |
1287 | |
1288 {CC"getAddress", CC"("ADR")"ADR, FN_PTR(Unsafe_GetNativeAddress)}, | |
1289 {CC"putAddress", CC"("ADR""ADR")V", FN_PTR(Unsafe_SetNativeAddress)}, | |
1290 | |
1291 {CC"allocateMemory", CC"(J)"ADR, FN_PTR(Unsafe_AllocateMemory)}, | |
1292 {CC"reallocateMemory", CC"("ADR"J)"ADR, FN_PTR(Unsafe_ReallocateMemory)}, | |
1293 // {CC"setMemory", CC"("ADR"JB)V", FN_PTR(Unsafe_SetMemory)}, | |
1294 // {CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)}, | |
1295 {CC"freeMemory", CC"("ADR")V", FN_PTR(Unsafe_FreeMemory)}, | |
1296 | |
1297 {CC"objectFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_ObjectFieldOffset)}, | |
1298 {CC"staticFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_StaticFieldOffset)}, | |
1299 {CC"staticFieldBase", CC"("FLD")"OBJ, FN_PTR(Unsafe_StaticFieldBaseFromField)}, | |
1300 {CC"ensureClassInitialized",CC"("CLS")V", FN_PTR(Unsafe_EnsureClassInitialized)}, | |
1301 {CC"arrayBaseOffset", CC"("CLS")I", FN_PTR(Unsafe_ArrayBaseOffset)}, | |
1302 {CC"arrayIndexScale", CC"("CLS")I", FN_PTR(Unsafe_ArrayIndexScale)}, | |
1303 {CC"addressSize", CC"()I", FN_PTR(Unsafe_AddressSize)}, | |
1304 {CC"pageSize", CC"()I", FN_PTR(Unsafe_PageSize)}, | |
1305 | |
1306 {CC"defineClass", CC"("DC0_Args")"CLS, FN_PTR(Unsafe_DefineClass0)}, | |
1307 {CC"defineClass", CC"("DC1_Args")"CLS, FN_PTR(Unsafe_DefineClass1)}, | |
1308 {CC"allocateInstance", CC"("CLS")"OBJ, FN_PTR(Unsafe_AllocateInstance)}, | |
1309 {CC"monitorEnter", CC"("OBJ")V", FN_PTR(Unsafe_MonitorEnter)}, | |
1310 {CC"monitorExit", CC"("OBJ")V", FN_PTR(Unsafe_MonitorExit)}, | |
1311 {CC"throwException", CC"("THR")V", FN_PTR(Unsafe_ThrowException)} | |
1312 | |
1313 }; | |
1314 | |
1315 // These are the old methods prior to the JSR 166 changes in 1.6.0 | |
1316 static JNINativeMethod methods_15[] = { | |
1317 | |
1318 {CC"getObject", CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObject)}, | |
1319 {CC"putObject", CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObject)}, | |
1320 {CC"getObjectVolatile",CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObjectVolatile)}, | |
1321 {CC"putObjectVolatile",CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObjectVolatile)}, | |
1322 | |
1323 | |
1324 DECLARE_GETSETOOP(Boolean, Z), | |
1325 DECLARE_GETSETOOP(Byte, B), | |
1326 DECLARE_GETSETOOP(Short, S), | |
1327 DECLARE_GETSETOOP(Char, C), | |
1328 DECLARE_GETSETOOP(Int, I), | |
1329 DECLARE_GETSETOOP(Long, J), | |
1330 DECLARE_GETSETOOP(Float, F), | |
1331 DECLARE_GETSETOOP(Double, D), | |
1332 | |
1333 DECLARE_GETSETNATIVE(Byte, B), | |
1334 DECLARE_GETSETNATIVE(Short, S), | |
1335 DECLARE_GETSETNATIVE(Char, C), | |
1336 DECLARE_GETSETNATIVE(Int, I), | |
1337 DECLARE_GETSETNATIVE(Long, J), | |
1338 DECLARE_GETSETNATIVE(Float, F), | |
1339 DECLARE_GETSETNATIVE(Double, D), | |
1340 | |
1341 {CC"getAddress", CC"("ADR")"ADR, FN_PTR(Unsafe_GetNativeAddress)}, | |
1342 {CC"putAddress", CC"("ADR""ADR")V", FN_PTR(Unsafe_SetNativeAddress)}, | |
1343 | |
1344 {CC"allocateMemory", CC"(J)"ADR, FN_PTR(Unsafe_AllocateMemory)}, | |
1345 {CC"reallocateMemory", CC"("ADR"J)"ADR, FN_PTR(Unsafe_ReallocateMemory)}, | |
1346 // {CC"setMemory", CC"("ADR"JB)V", FN_PTR(Unsafe_SetMemory)}, | |
1347 // {CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)}, | |
1348 {CC"freeMemory", CC"("ADR")V", FN_PTR(Unsafe_FreeMemory)}, | |
1349 | |
1350 {CC"objectFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_ObjectFieldOffset)}, | |
1351 {CC"staticFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_StaticFieldOffset)}, | |
1352 {CC"staticFieldBase", CC"("FLD")"OBJ, FN_PTR(Unsafe_StaticFieldBaseFromField)}, | |
1353 {CC"ensureClassInitialized",CC"("CLS")V", FN_PTR(Unsafe_EnsureClassInitialized)}, | |
1354 {CC"arrayBaseOffset", CC"("CLS")I", FN_PTR(Unsafe_ArrayBaseOffset)}, | |
1355 {CC"arrayIndexScale", CC"("CLS")I", FN_PTR(Unsafe_ArrayIndexScale)}, | |
1356 {CC"addressSize", CC"()I", FN_PTR(Unsafe_AddressSize)}, | |
1357 {CC"pageSize", CC"()I", FN_PTR(Unsafe_PageSize)}, | |
1358 | |
1359 {CC"defineClass", CC"("DC0_Args")"CLS, FN_PTR(Unsafe_DefineClass0)}, | |
1360 {CC"defineClass", CC"("DC1_Args")"CLS, FN_PTR(Unsafe_DefineClass1)}, | |
1361 {CC"allocateInstance", CC"("CLS")"OBJ, FN_PTR(Unsafe_AllocateInstance)}, | |
1362 {CC"monitorEnter", CC"("OBJ")V", FN_PTR(Unsafe_MonitorEnter)}, | |
1363 {CC"monitorExit", CC"("OBJ")V", FN_PTR(Unsafe_MonitorExit)}, | |
1364 {CC"throwException", CC"("THR")V", FN_PTR(Unsafe_ThrowException)}, | |
1365 {CC"compareAndSwapObject", CC"("OBJ"J"OBJ""OBJ")Z", FN_PTR(Unsafe_CompareAndSwapObject)}, | |
1366 {CC"compareAndSwapInt", CC"("OBJ"J""I""I"")Z", FN_PTR(Unsafe_CompareAndSwapInt)}, | |
1367 {CC"compareAndSwapLong", CC"("OBJ"J""J""J"")Z", FN_PTR(Unsafe_CompareAndSwapLong)}, | |
1368 {CC"park", CC"(ZJ)V", FN_PTR(Unsafe_Park)}, | |
1369 {CC"unpark", CC"("OBJ")V", FN_PTR(Unsafe_Unpark)} | |
1370 | |
1371 }; | |
1372 | |
1373 // These are the correct methods, moving forward: | |
1374 static JNINativeMethod methods[] = { | |
1375 | |
1376 {CC"getObject", CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObject)}, | |
1377 {CC"putObject", CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObject)}, | |
1378 {CC"getObjectVolatile",CC"("OBJ"J)"OBJ"", FN_PTR(Unsafe_GetObjectVolatile)}, | |
1379 {CC"putObjectVolatile",CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetObjectVolatile)}, | |
1380 | |
1381 | |
1382 DECLARE_GETSETOOP(Boolean, Z), | |
1383 DECLARE_GETSETOOP(Byte, B), | |
1384 DECLARE_GETSETOOP(Short, S), | |
1385 DECLARE_GETSETOOP(Char, C), | |
1386 DECLARE_GETSETOOP(Int, I), | |
1387 DECLARE_GETSETOOP(Long, J), | |
1388 DECLARE_GETSETOOP(Float, F), | |
1389 DECLARE_GETSETOOP(Double, D), | |
1390 | |
1391 DECLARE_GETSETNATIVE(Byte, B), | |
1392 DECLARE_GETSETNATIVE(Short, S), | |
1393 DECLARE_GETSETNATIVE(Char, C), | |
1394 DECLARE_GETSETNATIVE(Int, I), | |
1395 DECLARE_GETSETNATIVE(Long, J), | |
1396 DECLARE_GETSETNATIVE(Float, F), | |
1397 DECLARE_GETSETNATIVE(Double, D), | |
1398 | |
1399 {CC"getAddress", CC"("ADR")"ADR, FN_PTR(Unsafe_GetNativeAddress)}, | |
1400 {CC"putAddress", CC"("ADR""ADR")V", FN_PTR(Unsafe_SetNativeAddress)}, | |
1401 | |
1402 {CC"allocateMemory", CC"(J)"ADR, FN_PTR(Unsafe_AllocateMemory)}, | |
1403 {CC"reallocateMemory", CC"("ADR"J)"ADR, FN_PTR(Unsafe_ReallocateMemory)}, | |
1404 // {CC"setMemory", CC"("ADR"JB)V", FN_PTR(Unsafe_SetMemory)}, | |
1405 // {CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)}, | |
1406 {CC"freeMemory", CC"("ADR")V", FN_PTR(Unsafe_FreeMemory)}, | |
1407 | |
1408 {CC"objectFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_ObjectFieldOffset)}, | |
1409 {CC"staticFieldOffset", CC"("FLD")J", FN_PTR(Unsafe_StaticFieldOffset)}, | |
1410 {CC"staticFieldBase", CC"("FLD")"OBJ, FN_PTR(Unsafe_StaticFieldBaseFromField)}, | |
1411 {CC"ensureClassInitialized",CC"("CLS")V", FN_PTR(Unsafe_EnsureClassInitialized)}, | |
1412 {CC"arrayBaseOffset", CC"("CLS")I", FN_PTR(Unsafe_ArrayBaseOffset)}, | |
1413 {CC"arrayIndexScale", CC"("CLS")I", FN_PTR(Unsafe_ArrayIndexScale)}, | |
1414 {CC"addressSize", CC"()I", FN_PTR(Unsafe_AddressSize)}, | |
1415 {CC"pageSize", CC"()I", FN_PTR(Unsafe_PageSize)}, | |
1416 | |
1417 {CC"defineClass", CC"("DC0_Args")"CLS, FN_PTR(Unsafe_DefineClass0)}, | |
1418 {CC"defineClass", CC"("DC1_Args")"CLS, FN_PTR(Unsafe_DefineClass1)}, | |
1419 {CC"allocateInstance", CC"("CLS")"OBJ, FN_PTR(Unsafe_AllocateInstance)}, | |
1420 {CC"monitorEnter", CC"("OBJ")V", FN_PTR(Unsafe_MonitorEnter)}, | |
1421 {CC"monitorExit", CC"("OBJ")V", FN_PTR(Unsafe_MonitorExit)}, | |
1422 {CC"tryMonitorEnter", CC"("OBJ")Z", FN_PTR(Unsafe_TryMonitorEnter)}, | |
1423 {CC"throwException", CC"("THR")V", FN_PTR(Unsafe_ThrowException)}, | |
1424 {CC"compareAndSwapObject", CC"("OBJ"J"OBJ""OBJ")Z", FN_PTR(Unsafe_CompareAndSwapObject)}, | |
1425 {CC"compareAndSwapInt", CC"("OBJ"J""I""I"")Z", FN_PTR(Unsafe_CompareAndSwapInt)}, | |
1426 {CC"compareAndSwapLong", CC"("OBJ"J""J""J"")Z", FN_PTR(Unsafe_CompareAndSwapLong)}, | |
1427 {CC"putOrderedObject", CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetOrderedObject)}, | |
1428 {CC"putOrderedInt", CC"("OBJ"JI)V", FN_PTR(Unsafe_SetOrderedInt)}, | |
1429 {CC"putOrderedLong", CC"("OBJ"JJ)V", FN_PTR(Unsafe_SetOrderedLong)}, | |
1430 {CC"park", CC"(ZJ)V", FN_PTR(Unsafe_Park)}, | |
1431 {CC"unpark", CC"("OBJ")V", FN_PTR(Unsafe_Unpark)} | |
1432 | |
1433 // {CC"getLoadAverage", CC"([DI)I", FN_PTR(Unsafe_Loadavg)}, | |
1434 | |
1435 // {CC"prefetchRead", CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchRead)}, | |
1436 // {CC"prefetchWrite", CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchWrite)} | |
1437 // {CC"prefetchReadStatic", CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchRead)}, | |
1438 // {CC"prefetchWriteStatic",CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchWrite)} | |
1439 | |
1440 }; | |
1441 | |
1442 JNINativeMethod loadavg_method[] = { | |
1443 {CC"getLoadAverage", CC"([DI)I", FN_PTR(Unsafe_Loadavg)} | |
1444 }; | |
1445 | |
1446 JNINativeMethod prefetch_methods[] = { | |
1447 {CC"prefetchRead", CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchRead)}, | |
1448 {CC"prefetchWrite", CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchWrite)}, | |
1449 {CC"prefetchReadStatic", CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchRead)}, | |
1450 {CC"prefetchWriteStatic",CC"("OBJ"J)V", FN_PTR(Unsafe_PrefetchWrite)} | |
1451 }; | |
1452 | |
1453 JNINativeMethod memcopy_methods[] = { | |
1454 {CC"copyMemory", CC"("OBJ"J"OBJ"JJ)V", FN_PTR(Unsafe_CopyMemory2)}, | |
1455 {CC"setMemory", CC"("OBJ"JJB)V", FN_PTR(Unsafe_SetMemory2)} | |
1456 }; | |
1457 | |
1458 JNINativeMethod memcopy_methods_15[] = { | |
1459 {CC"setMemory", CC"("ADR"JB)V", FN_PTR(Unsafe_SetMemory)}, | |
1460 {CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)} | |
1461 }; | |
1462 | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1463 JNINativeMethod anonk_methods[] = { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1464 {CC"defineAnonymousClass", CC"("DAC_Args")"CLS, FN_PTR(Unsafe_DefineAnonymousClass)}, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1465 }; |
0 | 1466 |
1467 #undef CC | |
1468 #undef FN_PTR | |
1469 | |
1470 #undef ADR | |
1471 #undef LANG | |
1472 #undef OBJ | |
1473 #undef CLS | |
1474 #undef CTR | |
1475 #undef FLD | |
1476 #undef MTH | |
1477 #undef THR | |
1478 #undef DC0_Args | |
1479 #undef DC1_Args | |
1480 | |
1481 #undef DECLARE_GETSETOOP | |
1482 #undef DECLARE_GETSETNATIVE | |
1483 | |
1484 | |
1485 // This one function is exported, used by NativeLookup. | |
1486 // The Unsafe_xxx functions above are called only from the interpreter. | |
1487 // The optimizer looks at names and signatures to recognize | |
1488 // individual functions. | |
1489 | |
1490 JVM_ENTRY(void, JVM_RegisterUnsafeMethods(JNIEnv *env, jclass unsafecls)) | |
1491 UnsafeWrapper("JVM_RegisterUnsafeMethods"); | |
1492 { | |
1493 ThreadToNativeFromVM ttnfv(thread); | |
1494 { | |
1495 env->RegisterNatives(unsafecls, loadavg_method, sizeof(loadavg_method)/sizeof(JNINativeMethod)); | |
1496 if (env->ExceptionOccurred()) { | |
1497 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
1498 tty->print_cr("Warning: SDK 1.6 Unsafe.loadavg not found."); | |
1499 } | |
1500 env->ExceptionClear(); | |
1501 } | |
1502 } | |
1503 { | |
1504 env->RegisterNatives(unsafecls, prefetch_methods, sizeof(prefetch_methods)/sizeof(JNINativeMethod)); | |
1505 if (env->ExceptionOccurred()) { | |
1506 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
1507 tty->print_cr("Warning: SDK 1.6 Unsafe.prefetchRead/Write not found."); | |
1508 } | |
1509 env->ExceptionClear(); | |
1510 } | |
1511 } | |
1512 { | |
1513 env->RegisterNatives(unsafecls, memcopy_methods, sizeof(memcopy_methods)/sizeof(JNINativeMethod)); | |
1514 if (env->ExceptionOccurred()) { | |
1515 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
1516 tty->print_cr("Warning: SDK 1.7 Unsafe.copyMemory not found."); | |
1517 } | |
1518 env->ExceptionClear(); | |
1519 env->RegisterNatives(unsafecls, memcopy_methods_15, sizeof(memcopy_methods_15)/sizeof(JNINativeMethod)); | |
1520 if (env->ExceptionOccurred()) { | |
1521 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
1522 tty->print_cr("Warning: SDK 1.5 Unsafe.copyMemory not found."); | |
1523 } | |
1524 env->ExceptionClear(); | |
1525 } | |
1526 } | |
1527 } | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1528 if (AnonymousClasses) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1529 env->RegisterNatives(unsafecls, anonk_methods, sizeof(anonk_methods)/sizeof(JNINativeMethod)); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1530 if (env->ExceptionOccurred()) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1531 if (PrintMiscellaneous && (Verbose || WizardMode)) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1532 tty->print_cr("Warning: SDK 1.7 Unsafe.defineClass (anonymous version) not found."); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1533 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1534 env->ExceptionClear(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1535 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
356
diff
changeset
|
1536 } |
0 | 1537 int status = env->RegisterNatives(unsafecls, methods, sizeof(methods)/sizeof(JNINativeMethod)); |
1538 if (env->ExceptionOccurred()) { | |
1539 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
1540 tty->print_cr("Warning: SDK 1.6 version of Unsafe not found."); | |
1541 } | |
1542 env->ExceptionClear(); | |
1543 // %%% For now, be backward compatible with an older class: | |
1544 status = env->RegisterNatives(unsafecls, methods_15, sizeof(methods_15)/sizeof(JNINativeMethod)); | |
1545 } | |
1546 if (env->ExceptionOccurred()) { | |
1547 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
1548 tty->print_cr("Warning: SDK 1.5 version of Unsafe not found."); | |
1549 } | |
1550 env->ExceptionClear(); | |
1551 // %%% For now, be backward compatible with an older class: | |
1552 status = env->RegisterNatives(unsafecls, methods_141, sizeof(methods_141)/sizeof(JNINativeMethod)); | |
1553 } | |
1554 if (env->ExceptionOccurred()) { | |
1555 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
1556 tty->print_cr("Warning: SDK 1.4.1 version of Unsafe not found."); | |
1557 } | |
1558 env->ExceptionClear(); | |
1559 // %%% For now, be backward compatible with an older class: | |
1560 status = env->RegisterNatives(unsafecls, methods_140, sizeof(methods_140)/sizeof(JNINativeMethod)); | |
1561 } | |
1562 guarantee(status == 0, "register unsafe natives"); | |
1563 } | |
1564 JVM_END |