src/share/vm/prims/unsafe.cpp

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

mercurial