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