< prev index next >

src/hotspot/share/prims/unsafe.cpp

Print this page

  35 #include "oops/fieldStreams.inline.hpp"
  36 #include "oops/objArrayOop.inline.hpp"
  37 #include "oops/oop.inline.hpp"
  38 #include "oops/typeArrayOop.inline.hpp"
  39 #include "prims/unsafe.hpp"
  40 #include "runtime/globals.hpp"
  41 #include "runtime/handles.inline.hpp"
  42 #include "runtime/interfaceSupport.inline.hpp"
  43 #include "runtime/jniHandles.inline.hpp"
  44 #include "runtime/orderAccess.hpp"
  45 #include "runtime/reflection.hpp"
  46 #include "runtime/sharedRuntime.hpp"
  47 #include "runtime/thread.hpp"
  48 #include "runtime/threadSMR.hpp"
  49 #include "runtime/vm_version.hpp"
  50 #include "services/threadService.hpp"
  51 #include "utilities/align.hpp"
  52 #include "utilities/copy.hpp"
  53 #include "utilities/dtrace.hpp"
  54 #include "utilities/macros.hpp"



  55 
  56 /**
  57  * Implementation of the jdk.internal.misc.Unsafe class
  58  */
  59 
  60 
  61 #define MAX_OBJECT_SIZE \
  62   ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
  63     + ((julong)max_jint * sizeof(double)) )
  64 
  65 
  66 #define UNSAFE_ENTRY(result_type, header) \
  67   JVM_ENTRY(static result_type, header)
  68 
  69 #define UNSAFE_LEAF(result_type, header) \
  70   JVM_LEAF(static result_type, header)
  71 
  72 #define UNSAFE_END JVM_END
  73 
  74 

 246     }
 247   }
 248 
 249   void put_volatile(T x) {
 250     if (_obj == NULL) {
 251       GuardUnsafeAccess guard(_thread);
 252       RawAccess<MO_SEQ_CST>::store(addr(), normalize_for_write(x));
 253     } else {
 254       HeapAccess<MO_SEQ_CST>::store_at(_obj, _offset, normalize_for_write(x));
 255     }
 256   }
 257 };
 258 
 259 // These functions allow a null base pointer with an arbitrary address.
 260 // But if the base pointer is non-null, the offset should make some sense.
 261 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
 262 UNSAFE_ENTRY(jobject, Unsafe_GetReference(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {
 263   oop p = JNIHandles::resolve(obj);
 264   assert_field_offset_sane(p, offset);
 265   oop v = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(p, offset);








 266   return JNIHandles::make_local(env, v);
 267 } UNSAFE_END
 268 
 269 UNSAFE_ENTRY(void, Unsafe_PutReference(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
 270   oop x = JNIHandles::resolve(x_h);
 271   oop p = JNIHandles::resolve(obj);
 272   assert_field_offset_sane(p, offset);








 273   HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(p, offset, x);
 274 } UNSAFE_END
 275 
 276 UNSAFE_ENTRY(jobject, Unsafe_GetReferenceVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {
 277   oop p = JNIHandles::resolve(obj);
 278   assert_field_offset_sane(p, offset);
 279   oop v = HeapAccess<MO_SEQ_CST | ON_UNKNOWN_OOP_REF>::oop_load_at(p, offset);




 280   return JNIHandles::make_local(env, v);
 281 } UNSAFE_END
 282 
 283 UNSAFE_ENTRY(void, Unsafe_PutReferenceVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
 284   oop x = JNIHandles::resolve(x_h);
 285   oop p = JNIHandles::resolve(obj);
 286   assert_field_offset_sane(p, offset);




 287   HeapAccess<MO_SEQ_CST | ON_UNKNOWN_OOP_REF>::oop_store_at(p, offset, x);
 288 } UNSAFE_END
 289 
 290 UNSAFE_ENTRY(jobject, Unsafe_GetUncompressedObject(JNIEnv *env, jobject unsafe, jlong addr)) {
 291   oop v = *(oop*) (address) addr;
 292   return JNIHandles::make_local(env, v);
 293 } UNSAFE_END
 294 
 295 #define DEFINE_GETSETOOP(java_type, Type) \
 296  \
 297 UNSAFE_ENTRY(java_type, Unsafe_Get##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
 298   return MemoryAccess<java_type>(thread, obj, offset).get(); \





 299 } UNSAFE_END \
 300  \
 301 UNSAFE_ENTRY(void, Unsafe_Put##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \




 302   MemoryAccess<java_type>(thread, obj, offset).put(x); \
 303 } UNSAFE_END \
 304  \
 305 // END DEFINE_GETSETOOP.
 306 
 307 DEFINE_GETSETOOP(jboolean, Boolean)
 308 DEFINE_GETSETOOP(jbyte, Byte)
 309 DEFINE_GETSETOOP(jshort, Short);
 310 DEFINE_GETSETOOP(jchar, Char);
 311 DEFINE_GETSETOOP(jint, Int);
 312 DEFINE_GETSETOOP(jlong, Long);
 313 DEFINE_GETSETOOP(jfloat, Float);
 314 DEFINE_GETSETOOP(jdouble, Double);
 315 
 316 #undef DEFINE_GETSETOOP
 317 
 318 #define DEFINE_GETSETOOP_VOLATILE(java_type, Type) \
 319  \
 320 UNSAFE_ENTRY(java_type, Unsafe_Get##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
 321   return MemoryAccess<java_type>(thread, obj, offset).get_volatile(); \





 322 } UNSAFE_END \
 323  \
 324 UNSAFE_ENTRY(void, Unsafe_Put##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \




 325   MemoryAccess<java_type>(thread, obj, offset).put_volatile(x); \
 326 } UNSAFE_END \
 327  \
 328 // END DEFINE_GETSETOOP_VOLATILE.
 329 
 330 DEFINE_GETSETOOP_VOLATILE(jboolean, Boolean)
 331 DEFINE_GETSETOOP_VOLATILE(jbyte, Byte)
 332 DEFINE_GETSETOOP_VOLATILE(jshort, Short);
 333 DEFINE_GETSETOOP_VOLATILE(jchar, Char);
 334 DEFINE_GETSETOOP_VOLATILE(jint, Int);
 335 DEFINE_GETSETOOP_VOLATILE(jlong, Long);
 336 DEFINE_GETSETOOP_VOLATILE(jfloat, Float);
 337 DEFINE_GETSETOOP_VOLATILE(jdouble, Double);
 338 
 339 #undef DEFINE_GETSETOOP_VOLATILE
 340 
 341 UNSAFE_LEAF(void, Unsafe_LoadFence(JNIEnv *env, jobject unsafe)) {
 342   OrderAccess::acquire();
 343 } UNSAFE_END
 344 

 882   // this point.   The mirror and any instances of this class have to keep
 883   // it alive afterwards.
 884   if (anon_klass != NULL) {
 885     anon_klass->class_loader_data()->dec_keep_alive();
 886   }
 887 
 888   // let caller initialize it as needed...
 889 
 890   return (jclass) res_jh;
 891 } UNSAFE_END
 892 
 893 
 894 
 895 UNSAFE_ENTRY(void, Unsafe_ThrowException(JNIEnv *env, jobject unsafe, jthrowable thr)) {
 896   ThreadToNativeFromVM ttnfv(thread);
 897   env->Throw(thr);
 898 } UNSAFE_END
 899 
 900 // JSR166 ------------------------------------------------------------------
 901 
























 902 UNSAFE_ENTRY(jobject, Unsafe_CompareAndExchangeReference(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h)) {
 903   oop x = JNIHandles::resolve(x_h);
 904   oop e = JNIHandles::resolve(e_h);
 905   oop p = JNIHandles::resolve(obj);
 906   assert_field_offset_sane(p, offset);

 907   oop res = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x);
 908   return JNIHandles::make_local(env, res);
 909 } UNSAFE_END
 910 
 911 UNSAFE_ENTRY(jint, Unsafe_CompareAndExchangeInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) {
 912   oop p = JNIHandles::resolve(obj);
 913   if (p == NULL) {
 914     volatile jint* addr = (volatile jint*)index_oop_from_field_offset_long(p, offset);

 915     return RawAccess<>::atomic_cmpxchg(addr, e, x);
 916   } else {
 917     assert_field_offset_sane(p, offset);

 918     return HeapAccess<>::atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x);
 919   }
 920 } UNSAFE_END
 921 
 922 UNSAFE_ENTRY(jlong, Unsafe_CompareAndExchangeLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) {
 923   oop p = JNIHandles::resolve(obj);
 924   if (p == NULL) {
 925     volatile jlong* addr = (volatile jlong*)index_oop_from_field_offset_long(p, offset);

 926     return RawAccess<>::atomic_cmpxchg(addr, e, x);
 927   } else {
 928     assert_field_offset_sane(p, offset);

 929     return HeapAccess<>::atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x);
 930   }
 931 } UNSAFE_END
 932 
 933 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetReference(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h)) {
 934   oop x = JNIHandles::resolve(x_h);
 935   oop e = JNIHandles::resolve(e_h);
 936   oop p = JNIHandles::resolve(obj);
 937   assert_field_offset_sane(p, offset);

 938   oop ret = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x);
 939   return ret == e;
 940 } UNSAFE_END
 941 
 942 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) {
 943   oop p = JNIHandles::resolve(obj);
 944   if (p == NULL) {
 945     volatile jint* addr = (volatile jint*)index_oop_from_field_offset_long(p, offset);

 946     return RawAccess<>::atomic_cmpxchg(addr, e, x) == e;
 947   } else {
 948     assert_field_offset_sane(p, offset);

 949     return HeapAccess<>::atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x) == e;
 950   }
 951 } UNSAFE_END
 952 
 953 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) {
 954   oop p = JNIHandles::resolve(obj);
 955   if (p == NULL) {
 956     volatile jlong* addr = (volatile jlong*)index_oop_from_field_offset_long(p, offset);

 957     return RawAccess<>::atomic_cmpxchg(addr, e, x) == e;
 958   } else {
 959     assert_field_offset_sane(p, offset);

 960     return HeapAccess<>::atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x) == e;
 961   }
 962 } UNSAFE_END
 963 
 964 static void post_thread_park_event(EventThreadPark* event, const oop obj, jlong timeout_nanos, jlong until_epoch_millis) {
 965   assert(event != NULL, "invariant");
 966   assert(event->should_commit(), "invariant");
 967   event->set_parkedClass((obj != NULL) ? obj->klass() : NULL);
 968   event->set_timeout(timeout_nanos);
 969   event->set_until(until_epoch_millis);
 970   event->set_address((obj != NULL) ? (u8)cast_from_oop<uintptr_t>(obj) : 0);
 971   event->commit();
 972 }
 973 
 974 UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time)) {
 975   HOTSPOT_THREAD_PARK_BEGIN((uintptr_t) thread->parker(), (int) isAbsolute, time);
 976   EventThreadPark event;
 977 
 978   JavaThreadParkedState jtps(thread, time != 0);
 979   thread->parker()->park(isAbsolute != 0, time);

  35 #include "oops/fieldStreams.inline.hpp"
  36 #include "oops/objArrayOop.inline.hpp"
  37 #include "oops/oop.inline.hpp"
  38 #include "oops/typeArrayOop.inline.hpp"
  39 #include "prims/unsafe.hpp"
  40 #include "runtime/globals.hpp"
  41 #include "runtime/handles.inline.hpp"
  42 #include "runtime/interfaceSupport.inline.hpp"
  43 #include "runtime/jniHandles.inline.hpp"
  44 #include "runtime/orderAccess.hpp"
  45 #include "runtime/reflection.hpp"
  46 #include "runtime/sharedRuntime.hpp"
  47 #include "runtime/thread.hpp"
  48 #include "runtime/threadSMR.hpp"
  49 #include "runtime/vm_version.hpp"
  50 #include "services/threadService.hpp"
  51 #include "utilities/align.hpp"
  52 #include "utilities/copy.hpp"
  53 #include "utilities/dtrace.hpp"
  54 #include "utilities/macros.hpp"
  55 #if INCLUDE_TSAN
  56 #include "tsan/tsanExternalDecls.hpp"
  57 #endif
  58 
  59 /**
  60  * Implementation of the jdk.internal.misc.Unsafe class
  61  */
  62 
  63 
  64 #define MAX_OBJECT_SIZE \
  65   ( arrayOopDesc::header_size(T_DOUBLE) * HeapWordSize \
  66     + ((julong)max_jint * sizeof(double)) )
  67 
  68 
  69 #define UNSAFE_ENTRY(result_type, header) \
  70   JVM_ENTRY(static result_type, header)
  71 
  72 #define UNSAFE_LEAF(result_type, header) \
  73   JVM_LEAF(static result_type, header)
  74 
  75 #define UNSAFE_END JVM_END
  76 
  77 

 249     }
 250   }
 251 
 252   void put_volatile(T x) {
 253     if (_obj == NULL) {
 254       GuardUnsafeAccess guard(_thread);
 255       RawAccess<MO_SEQ_CST>::store(addr(), normalize_for_write(x));
 256     } else {
 257       HeapAccess<MO_SEQ_CST>::store_at(_obj, _offset, normalize_for_write(x));
 258     }
 259   }
 260 };
 261 
 262 // These functions allow a null base pointer with an arbitrary address.
 263 // But if the base pointer is non-null, the offset should make some sense.
 264 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
 265 UNSAFE_ENTRY(jobject, Unsafe_GetReference(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {
 266   oop p = JNIHandles::resolve(obj);
 267   assert_field_offset_sane(p, offset);
 268   oop v = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(p, offset);
 269   TSAN_RUNTIME_ONLY(
 270     void* addr = index_oop_from_field_offset_long(p, offset);
 271     if (UseCompressedOops) {
 272       __tsan_read4_pc(addr, SharedRuntime::tsan_code_location(0, 0));
 273     } else {
 274       __tsan_read8_pc(addr, SharedRuntime::tsan_code_location(0, 0));
 275     }
 276   );
 277   return JNIHandles::make_local(env, v);
 278 } UNSAFE_END
 279 
 280 UNSAFE_ENTRY(void, Unsafe_PutReference(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
 281   oop x = JNIHandles::resolve(x_h);
 282   oop p = JNIHandles::resolve(obj);
 283   assert_field_offset_sane(p, offset);
 284   TSAN_RUNTIME_ONLY(
 285     void* addr = index_oop_from_field_offset_long(p, offset);
 286     if (UseCompressedOops) {
 287       __tsan_write4_pc(addr, SharedRuntime::tsan_code_location(0, 0));
 288     } else {
 289       __tsan_write8_pc(addr, SharedRuntime::tsan_code_location(0, 0));
 290     }
 291   );
 292   HeapAccess<ON_UNKNOWN_OOP_REF>::oop_store_at(p, offset, x);
 293 } UNSAFE_END
 294 
 295 UNSAFE_ENTRY(jobject, Unsafe_GetReferenceVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {
 296   oop p = JNIHandles::resolve(obj);
 297   assert_field_offset_sane(p, offset);
 298   oop v = HeapAccess<MO_SEQ_CST | ON_UNKNOWN_OOP_REF>::oop_load_at(p, offset);
 299   TSAN_RUNTIME_ONLY(
 300     void* addr = index_oop_from_field_offset_long(p, offset);
 301     __tsan_java_acquire(addr);
 302   );
 303   return JNIHandles::make_local(env, v);
 304 } UNSAFE_END
 305 
 306 UNSAFE_ENTRY(void, Unsafe_PutReferenceVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
 307   oop x = JNIHandles::resolve(x_h);
 308   oop p = JNIHandles::resolve(obj);
 309   assert_field_offset_sane(p, offset);
 310   TSAN_RUNTIME_ONLY(
 311     void* addr = index_oop_from_field_offset_long(p, offset);
 312     __tsan_java_release(addr);
 313   );
 314   HeapAccess<MO_SEQ_CST | ON_UNKNOWN_OOP_REF>::oop_store_at(p, offset, x);
 315 } UNSAFE_END
 316 
 317 UNSAFE_ENTRY(jobject, Unsafe_GetUncompressedObject(JNIEnv *env, jobject unsafe, jlong addr)) {
 318   oop v = *(oop*) (address) addr;
 319   return JNIHandles::make_local(env, v);
 320 } UNSAFE_END
 321 
 322 #define DEFINE_GETSETOOP(java_type, Type, size) \
 323  \
 324 UNSAFE_ENTRY(java_type, Unsafe_Get##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
 325   java_type ret = MemoryAccess<java_type>(thread, obj, offset).get(); \
 326   TSAN_RUNTIME_ONLY( \
 327     void* addr = index_oop_from_field_offset_long(JNIHandles::resolve(obj), offset); \
 328     __tsan_read##size##_pc(addr, SharedRuntime::tsan_code_location(0, 0)); \
 329   ); \
 330   return ret; \
 331 } UNSAFE_END \
 332  \
 333 UNSAFE_ENTRY(void, Unsafe_Put##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
 334   TSAN_RUNTIME_ONLY( \
 335     void* addr = index_oop_from_field_offset_long(JNIHandles::resolve(obj), offset); \
 336     __tsan_write##size##_pc(addr, SharedRuntime::tsan_code_location(0, 0)); \
 337   ); \
 338   MemoryAccess<java_type>(thread, obj, offset).put(x); \
 339 } UNSAFE_END \
 340  \
 341 // END DEFINE_GETSETOOP.
 342 
 343 DEFINE_GETSETOOP(jboolean, Boolean, 1)
 344 DEFINE_GETSETOOP(jbyte, Byte, 1)
 345 DEFINE_GETSETOOP(jshort, Short, 2);
 346 DEFINE_GETSETOOP(jchar, Char, 2);
 347 DEFINE_GETSETOOP(jint, Int, 4);
 348 DEFINE_GETSETOOP(jlong, Long, 8);
 349 DEFINE_GETSETOOP(jfloat, Float, 4);
 350 DEFINE_GETSETOOP(jdouble, Double, 8);
 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   java_type ret = MemoryAccess<java_type>(thread, obj, offset).get_volatile(); \
 358   TSAN_RUNTIME_ONLY( \
 359     void* addr = index_oop_from_field_offset_long(JNIHandles::resolve(obj), offset); \
 360     __tsan_java_acquire(addr); \
 361   ); \
 362   return ret; \
 363 } UNSAFE_END \
 364  \
 365 UNSAFE_ENTRY(void, Unsafe_Put##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
 366   TSAN_RUNTIME_ONLY( \
 367     void* addr = index_oop_from_field_offset_long(JNIHandles::resolve(obj), offset); \
 368     __tsan_java_release(addr); \
 369   ); \
 370   MemoryAccess<java_type>(thread, obj, offset).put_volatile(x); \
 371 } UNSAFE_END \
 372  \
 373 // END DEFINE_GETSETOOP_VOLATILE.
 374 
 375 DEFINE_GETSETOOP_VOLATILE(jboolean, Boolean)
 376 DEFINE_GETSETOOP_VOLATILE(jbyte, Byte)
 377 DEFINE_GETSETOOP_VOLATILE(jshort, Short);
 378 DEFINE_GETSETOOP_VOLATILE(jchar, Char);
 379 DEFINE_GETSETOOP_VOLATILE(jint, Int);
 380 DEFINE_GETSETOOP_VOLATILE(jlong, Long);
 381 DEFINE_GETSETOOP_VOLATILE(jfloat, Float);
 382 DEFINE_GETSETOOP_VOLATILE(jdouble, Double);
 383 
 384 #undef DEFINE_GETSETOOP_VOLATILE
 385 
 386 UNSAFE_LEAF(void, Unsafe_LoadFence(JNIEnv *env, jobject unsafe)) {
 387   OrderAccess::acquire();
 388 } UNSAFE_END
 389 

 927   // this point.   The mirror and any instances of this class have to keep
 928   // it alive afterwards.
 929   if (anon_klass != NULL) {
 930     anon_klass->class_loader_data()->dec_keep_alive();
 931   }
 932 
 933   // let caller initialize it as needed...
 934 
 935   return (jclass) res_jh;
 936 } UNSAFE_END
 937 
 938 
 939 
 940 UNSAFE_ENTRY(void, Unsafe_ThrowException(JNIEnv *env, jobject unsafe, jthrowable thr)) {
 941   ThreadToNativeFromVM ttnfv(thread);
 942   env->Throw(thr);
 943 } UNSAFE_END
 944 
 945 // JSR166 ------------------------------------------------------------------
 946 
 947 // Calls __tsan_java_release() on construct and __tsan_java_acquire() on destruct.
 948 class ScopedReleaseAcquire: public StackObj {
 949 private:
 950   void* _addr;
 951 public:
 952   ScopedReleaseAcquire(volatile void* addr) {
 953     TSAN_RUNTIME_ONLY(
 954       _addr = const_cast<void*>(addr);
 955       __tsan_java_release(_addr);
 956     );
 957   }
 958 
 959   ScopedReleaseAcquire(oop obj, jlong offset) {
 960     TSAN_RUNTIME_ONLY(
 961       _addr = index_oop_from_field_offset_long(obj, offset);
 962       __tsan_java_release(_addr);
 963     );
 964   }
 965 
 966   ~ScopedReleaseAcquire() {
 967     TSAN_RUNTIME_ONLY(__tsan_java_acquire(_addr));
 968   }
 969 };
 970 
 971 UNSAFE_ENTRY(jobject, Unsafe_CompareAndExchangeReference(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h)) {
 972   oop x = JNIHandles::resolve(x_h);
 973   oop e = JNIHandles::resolve(e_h);
 974   oop p = JNIHandles::resolve(obj);
 975   assert_field_offset_sane(p, offset);
 976   ScopedReleaseAcquire releaseAcquire(p, offset);
 977   oop res = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x);
 978   return JNIHandles::make_local(env, res);
 979 } UNSAFE_END
 980 
 981 UNSAFE_ENTRY(jint, Unsafe_CompareAndExchangeInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) {
 982   oop p = JNIHandles::resolve(obj);
 983   if (p == NULL) {
 984     volatile jint* addr = (volatile jint*)index_oop_from_field_offset_long(p, offset);
 985     ScopedReleaseAcquire releaseAcquire(addr);
 986     return RawAccess<>::atomic_cmpxchg(addr, e, x);
 987   } else {
 988     assert_field_offset_sane(p, offset);
 989     ScopedReleaseAcquire releaseAcquire(p, offset);
 990     return HeapAccess<>::atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x);
 991   }
 992 } UNSAFE_END
 993 
 994 UNSAFE_ENTRY(jlong, Unsafe_CompareAndExchangeLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) {
 995   oop p = JNIHandles::resolve(obj);
 996   if (p == NULL) {
 997     volatile jlong* addr = (volatile jlong*)index_oop_from_field_offset_long(p, offset);
 998     ScopedReleaseAcquire releaseAcquire(addr);
 999     return RawAccess<>::atomic_cmpxchg(addr, e, x);
1000   } else {
1001     assert_field_offset_sane(p, offset);
1002     ScopedReleaseAcquire releaseAcquire(p, offset);
1003     return HeapAccess<>::atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x);
1004   }
1005 } UNSAFE_END
1006 
1007 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetReference(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h)) {
1008   oop x = JNIHandles::resolve(x_h);
1009   oop e = JNIHandles::resolve(e_h);
1010   oop p = JNIHandles::resolve(obj);
1011   assert_field_offset_sane(p, offset);
1012   ScopedReleaseAcquire releaseAcquire(p, offset);
1013   oop ret = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x);
1014   return ret == e;
1015 } UNSAFE_END
1016 
1017 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) {
1018   oop p = JNIHandles::resolve(obj);
1019   if (p == NULL) {
1020     volatile jint* addr = (volatile jint*)index_oop_from_field_offset_long(p, offset);
1021     ScopedReleaseAcquire releaseAcquire(addr);
1022     return RawAccess<>::atomic_cmpxchg(addr, e, x) == e;
1023   } else {
1024     assert_field_offset_sane(p, offset);
1025     ScopedReleaseAcquire releaseAcquire(p, offset);
1026     return HeapAccess<>::atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x) == e;
1027   }
1028 } UNSAFE_END
1029 
1030 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) {
1031   oop p = JNIHandles::resolve(obj);
1032   if (p == NULL) {
1033     volatile jlong* addr = (volatile jlong*)index_oop_from_field_offset_long(p, offset);
1034     ScopedReleaseAcquire releaseAcquire(addr);
1035     return RawAccess<>::atomic_cmpxchg(addr, e, x) == e;
1036   } else {
1037     assert_field_offset_sane(p, offset);
1038     ScopedReleaseAcquire releaseAcquire(p, offset);
1039     return HeapAccess<>::atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x) == e;
1040   }
1041 } UNSAFE_END
1042 
1043 static void post_thread_park_event(EventThreadPark* event, const oop obj, jlong timeout_nanos, jlong until_epoch_millis) {
1044   assert(event != NULL, "invariant");
1045   assert(event->should_commit(), "invariant");
1046   event->set_parkedClass((obj != NULL) ? obj->klass() : NULL);
1047   event->set_timeout(timeout_nanos);
1048   event->set_until(until_epoch_millis);
1049   event->set_address((obj != NULL) ? (u8)cast_from_oop<uintptr_t>(obj) : 0);
1050   event->commit();
1051 }
1052 
1053 UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, jlong time)) {
1054   HOTSPOT_THREAD_PARK_BEGIN((uintptr_t) thread->parker(), (int) isAbsolute, time);
1055   EventThreadPark event;
1056 
1057   JavaThreadParkedState jtps(thread, time != 0);
1058   thread->parker()->park(isAbsolute != 0, time);
< prev index next >