hotspot/src/share/vm/prims/unsafe.cpp
changeset 360 21d113ecbf6a
parent 1 489c9b5090e2
child 670 ddf3e9583f2f
child 1374 4c24294029a9
equal deleted inserted replaced
357:f4edb0d9f109 360:21d113ecbf6a
    98 #ifdef ASSERT
    98 #ifdef ASSERT
    99   if (p != NULL) {
    99   if (p != NULL) {
   100     assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset");
   100     assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset");
   101     if (byte_offset == (jint)byte_offset) {
   101     if (byte_offset == (jint)byte_offset) {
   102       void* ptr_plus_disp = (address)p + byte_offset;
   102       void* ptr_plus_disp = (address)p + byte_offset;
   103       assert((void*)p->obj_field_addr((jint)byte_offset) == ptr_plus_disp,
   103       assert((void*)p->obj_field_addr<oop>((jint)byte_offset) == ptr_plus_disp,
   104              "raw [ptr+disp] must be consistent with oop::field_base");
   104              "raw [ptr+disp] must be consistent with oop::field_base");
   105     }
   105     }
   106   }
   106   }
   107 #endif
   107 #endif
   108   if (sizeof(char*) == sizeof(jint))    // (this constant folds!)
   108   if (sizeof(char*) == sizeof(jint))    // (this constant folds!)
   144 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
   144 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
   145   oop p = JNIHandles::resolve(obj); \
   145   oop p = JNIHandles::resolve(obj); \
   146   *(volatile type_name*)index_oop_from_field_offset_long(p, offset) = x; \
   146   *(volatile type_name*)index_oop_from_field_offset_long(p, offset) = x; \
   147   OrderAccess::fence();
   147   OrderAccess::fence();
   148 
   148 
       
   149 // Macros for oops that check UseCompressedOops
       
   150 
       
   151 #define GET_OOP_FIELD(obj, offset, v) \
       
   152   oop p = JNIHandles::resolve(obj);   \
       
   153   oop v;                              \
       
   154   if (UseCompressedOops) {            \
       
   155     narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \
       
   156     v = oopDesc::decode_heap_oop(n);                                \
       
   157   } else {                            \
       
   158     v = *(oop*)index_oop_from_field_offset_long(p, offset);                 \
       
   159   }
       
   160 
       
   161 #define GET_OOP_FIELD_VOLATILE(obj, offset, v) \
       
   162   oop p = JNIHandles::resolve(obj);   \
       
   163   volatile oop v;                     \
       
   164   if (UseCompressedOops) {            \
       
   165     volatile narrowOop n = *(volatile narrowOop*)index_oop_from_field_offset_long(p, offset); \
       
   166     v = oopDesc::decode_heap_oop(n);                               \
       
   167   } else {                            \
       
   168     v = *(volatile oop*)index_oop_from_field_offset_long(p, offset);       \
       
   169   }
       
   170 
       
   171 
   149 // Get/SetObject must be special-cased, since it works with handles.
   172 // Get/SetObject must be special-cased, since it works with handles.
   150 
   173 
   151 // The xxx140 variants for backward compatibility do not allow a full-width offset.
   174 // The xxx140 variants for backward compatibility do not allow a full-width offset.
   152 UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset))
   175 UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset))
   153   UnsafeWrapper("Unsafe_GetObject");
   176   UnsafeWrapper("Unsafe_GetObject");
   154   if (obj == NULL)  THROW_0(vmSymbols::java_lang_NullPointerException());
   177   if (obj == NULL)  THROW_0(vmSymbols::java_lang_NullPointerException());
   155   GET_FIELD(obj, offset, oop, v);
   178   GET_OOP_FIELD(obj, offset, v)
   156   return JNIHandles::make_local(env, v);
   179   return JNIHandles::make_local(env, v);
   157 UNSAFE_END
   180 UNSAFE_END
   158 
   181 
   159 UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h))
   182 UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h))
   160   UnsafeWrapper("Unsafe_SetObject");
   183   UnsafeWrapper("Unsafe_SetObject");
   161   if (obj == NULL)  THROW(vmSymbols::java_lang_NullPointerException());
   184   if (obj == NULL)  THROW(vmSymbols::java_lang_NullPointerException());
   162   oop x = JNIHandles::resolve(x_h);
   185   oop x = JNIHandles::resolve(x_h);
   163   //SET_FIELD(obj, offset, oop, x);
   186   //SET_FIELD(obj, offset, oop, x);
   164   oop p = JNIHandles::resolve(obj);
   187   oop p = JNIHandles::resolve(obj);
   165   if (x != NULL) {
   188   if (UseCompressedOops) {
   166     // If there is a heap base pointer, we are obliged to emit a store barrier.
   189     if (x != NULL) {
   167     oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
   190       // If there is a heap base pointer, we are obliged to emit a store barrier.
       
   191       oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
       
   192     } else {
       
   193       narrowOop n = oopDesc::encode_heap_oop_not_null(x);
       
   194       *(narrowOop*)index_oop_from_field_offset_long(p, offset) = n;
       
   195     }
   168   } else {
   196   } else {
   169     *(oop*)index_oop_from_field_offset_long(p, offset) = x;
   197     if (x != NULL) {
       
   198       // If there is a heap base pointer, we are obliged to emit a store barrier.
       
   199       oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
       
   200     } else {
       
   201       *(oop*)index_oop_from_field_offset_long(p, offset) = x;
       
   202     }
   170   }
   203   }
   171 UNSAFE_END
   204 UNSAFE_END
   172 
   205 
   173 // The normal variants allow a null base pointer with an arbitrary address.
   206 // The normal variants allow a null base pointer with an arbitrary address.
   174 // But if the base pointer is non-null, the offset should make some sense.
   207 // But if the base pointer is non-null, the offset should make some sense.
   175 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
   208 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
   176 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
   209 UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
   177   UnsafeWrapper("Unsafe_GetObject");
   210   UnsafeWrapper("Unsafe_GetObject");
   178   GET_FIELD(obj, offset, oop, v);
   211   GET_OOP_FIELD(obj, offset, v)
   179   return JNIHandles::make_local(env, v);
   212   return JNIHandles::make_local(env, v);
   180 UNSAFE_END
   213 UNSAFE_END
   181 
   214 
   182 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
   215 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
   183   UnsafeWrapper("Unsafe_SetObject");
   216   UnsafeWrapper("Unsafe_SetObject");
   184   oop x = JNIHandles::resolve(x_h);
   217   oop x = JNIHandles::resolve(x_h);
   185   oop p = JNIHandles::resolve(obj);
   218   oop p = JNIHandles::resolve(obj);
   186   oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
   219   if (UseCompressedOops) {
       
   220     oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
       
   221   } else {
       
   222     oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
       
   223   }
   187 UNSAFE_END
   224 UNSAFE_END
   188 
   225 
   189 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
   226 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
   190   UnsafeWrapper("Unsafe_GetObjectVolatile");
   227   UnsafeWrapper("Unsafe_GetObjectVolatile");
   191   GET_FIELD_VOLATILE(obj, offset, oop, v);
   228   GET_OOP_FIELD_VOLATILE(obj, offset, v)
   192   return JNIHandles::make_local(env, v);
   229   return JNIHandles::make_local(env, v);
   193 UNSAFE_END
   230 UNSAFE_END
   194 
   231 
   195 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
   232 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
   196   UnsafeWrapper("Unsafe_SetObjectVolatile");
   233   UnsafeWrapper("Unsafe_SetObjectVolatile");
   197   oop x = JNIHandles::resolve(x_h);
   234   oop x = JNIHandles::resolve(x_h);
   198   oop p = JNIHandles::resolve(obj);
   235   oop p = JNIHandles::resolve(obj);
   199   oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
   236   if (UseCompressedOops) {
       
   237     oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
       
   238   } else {
       
   239     oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
       
   240   }
   200   OrderAccess::fence();
   241   OrderAccess::fence();
   201 UNSAFE_END
   242 UNSAFE_END
   202 
   243 
   203 // Volatile long versions must use locks if !VM_Version::supports_cx8().
   244 // Volatile long versions must use locks if !VM_Version::supports_cx8().
   204 // support_cx8 is a surrogate for 'supports atomic long memory ops'.
   245 // support_cx8 is a surrogate for 'supports atomic long memory ops'.
   309 
   350 
   310 UNSAFE_ENTRY(void, Unsafe_SetOrderedObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
   351 UNSAFE_ENTRY(void, Unsafe_SetOrderedObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
   311   UnsafeWrapper("Unsafe_SetOrderedObject");
   352   UnsafeWrapper("Unsafe_SetOrderedObject");
   312   oop x = JNIHandles::resolve(x_h);
   353   oop x = JNIHandles::resolve(x_h);
   313   oop p = JNIHandles::resolve(obj);
   354   oop p = JNIHandles::resolve(obj);
   314   oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
   355   if (UseCompressedOops) {
       
   356     oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
       
   357   } else {
       
   358     oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
       
   359   }
   315   OrderAccess::fence();
   360   OrderAccess::fence();
   316 UNSAFE_END
   361 UNSAFE_END
   317 
   362 
   318 UNSAFE_ENTRY(void, Unsafe_SetOrderedLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x))
   363 UNSAFE_ENTRY(void, Unsafe_SetOrderedLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x))
   319   UnsafeWrapper("Unsafe_SetOrderedLong");
   364   UnsafeWrapper("Unsafe_SetOrderedLong");
   645   klassOop k      = java_lang_Class::as_klassOop(mirror);
   690   klassOop k      = java_lang_Class::as_klassOop(mirror);
   646   if (k == NULL || !k->klass_part()->oop_is_array()) {
   691   if (k == NULL || !k->klass_part()->oop_is_array()) {
   647     THROW(vmSymbols::java_lang_InvalidClassException());
   692     THROW(vmSymbols::java_lang_InvalidClassException());
   648   } else if (k->klass_part()->oop_is_objArray()) {
   693   } else if (k->klass_part()->oop_is_objArray()) {
   649     base  = arrayOopDesc::base_offset_in_bytes(T_OBJECT);
   694     base  = arrayOopDesc::base_offset_in_bytes(T_OBJECT);
   650     scale = oopSize;
   695     scale = heapOopSize;
   651   } else if (k->klass_part()->oop_is_typeArray()) {
   696   } else if (k->klass_part()->oop_is_typeArray()) {
   652     typeArrayKlass* tak = typeArrayKlass::cast(k);
   697     typeArrayKlass* tak = typeArrayKlass::cast(k);
   653     base  = tak->array_header_in_bytes();
   698     base  = tak->array_header_in_bytes();
   654     assert(base == arrayOopDesc::base_offset_in_bytes(tak->element_type()), "array_header_size semantics ok");
   699     assert(base == arrayOopDesc::base_offset_in_bytes(tak->element_type()), "array_header_size semantics ok");
   655     scale = (1 << tak->log2_element_size());
   700     scale = (1 << tak->log2_element_size());
   843 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h))
   888 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h))
   844   UnsafeWrapper("Unsafe_CompareAndSwapObject");
   889   UnsafeWrapper("Unsafe_CompareAndSwapObject");
   845   oop x = JNIHandles::resolve(x_h);
   890   oop x = JNIHandles::resolve(x_h);
   846   oop e = JNIHandles::resolve(e_h);
   891   oop e = JNIHandles::resolve(e_h);
   847   oop p = JNIHandles::resolve(obj);
   892   oop p = JNIHandles::resolve(obj);
   848   intptr_t* addr = (intptr_t *)index_oop_from_field_offset_long(p, offset);
   893   HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset);
   849   intptr_t res = Atomic::cmpxchg_ptr((intptr_t)x, addr, (intptr_t)e);
   894   oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e);
   850   jboolean success  = (res == (intptr_t)e);
   895   jboolean success  = (res == e);
   851   if (success)
   896   if (success)
   852     update_barrier_set((oop*)addr, x);
   897     update_barrier_set((void*)addr, x);
   853   return success;
   898   return success;
   854 UNSAFE_END
   899 UNSAFE_END
   855 
   900 
   856 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))
   901 UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))
   857   UnsafeWrapper("Unsafe_CompareAndSwapInt");
   902   UnsafeWrapper("Unsafe_CompareAndSwapInt");