hotspot/src/share/vm/prims/unsafe.cpp
changeset 38211 fe30fdab0f62
parent 38060 954c9575f653
child 39260 10fcac2a233a
equal deleted inserted replaced
38209:b2a58604e046 38211:fe30fdab0f62
   129 jlong Unsafe_field_offset_from_byte_offset(jlong byte_offset) {
   129 jlong Unsafe_field_offset_from_byte_offset(jlong byte_offset) {
   130   return byte_offset;
   130   return byte_offset;
   131 }
   131 }
   132 
   132 
   133 
   133 
   134 ///// Data in the Java heap.
   134 ///// Data read/writes on the Java heap and in native (off-heap) memory
   135 
   135 
   136 #define truncate_jboolean(x) ((x) & 1)
   136 /**
   137 #define truncate_jbyte(x) (x)
   137  * Helper class for accessing memory.
   138 #define truncate_jshort(x) (x)
   138  *
   139 #define truncate_jchar(x) (x)
   139  * Normalizes values and wraps accesses in
   140 #define truncate_jint(x) (x)
   140  * JavaThread::doing_unsafe_access() if needed.
   141 #define truncate_jlong(x) (x)
   141  */
   142 #define truncate_jfloat(x) (x)
   142 class MemoryAccess : StackObj {
   143 #define truncate_jdouble(x) (x)
   143   JavaThread* _thread;
   144 
   144   jobject _obj;
   145 #define GET_FIELD(obj, offset, type_name, v) \
   145   jlong _offset;
   146   oop p = JNIHandles::resolve(obj); \
   146 
   147   type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset)
   147   // Resolves and returns the address of the memory access
   148 
   148   void* addr() {
   149 #define SET_FIELD(obj, offset, type_name, x) \
   149     return index_oop_from_field_offset_long(JNIHandles::resolve(_obj), _offset);
   150   oop p = JNIHandles::resolve(obj); \
   150   }
   151   *(type_name*)index_oop_from_field_offset_long(p, offset) = truncate_##type_name(x)
   151 
   152 
   152   template <typename T>
   153 #define GET_FIELD_VOLATILE(obj, offset, type_name, v) \
   153   T normalize(T x) {
   154   oop p = JNIHandles::resolve(obj); \
   154     return x;
   155   if (support_IRIW_for_not_multiple_copy_atomic_cpu) { \
   155   }
   156     OrderAccess::fence(); \
   156 
   157   } \
   157   jboolean normalize(jboolean x) {
   158   volatile type_name v = OrderAccess::load_acquire((volatile type_name*)index_oop_from_field_offset_long(p, offset));
   158     return x & 1;
   159 
   159   }
   160 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
   160 
   161   oop p = JNIHandles::resolve(obj); \
   161   /**
   162   OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), truncate_##type_name(x));
   162    * Helper class to wrap memory accesses in JavaThread::doing_unsafe_access()
   163 
   163    */
   164 
   164   class GuardUnsafeAccess {
   165 // Get/SetObject must be special-cased, since it works with handles.
   165     JavaThread* _thread;
       
   166     bool _active;
       
   167 
       
   168   public:
       
   169     GuardUnsafeAccess(JavaThread* thread, jobject _obj) : _thread(thread) {
       
   170       if (JNIHandles::resolve(_obj) == NULL) {
       
   171         // native/off-heap access which may raise SIGBUS if accessing
       
   172         // memory mapped file data in a region of the file which has
       
   173         // been truncated and is now invalid
       
   174         _thread->set_doing_unsafe_access(true);
       
   175         _active = true;
       
   176       } else {
       
   177         _active = false;
       
   178       }
       
   179     }
       
   180 
       
   181     ~GuardUnsafeAccess() {
       
   182       if (_active) {
       
   183         _thread->set_doing_unsafe_access(false);
       
   184       }
       
   185     }
       
   186   };
       
   187 
       
   188 public:
       
   189   MemoryAccess(JavaThread* thread, jobject obj, jlong offset)
       
   190     : _thread(thread), _obj(obj), _offset(offset) {
       
   191   }
       
   192 
       
   193   template <typename T>
       
   194   T get() {
       
   195     GuardUnsafeAccess guard(_thread, _obj);
       
   196 
       
   197     T* p = (T*)addr();
       
   198 
       
   199     T x = *p;
       
   200 
       
   201     return x;
       
   202   }
       
   203 
       
   204   template <typename T>
       
   205   void put(T x) {
       
   206     GuardUnsafeAccess guard(_thread, _obj);
       
   207 
       
   208     T* p = (T*)addr();
       
   209 
       
   210     *p = normalize(x);
       
   211   }
       
   212 
       
   213 
       
   214   template <typename T>
       
   215   T get_volatile() {
       
   216     GuardUnsafeAccess guard(_thread, _obj);
       
   217 
       
   218     T* p = (T*)addr();
       
   219 
       
   220     if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
       
   221       OrderAccess::fence();
       
   222     }
       
   223 
       
   224     T x = OrderAccess::load_acquire((volatile T*)p);
       
   225 
       
   226     return x;
       
   227   }
       
   228 
       
   229   template <typename T>
       
   230   void put_volatile(T x) {
       
   231     GuardUnsafeAccess guard(_thread, _obj);
       
   232 
       
   233     T* p = (T*)addr();
       
   234 
       
   235     OrderAccess::release_store_fence((volatile T*)p, normalize(x));
       
   236   }
       
   237 
       
   238 
       
   239 #ifndef SUPPORTS_NATIVE_CX8
       
   240   jlong get_jlong_locked() {
       
   241     GuardUnsafeAccess guard(_thread, _obj);
       
   242 
       
   243     MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
       
   244 
       
   245     jlong* p = (jlong*)addr();
       
   246 
       
   247     jlong x = Atomic::load(p);
       
   248 
       
   249     return x;
       
   250   }
       
   251 
       
   252   void put_jlong_locked(jlong x) {
       
   253     GuardUnsafeAccess guard(_thread, _obj);
       
   254 
       
   255     MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
       
   256 
       
   257     jlong* p = (jlong*)addr();
       
   258 
       
   259     Atomic::store(normalize(x),  p);
       
   260   }
       
   261 #endif
       
   262 };
       
   263 
       
   264 // Get/PutObject must be special-cased, since it works with handles.
   166 
   265 
   167 // These functions allow a null base pointer with an arbitrary address.
   266 // These functions allow a null base pointer with an arbitrary address.
   168 // But if the base pointer is non-null, the offset should make some sense.
   267 // But if the base pointer is non-null, the offset should make some sense.
   169 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
   268 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
   170 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {
   269 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {
   206 #endif // INCLUDE_ALL_GCS
   305 #endif // INCLUDE_ALL_GCS
   207 
   306 
   208   return ret;
   307   return ret;
   209 } UNSAFE_END
   308 } UNSAFE_END
   210 
   309 
   211 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
   310 UNSAFE_ENTRY(void, Unsafe_PutObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
   212   oop x = JNIHandles::resolve(x_h);
   311   oop x = JNIHandles::resolve(x_h);
   213   oop p = JNIHandles::resolve(obj);
   312   oop p = JNIHandles::resolve(obj);
   214 
   313 
   215   if (UseCompressedOops) {
   314   if (UseCompressedOops) {
   216     oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
   315     oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
   234 
   333 
   235   OrderAccess::acquire();
   334   OrderAccess::acquire();
   236   return JNIHandles::make_local(env, v);
   335   return JNIHandles::make_local(env, v);
   237 } UNSAFE_END
   336 } UNSAFE_END
   238 
   337 
   239 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
   338 UNSAFE_ENTRY(void, Unsafe_PutObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
   240   oop x = JNIHandles::resolve(x_h);
   339   oop x = JNIHandles::resolve(x_h);
   241   oop p = JNIHandles::resolve(obj);
   340   oop p = JNIHandles::resolve(obj);
   242   void* addr = index_oop_from_field_offset_long(p, offset);
   341   void* addr = index_oop_from_field_offset_long(p, offset);
   243   OrderAccess::release();
   342   OrderAccess::release();
   244 
   343 
   299 // the address of the field _after_ we have acquired the lock, else the object may have
   398 // the address of the field _after_ we have acquired the lock, else the object may have
   300 // been moved by the GC
   399 // been moved by the GC
   301 
   400 
   302 UNSAFE_ENTRY(jlong, Unsafe_GetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {
   401 UNSAFE_ENTRY(jlong, Unsafe_GetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) {
   303   if (VM_Version::supports_cx8()) {
   402   if (VM_Version::supports_cx8()) {
   304     GET_FIELD_VOLATILE(obj, offset, jlong, v);
   403     return MemoryAccess(thread, obj, offset).get_volatile<jlong>();
   305     return v;
       
   306   } else {
   404   } else {
   307     Handle p (THREAD, JNIHandles::resolve(obj));
   405     return MemoryAccess(thread, obj, offset).get_jlong_locked();
   308     jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
   406   }
   309     MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
   407 } UNSAFE_END
   310     jlong value = Atomic::load(addr);
   408 
   311     return value;
   409 UNSAFE_ENTRY(void, Unsafe_PutLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x)) {
   312   }
       
   313 } UNSAFE_END
       
   314 
       
   315 UNSAFE_ENTRY(void, Unsafe_SetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x)) {
       
   316   if (VM_Version::supports_cx8()) {
   410   if (VM_Version::supports_cx8()) {
   317     SET_FIELD_VOLATILE(obj, offset, jlong, x);
   411     MemoryAccess(thread, obj, offset).put_volatile<jlong>(x);
   318   } else {
   412   } else {
   319     Handle p (THREAD, JNIHandles::resolve(obj));
   413     MemoryAccess(thread, obj, offset).put_jlong_locked(x);
   320     jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
       
   321     MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
       
   322     Atomic::store(x, addr);
       
   323   }
   414   }
   324 } UNSAFE_END
   415 } UNSAFE_END
   325 
   416 
   326 #endif // not SUPPORTS_NATIVE_CX8
   417 #endif // not SUPPORTS_NATIVE_CX8
   327 
   418 
   335 
   426 
   336 UNSAFE_LEAF(jint, Unsafe_unalignedAccess0(JNIEnv *env, jobject unsafe)) {
   427 UNSAFE_LEAF(jint, Unsafe_unalignedAccess0(JNIEnv *env, jobject unsafe)) {
   337   return UseUnalignedAccesses;
   428   return UseUnalignedAccesses;
   338 } UNSAFE_END
   429 } UNSAFE_END
   339 
   430 
   340 #define DEFINE_GETSETOOP(java_type, Type)        \
   431 #define DEFINE_GETSETOOP(java_type, Type) \
   341  \
   432  \
   342 UNSAFE_ENTRY(java_type, Unsafe_Get##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
   433 UNSAFE_ENTRY(java_type, Unsafe_Get##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
   343   GET_FIELD(obj, offset, java_type, v); \
   434   return MemoryAccess(thread, obj, offset).get<java_type>(); \
   344   return v; \
       
   345 } UNSAFE_END \
   435 } UNSAFE_END \
   346  \
   436  \
   347 UNSAFE_ENTRY(void, Unsafe_Set##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
   437 UNSAFE_ENTRY(void, Unsafe_Put##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
   348   SET_FIELD(obj, offset, java_type, x); \
   438   MemoryAccess(thread, obj, offset).put<java_type>(x); \
   349 } UNSAFE_END \
   439 } UNSAFE_END \
   350  \
   440  \
   351 // END DEFINE_GETSETOOP.
   441 // END DEFINE_GETSETOOP.
   352 
   442 
   353 DEFINE_GETSETOOP(jboolean, Boolean)
   443 DEFINE_GETSETOOP(jboolean, Boolean)
   362 #undef DEFINE_GETSETOOP
   452 #undef DEFINE_GETSETOOP
   363 
   453 
   364 #define DEFINE_GETSETOOP_VOLATILE(java_type, Type) \
   454 #define DEFINE_GETSETOOP_VOLATILE(java_type, Type) \
   365  \
   455  \
   366 UNSAFE_ENTRY(java_type, Unsafe_Get##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
   456 UNSAFE_ENTRY(java_type, Unsafe_Get##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
   367   GET_FIELD_VOLATILE(obj, offset, java_type, v); \
   457   return MemoryAccess(thread, obj, offset).get_volatile<java_type>(); \
   368   return v; \
       
   369 } UNSAFE_END \
   458 } UNSAFE_END \
   370  \
   459  \
   371 UNSAFE_ENTRY(void, Unsafe_Set##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
   460 UNSAFE_ENTRY(void, Unsafe_Put##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
   372   SET_FIELD_VOLATILE(obj, offset, java_type, x); \
   461   MemoryAccess(thread, obj, offset).put_volatile<java_type>(x); \
   373 } UNSAFE_END \
   462 } UNSAFE_END \
   374  \
   463  \
   375 // END DEFINE_GETSETOOP_VOLATILE.
   464 // END DEFINE_GETSETOOP_VOLATILE.
   376 
   465 
   377 DEFINE_GETSETOOP_VOLATILE(jboolean, Boolean)
   466 DEFINE_GETSETOOP_VOLATILE(jboolean, Boolean)
   397 } UNSAFE_END
   486 } UNSAFE_END
   398 
   487 
   399 UNSAFE_LEAF(void, Unsafe_FullFence(JNIEnv *env, jobject unsafe)) {
   488 UNSAFE_LEAF(void, Unsafe_FullFence(JNIEnv *env, jobject unsafe)) {
   400   OrderAccess::fence();
   489   OrderAccess::fence();
   401 } UNSAFE_END
   490 } UNSAFE_END
   402 
       
   403 ////// Data in the C heap.
       
   404 
       
   405 // Note:  These do not throw NullPointerException for bad pointers.
       
   406 // They just crash.  Only a oop base pointer can generate a NullPointerException.
       
   407 //
       
   408 #define DEFINE_GETSETNATIVE(java_type, Type, native_type) \
       
   409  \
       
   410 UNSAFE_ENTRY(java_type, Unsafe_GetNative##Type(JNIEnv *env, jobject unsafe, jlong addr)) { \
       
   411   void* p = addr_from_java(addr); \
       
   412   JavaThread* t = JavaThread::current(); \
       
   413   t->set_doing_unsafe_access(true); \
       
   414   java_type x = *(volatile native_type*)p; \
       
   415   t->set_doing_unsafe_access(false); \
       
   416   return x; \
       
   417 } UNSAFE_END \
       
   418  \
       
   419 UNSAFE_ENTRY(void, Unsafe_SetNative##Type(JNIEnv *env, jobject unsafe, jlong addr, java_type x)) { \
       
   420   JavaThread* t = JavaThread::current(); \
       
   421   t->set_doing_unsafe_access(true); \
       
   422   void* p = addr_from_java(addr); \
       
   423   *(volatile native_type*)p = x; \
       
   424   t->set_doing_unsafe_access(false); \
       
   425 } UNSAFE_END \
       
   426  \
       
   427 // END DEFINE_GETSETNATIVE.
       
   428 
       
   429 DEFINE_GETSETNATIVE(jbyte, Byte, signed char)
       
   430 DEFINE_GETSETNATIVE(jshort, Short, signed short);
       
   431 DEFINE_GETSETNATIVE(jchar, Char, unsigned short);
       
   432 DEFINE_GETSETNATIVE(jint, Int, jint);
       
   433 // no long -- handled specially
       
   434 DEFINE_GETSETNATIVE(jfloat, Float, float);
       
   435 DEFINE_GETSETNATIVE(jdouble, Double, double);
       
   436 
       
   437 #undef DEFINE_GETSETNATIVE
       
   438 
       
   439 UNSAFE_ENTRY(jlong, Unsafe_GetNativeLong(JNIEnv *env, jobject unsafe, jlong addr)) {
       
   440   JavaThread* t = JavaThread::current();
       
   441   // We do it this way to avoid problems with access to heap using 64
       
   442   // bit loads, as jlong in heap could be not 64-bit aligned, and on
       
   443   // some CPUs (SPARC) it leads to SIGBUS.
       
   444   t->set_doing_unsafe_access(true);
       
   445   void* p = addr_from_java(addr);
       
   446   jlong x;
       
   447 
       
   448   if (is_ptr_aligned(p, sizeof(jlong)) == 0) {
       
   449     // jlong is aligned, do a volatile access
       
   450     x = *(volatile jlong*)p;
       
   451   } else {
       
   452     jlong_accessor acc;
       
   453     acc.words[0] = ((volatile jint*)p)[0];
       
   454     acc.words[1] = ((volatile jint*)p)[1];
       
   455     x = acc.long_value;
       
   456   }
       
   457 
       
   458   t->set_doing_unsafe_access(false);
       
   459 
       
   460   return x;
       
   461 } UNSAFE_END
       
   462 
       
   463 UNSAFE_ENTRY(void, Unsafe_SetNativeLong(JNIEnv *env, jobject unsafe, jlong addr, jlong x)) {
       
   464   JavaThread* t = JavaThread::current();
       
   465   // see comment for Unsafe_GetNativeLong
       
   466   t->set_doing_unsafe_access(true);
       
   467   void* p = addr_from_java(addr);
       
   468 
       
   469   if (is_ptr_aligned(p, sizeof(jlong))) {
       
   470     // jlong is aligned, do a volatile access
       
   471     *(volatile jlong*)p = x;
       
   472   } else {
       
   473     jlong_accessor acc;
       
   474     acc.long_value = x;
       
   475     ((volatile jint*)p)[0] = acc.words[0];
       
   476     ((volatile jint*)p)[1] = acc.words[1];
       
   477   }
       
   478 
       
   479   t->set_doing_unsafe_access(false);
       
   480 } UNSAFE_END
       
   481 
       
   482 
       
   483 UNSAFE_LEAF(jlong, Unsafe_GetNativeAddress(JNIEnv *env, jobject unsafe, jlong addr)) {
       
   484   void* p = addr_from_java(addr);
       
   485 
       
   486   return addr_to_java(*(void**)p);
       
   487 } UNSAFE_END
       
   488 
       
   489 UNSAFE_LEAF(void, Unsafe_SetNativeAddress(JNIEnv *env, jobject unsafe, jlong addr, jlong x)) {
       
   490   void* p = addr_from_java(addr);
       
   491   *(void**)p = addr_from_java(x);
       
   492 } UNSAFE_END
       
   493 
       
   494 
   491 
   495 ////// Allocation requests
   492 ////// Allocation requests
   496 
   493 
   497 UNSAFE_ENTRY(jobject, Unsafe_AllocateInstance(JNIEnv *env, jobject unsafe, jclass cls)) {
   494 UNSAFE_ENTRY(jobject, Unsafe_AllocateInstance(JNIEnv *env, jobject unsafe, jclass cls)) {
   498   ThreadToNativeFromVM ttnfv(thread);
   495   ThreadToNativeFromVM ttnfv(thread);
   978 
   975 
   979   return (jint)(Atomic::cmpxchg(x, addr, e));
   976   return (jint)(Atomic::cmpxchg(x, addr, e));
   980 } UNSAFE_END
   977 } UNSAFE_END
   981 
   978 
   982 UNSAFE_ENTRY(jlong, Unsafe_CompareAndExchangeLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) {
   979 UNSAFE_ENTRY(jlong, Unsafe_CompareAndExchangeLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) {
   983   Handle p (THREAD, JNIHandles::resolve(obj));
   980   Handle p(THREAD, JNIHandles::resolve(obj));
   984   jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
   981   jlong* addr = (jlong*)index_oop_from_field_offset_long(p(), offset);
   985 
   982 
   986 #ifdef SUPPORTS_NATIVE_CX8
   983 #ifdef SUPPORTS_NATIVE_CX8
   987   return (jlong)(Atomic::cmpxchg(x, addr, e));
   984   return (jlong)(Atomic::cmpxchg(x, addr, e));
   988 #else
   985 #else
   989   if (VM_Version::supports_cx8()) {
   986   if (VM_Version::supports_cx8()) {
  1015   return true;
  1012   return true;
  1016 } UNSAFE_END
  1013 } UNSAFE_END
  1017 
  1014 
  1018 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) {
  1015 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) {
  1019   oop p = JNIHandles::resolve(obj);
  1016   oop p = JNIHandles::resolve(obj);
  1020   jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
  1017   jint* addr = (jint *)index_oop_from_field_offset_long(p, offset);
  1021 
  1018 
  1022   return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
  1019   return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
  1023 } UNSAFE_END
  1020 } UNSAFE_END
  1024 
  1021 
  1025 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) {
  1022 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) {
  1141 #define CC (char*)  /*cast a literal from (const char*)*/
  1138 #define CC (char*)  /*cast a literal from (const char*)*/
  1142 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
  1139 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
  1143 
  1140 
  1144 #define DECLARE_GETPUTOOP(Type, Desc) \
  1141 #define DECLARE_GETPUTOOP(Type, Desc) \
  1145     {CC "get" #Type,      CC "(" OBJ "J)" #Desc,       FN_PTR(Unsafe_Get##Type)}, \
  1142     {CC "get" #Type,      CC "(" OBJ "J)" #Desc,       FN_PTR(Unsafe_Get##Type)}, \
  1146     {CC "put" #Type,      CC "(" OBJ "J" #Desc ")V",   FN_PTR(Unsafe_Set##Type)}, \
  1143     {CC "put" #Type,      CC "(" OBJ "J" #Desc ")V",   FN_PTR(Unsafe_Put##Type)}, \
  1147     {CC "get" #Type "Volatile",      CC "(" OBJ "J)" #Desc,       FN_PTR(Unsafe_Get##Type##Volatile)}, \
  1144     {CC "get" #Type "Volatile",      CC "(" OBJ "J)" #Desc,       FN_PTR(Unsafe_Get##Type##Volatile)}, \
  1148     {CC "put" #Type "Volatile",      CC "(" OBJ "J" #Desc ")V",   FN_PTR(Unsafe_Set##Type##Volatile)}
  1145     {CC "put" #Type "Volatile",      CC "(" OBJ "J" #Desc ")V",   FN_PTR(Unsafe_Put##Type##Volatile)}
  1149 
  1146 
  1150 
       
  1151 #define DECLARE_GETPUTNATIVE(Byte, B) \
       
  1152     {CC "get" #Byte,         CC "(" ADR ")" #B,       FN_PTR(Unsafe_GetNative##Byte)}, \
       
  1153     {CC "put" #Byte,         CC "(" ADR#B ")V",       FN_PTR(Unsafe_SetNative##Byte)}
       
  1154 
  1147 
  1155 static JNINativeMethod jdk_internal_misc_Unsafe_methods[] = {
  1148 static JNINativeMethod jdk_internal_misc_Unsafe_methods[] = {
  1156     {CC "getObject",        CC "(" OBJ "J)" OBJ "",   FN_PTR(Unsafe_GetObject)},
  1149     {CC "getObject",        CC "(" OBJ "J)" OBJ "",   FN_PTR(Unsafe_GetObject)},
  1157     {CC "putObject",        CC "(" OBJ "J" OBJ ")V",  FN_PTR(Unsafe_SetObject)},
  1150     {CC "putObject",        CC "(" OBJ "J" OBJ ")V",  FN_PTR(Unsafe_PutObject)},
  1158     {CC "getObjectVolatile",CC "(" OBJ "J)" OBJ "",   FN_PTR(Unsafe_GetObjectVolatile)},
  1151     {CC "getObjectVolatile",CC "(" OBJ "J)" OBJ "",   FN_PTR(Unsafe_GetObjectVolatile)},
  1159     {CC "putObjectVolatile",CC "(" OBJ "J" OBJ ")V",  FN_PTR(Unsafe_SetObjectVolatile)},
  1152     {CC "putObjectVolatile",CC "(" OBJ "J" OBJ ")V",  FN_PTR(Unsafe_PutObjectVolatile)},
  1160 
  1153 
  1161     {CC "getUncompressedObject", CC "(" ADR ")" OBJ,  FN_PTR(Unsafe_GetUncompressedObject)},
  1154     {CC "getUncompressedObject", CC "(" ADR ")" OBJ,  FN_PTR(Unsafe_GetUncompressedObject)},
  1162     {CC "getJavaMirror",         CC "(" ADR ")" CLS,  FN_PTR(Unsafe_GetJavaMirror)},
  1155     {CC "getJavaMirror",         CC "(" ADR ")" CLS,  FN_PTR(Unsafe_GetJavaMirror)},
  1163     {CC "getKlassPointer",       CC "(" OBJ ")" ADR,  FN_PTR(Unsafe_GetKlassPointer)},
  1156     {CC "getKlassPointer",       CC "(" OBJ ")" ADR,  FN_PTR(Unsafe_GetKlassPointer)},
  1164 
  1157 
  1168     DECLARE_GETPUTOOP(Char, C),
  1161     DECLARE_GETPUTOOP(Char, C),
  1169     DECLARE_GETPUTOOP(Int, I),
  1162     DECLARE_GETPUTOOP(Int, I),
  1170     DECLARE_GETPUTOOP(Long, J),
  1163     DECLARE_GETPUTOOP(Long, J),
  1171     DECLARE_GETPUTOOP(Float, F),
  1164     DECLARE_GETPUTOOP(Float, F),
  1172     DECLARE_GETPUTOOP(Double, D),
  1165     DECLARE_GETPUTOOP(Double, D),
  1173 
       
  1174     DECLARE_GETPUTNATIVE(Byte, B),
       
  1175     DECLARE_GETPUTNATIVE(Short, S),
       
  1176     DECLARE_GETPUTNATIVE(Char, C),
       
  1177     DECLARE_GETPUTNATIVE(Int, I),
       
  1178     DECLARE_GETPUTNATIVE(Long, J),
       
  1179     DECLARE_GETPUTNATIVE(Float, F),
       
  1180     DECLARE_GETPUTNATIVE(Double, D),
       
  1181 
       
  1182     {CC "getAddress",         CC "(" ADR ")" ADR,        FN_PTR(Unsafe_GetNativeAddress)},
       
  1183     {CC "putAddress",         CC "(" ADR "" ADR ")V",    FN_PTR(Unsafe_SetNativeAddress)},
       
  1184 
  1166 
  1185     {CC "allocateMemory0",    CC "(J)" ADR,              FN_PTR(Unsafe_AllocateMemory0)},
  1167     {CC "allocateMemory0",    CC "(J)" ADR,              FN_PTR(Unsafe_AllocateMemory0)},
  1186     {CC "reallocateMemory0",  CC "(" ADR "J)" ADR,       FN_PTR(Unsafe_ReallocateMemory0)},
  1168     {CC "reallocateMemory0",  CC "(" ADR "J)" ADR,       FN_PTR(Unsafe_ReallocateMemory0)},
  1187     {CC "freeMemory0",        CC "(" ADR ")V",           FN_PTR(Unsafe_FreeMemory0)},
  1169     {CC "freeMemory0",        CC "(" ADR ")V",           FN_PTR(Unsafe_FreeMemory0)},
  1188 
  1170 
  1237 #undef THR
  1219 #undef THR
  1238 #undef DC_Args
  1220 #undef DC_Args
  1239 #undef DAC_Args
  1221 #undef DAC_Args
  1240 
  1222 
  1241 #undef DECLARE_GETPUTOOP
  1223 #undef DECLARE_GETPUTOOP
  1242 #undef DECLARE_GETPUTNATIVE
       
  1243 
  1224 
  1244 
  1225 
  1245 // This function is exported, used by NativeLookup.
  1226 // This function is exported, used by NativeLookup.
  1246 // The Unsafe_xxx functions above are called only from the interpreter.
  1227 // The Unsafe_xxx functions above are called only from the interpreter.
  1247 // The optimizer looks at names and signatures to recognize
  1228 // The optimizer looks at names and signatures to recognize