hotspot/src/share/vm/prims/unsafe.cpp
changeset 7885 c02b05ba16a1
parent 7397 5b173b4ca846
child 8076 96d498ec7ae1
equal deleted inserted replaced
7884:10a0fafc26aa 7885:c02b05ba16a1
     1 /*
     1 /*
     2  * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
   152   oop p = JNIHandles::resolve(obj); \
   152   oop p = JNIHandles::resolve(obj); \
   153   *(type_name*)index_oop_from_field_offset_long(p, offset) = x
   153   *(type_name*)index_oop_from_field_offset_long(p, offset) = x
   154 
   154 
   155 #define GET_FIELD_VOLATILE(obj, offset, type_name, v) \
   155 #define GET_FIELD_VOLATILE(obj, offset, type_name, v) \
   156   oop p = JNIHandles::resolve(obj); \
   156   oop p = JNIHandles::resolve(obj); \
   157   volatile type_name v = *(volatile type_name*)index_oop_from_field_offset_long(p, offset)
   157   volatile type_name v = OrderAccess::load_acquire((volatile type_name*)index_oop_from_field_offset_long(p, offset));
   158 
   158 
   159 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
   159 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
   160   oop p = JNIHandles::resolve(obj); \
   160   oop p = JNIHandles::resolve(obj); \
   161   *(volatile type_name*)index_oop_from_field_offset_long(p, offset) = x; \
   161   OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), x);
   162   OrderAccess::fence();
       
   163 
   162 
   164 // Macros for oops that check UseCompressedOops
   163 // Macros for oops that check UseCompressedOops
   165 
   164 
   166 #define GET_OOP_FIELD(obj, offset, v) \
   165 #define GET_OOP_FIELD(obj, offset, v) \
   167   oop p = JNIHandles::resolve(obj);   \
   166   oop p = JNIHandles::resolve(obj);   \
   179   if (UseCompressedOops) {            \
   178   if (UseCompressedOops) {            \
   180     volatile narrowOop n = *(volatile narrowOop*)index_oop_from_field_offset_long(p, offset); \
   179     volatile narrowOop n = *(volatile narrowOop*)index_oop_from_field_offset_long(p, offset); \
   181     v = oopDesc::decode_heap_oop(n);                               \
   180     v = oopDesc::decode_heap_oop(n);                               \
   182   } else {                            \
   181   } else {                            \
   183     v = *(volatile oop*)index_oop_from_field_offset_long(p, offset);       \
   182     v = *(volatile oop*)index_oop_from_field_offset_long(p, offset);       \
   184   }
   183   } \
       
   184   OrderAccess::acquire();
   185 
   185 
   186 
   186 
   187 // Get/SetObject must be special-cased, since it works with handles.
   187 // Get/SetObject must be special-cased, since it works with handles.
   188 
   188 
   189 // The xxx140 variants for backward compatibility do not allow a full-width offset.
   189 // The xxx140 variants for backward compatibility do not allow a full-width offset.
   246 
   246 
   247 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
   247 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
   248   UnsafeWrapper("Unsafe_SetObjectVolatile");
   248   UnsafeWrapper("Unsafe_SetObjectVolatile");
   249   oop x = JNIHandles::resolve(x_h);
   249   oop x = JNIHandles::resolve(x_h);
   250   oop p = JNIHandles::resolve(obj);
   250   oop p = JNIHandles::resolve(obj);
       
   251   void* addr = index_oop_from_field_offset_long(p, offset);
       
   252   OrderAccess::release();
   251   if (UseCompressedOops) {
   253   if (UseCompressedOops) {
   252     oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
   254     oop_store((narrowOop*)addr, x);
   253   } else {
   255   } else {
   254     oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
   256     oop_store((oop*)addr, x);
   255   }
   257   }
   256   OrderAccess::fence();
   258   OrderAccess::fence();
   257 UNSAFE_END
   259 UNSAFE_END
       
   260 
       
   261 #if defined(SPARC) || defined(X86)
       
   262 // Sparc and X86 have atomic jlong (8 bytes) instructions
       
   263 
       
   264 #else
       
   265 // Keep old code for platforms which may not have atomic jlong (8 bytes) instructions
   258 
   266 
   259 // Volatile long versions must use locks if !VM_Version::supports_cx8().
   267 // Volatile long versions must use locks if !VM_Version::supports_cx8().
   260 // support_cx8 is a surrogate for 'supports atomic long memory ops'.
   268 // support_cx8 is a surrogate for 'supports atomic long memory ops'.
   261 
   269 
   262 UNSAFE_ENTRY(jlong, Unsafe_GetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
   270 UNSAFE_ENTRY(jlong, Unsafe_GetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
   289       *addr = x;
   297       *addr = x;
   290     }
   298     }
   291   }
   299   }
   292 UNSAFE_END
   300 UNSAFE_END
   293 
   301 
       
   302 #endif // not SPARC and not X86
   294 
   303 
   295 #define DEFINE_GETSETOOP(jboolean, Boolean) \
   304 #define DEFINE_GETSETOOP(jboolean, Boolean) \
   296  \
   305  \
   297 UNSAFE_ENTRY(jboolean, Unsafe_Get##Boolean##140(JNIEnv *env, jobject unsafe, jobject obj, jint offset)) \
   306 UNSAFE_ENTRY(jboolean, Unsafe_Get##Boolean##140(JNIEnv *env, jobject unsafe, jobject obj, jint offset)) \
   298   UnsafeWrapper("Unsafe_Get"#Boolean); \
   307   UnsafeWrapper("Unsafe_Get"#Boolean); \
   318   SET_FIELD(obj, offset, jboolean, x); \
   327   SET_FIELD(obj, offset, jboolean, x); \
   319 UNSAFE_END \
   328 UNSAFE_END \
   320  \
   329  \
   321 // END DEFINE_GETSETOOP.
   330 // END DEFINE_GETSETOOP.
   322 
   331 
       
   332 DEFINE_GETSETOOP(jboolean, Boolean)
       
   333 DEFINE_GETSETOOP(jbyte, Byte)
       
   334 DEFINE_GETSETOOP(jshort, Short);
       
   335 DEFINE_GETSETOOP(jchar, Char);
       
   336 DEFINE_GETSETOOP(jint, Int);
       
   337 DEFINE_GETSETOOP(jlong, Long);
       
   338 DEFINE_GETSETOOP(jfloat, Float);
       
   339 DEFINE_GETSETOOP(jdouble, Double);
       
   340 
       
   341 #undef DEFINE_GETSETOOP
   323 
   342 
   324 #define DEFINE_GETSETOOP_VOLATILE(jboolean, Boolean) \
   343 #define DEFINE_GETSETOOP_VOLATILE(jboolean, Boolean) \
   325  \
   344  \
   326 UNSAFE_ENTRY(jboolean, Unsafe_Get##Boolean##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) \
   345 UNSAFE_ENTRY(jboolean, Unsafe_Get##Boolean##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) \
   327   UnsafeWrapper("Unsafe_Get"#Boolean); \
   346   UnsafeWrapper("Unsafe_Get"#Boolean); \
   334   SET_FIELD_VOLATILE(obj, offset, jboolean, x); \
   353   SET_FIELD_VOLATILE(obj, offset, jboolean, x); \
   335 UNSAFE_END \
   354 UNSAFE_END \
   336  \
   355  \
   337 // END DEFINE_GETSETOOP_VOLATILE.
   356 // END DEFINE_GETSETOOP_VOLATILE.
   338 
   357 
   339 DEFINE_GETSETOOP(jboolean, Boolean)
       
   340 DEFINE_GETSETOOP(jbyte, Byte)
       
   341 DEFINE_GETSETOOP(jshort, Short);
       
   342 DEFINE_GETSETOOP(jchar, Char);
       
   343 DEFINE_GETSETOOP(jint, Int);
       
   344 DEFINE_GETSETOOP(jlong, Long);
       
   345 DEFINE_GETSETOOP(jfloat, Float);
       
   346 DEFINE_GETSETOOP(jdouble, Double);
       
   347 
       
   348 DEFINE_GETSETOOP_VOLATILE(jboolean, Boolean)
   358 DEFINE_GETSETOOP_VOLATILE(jboolean, Boolean)
   349 DEFINE_GETSETOOP_VOLATILE(jbyte, Byte)
   359 DEFINE_GETSETOOP_VOLATILE(jbyte, Byte)
   350 DEFINE_GETSETOOP_VOLATILE(jshort, Short);
   360 DEFINE_GETSETOOP_VOLATILE(jshort, Short);
   351 DEFINE_GETSETOOP_VOLATILE(jchar, Char);
   361 DEFINE_GETSETOOP_VOLATILE(jchar, Char);
   352 DEFINE_GETSETOOP_VOLATILE(jint, Int);
   362 DEFINE_GETSETOOP_VOLATILE(jint, Int);
   353 // no long -- handled specially
       
   354 DEFINE_GETSETOOP_VOLATILE(jfloat, Float);
   363 DEFINE_GETSETOOP_VOLATILE(jfloat, Float);
   355 DEFINE_GETSETOOP_VOLATILE(jdouble, Double);
   364 DEFINE_GETSETOOP_VOLATILE(jdouble, Double);
   356 
   365 
   357 #undef DEFINE_GETSETOOP
   366 #if defined(SPARC) || defined(X86)
       
   367 // Sparc and X86 have atomic jlong (8 bytes) instructions
       
   368 DEFINE_GETSETOOP_VOLATILE(jlong, Long);
       
   369 #endif
       
   370 
       
   371 #undef DEFINE_GETSETOOP_VOLATILE
   358 
   372 
   359 // The non-intrinsified versions of setOrdered just use setVolatile
   373 // The non-intrinsified versions of setOrdered just use setVolatile
   360 
   374 
   361 UNSAFE_ENTRY(void, Unsafe_SetOrderedInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint x)) \
   375 UNSAFE_ENTRY(void, Unsafe_SetOrderedInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint x))
   362   UnsafeWrapper("Unsafe_SetOrderedInt"); \
   376   UnsafeWrapper("Unsafe_SetOrderedInt");
   363   SET_FIELD_VOLATILE(obj, offset, jint, x); \
   377   SET_FIELD_VOLATILE(obj, offset, jint, x);
   364 UNSAFE_END
   378 UNSAFE_END
   365 
   379 
   366 UNSAFE_ENTRY(void, Unsafe_SetOrderedObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
   380 UNSAFE_ENTRY(void, Unsafe_SetOrderedObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
   367   UnsafeWrapper("Unsafe_SetOrderedObject");
   381   UnsafeWrapper("Unsafe_SetOrderedObject");
   368   oop x = JNIHandles::resolve(x_h);
   382   oop x = JNIHandles::resolve(x_h);
   369   oop p = JNIHandles::resolve(obj);
   383   oop p = JNIHandles::resolve(obj);
       
   384   void* addr = index_oop_from_field_offset_long(p, offset);
       
   385   OrderAccess::release();
   370   if (UseCompressedOops) {
   386   if (UseCompressedOops) {
   371     oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
   387     oop_store((narrowOop*)addr, x);
   372   } else {
   388   } else {
   373     oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
   389     oop_store((oop*)addr, x);
   374   }
   390   }
   375   OrderAccess::fence();
   391   OrderAccess::fence();
   376 UNSAFE_END
   392 UNSAFE_END
   377 
   393 
   378 UNSAFE_ENTRY(void, Unsafe_SetOrderedLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x))
   394 UNSAFE_ENTRY(void, Unsafe_SetOrderedLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x))
   379   UnsafeWrapper("Unsafe_SetOrderedLong");
   395   UnsafeWrapper("Unsafe_SetOrderedLong");
       
   396 #if defined(SPARC) || defined(X86)
       
   397   // Sparc and X86 have atomic jlong (8 bytes) instructions
       
   398   SET_FIELD_VOLATILE(obj, offset, jlong, x);
       
   399 #else
       
   400   // Keep old code for platforms which may not have atomic long (8 bytes) instructions
   380   {
   401   {
   381     if (VM_Version::supports_cx8()) {
   402     if (VM_Version::supports_cx8()) {
   382       SET_FIELD_VOLATILE(obj, offset, jlong, x);
   403       SET_FIELD_VOLATILE(obj, offset, jlong, x);
   383     }
   404     }
   384     else {
   405     else {
   386       jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
   407       jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
   387       ObjectLocker ol(p, THREAD);
   408       ObjectLocker ol(p, THREAD);
   388       *addr = x;
   409       *addr = x;
   389     }
   410     }
   390   }
   411   }
       
   412 #endif
   391 UNSAFE_END
   413 UNSAFE_END
   392 
   414 
   393 ////// Data in the C heap.
   415 ////// Data in the C heap.
   394 
   416 
   395 // Note:  These do not throw NullPointerException for bad pointers.
   417 // Note:  These do not throw NullPointerException for bad pointers.