< prev index next >

src/share/vm/prims/unsafe.cpp

Print this page
rev 8577 : 8165489: Missing G1 barrier in Unsafe_GetObjectVolatile
Summary: Add missing barrier, sharing code with Unsafe_GetObject.
Reviewed-by: kbarrett, mgerdin, pliden


 182 
 183 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
 184   oop p = JNIHandles::resolve(obj); \
 185   OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), truncate_##type_name(x));
 186 
 187 // Macros for oops that check UseCompressedOops
 188 
 189 #define GET_OOP_FIELD(obj, offset, v) \
 190   oop p = JNIHandles::resolve(obj);   \
 191   oop v;                              \
 192   if (UseCompressedOops) {            \
 193     narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \
 194     v = oopDesc::decode_heap_oop(n);                                \
 195   } else {                            \
 196     v = *(oop*)index_oop_from_field_offset_long(p, offset);                 \
 197   }
 198 
 199 
 200 // Get/SetObject must be special-cased, since it works with handles.
 201 
 202 // The xxx140 variants for backward compatibility do not allow a full-width offset.
 203 UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset))
 204   UnsafeWrapper("Unsafe_GetObject");
 205   if (obj == NULL)  THROW_0(vmSymbols::java_lang_NullPointerException());
 206   GET_OOP_FIELD(obj, offset, v)
 207   jobject ret = JNIHandles::make_local(env, v);
 208 #if INCLUDE_ALL_GCS
 209   // We could be accessing the referent field in a reference
 210   // object. If G1 is enabled then we need to register a non-null
 211   // referent with the SATB barrier.
 212   if (UseG1GC) {
 213     bool needs_barrier = false;
 214 
 215     if (ret != NULL) {
 216       if (offset == java_lang_ref_Reference::referent_offset) {
 217         oop o = JNIHandles::resolve_non_null(obj);
 218         Klass* k = o->klass();
 219         if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
 220           assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
 221           needs_barrier = true;
 222         }
 223       }
 224     }



 225 
 226     if (needs_barrier) {
 227       oop referent = JNIHandles::resolve(ret);
 228       G1SATBCardTableModRefBS::enqueue(referent);
 229     }
 230   }
 231 #endif // INCLUDE_ALL_GCS
 232   return ret;










 233 UNSAFE_END
 234 
 235 UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h))
 236   UnsafeWrapper("Unsafe_SetObject");
 237   if (obj == NULL)  THROW(vmSymbols::java_lang_NullPointerException());
 238   oop x = JNIHandles::resolve(x_h);
 239   //SET_FIELD(obj, offset, oop, x);
 240   oop p = JNIHandles::resolve(obj);
 241   if (UseCompressedOops) {
 242     if (x != NULL) {
 243       // If there is a heap base pointer, we are obliged to emit a store barrier.
 244       oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
 245     } else {
 246       narrowOop n = oopDesc::encode_heap_oop_not_null(x);
 247       *(narrowOop*)index_oop_from_field_offset_long(p, offset) = n;
 248     }
 249   } else {
 250     if (x != NULL) {
 251       // If there is a heap base pointer, we are obliged to emit a store barrier.
 252       oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
 253     } else {
 254       *(oop*)index_oop_from_field_offset_long(p, offset) = x;
 255     }
 256   }
 257 UNSAFE_END
 258 
 259 // The normal variants 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_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
 263   UnsafeWrapper("Unsafe_GetObject");
 264   GET_OOP_FIELD(obj, offset, v)
 265   jobject ret = JNIHandles::make_local(env, v);
 266 #if INCLUDE_ALL_GCS
 267   // We could be accessing the referent field in a reference
 268   // object. If G1 is enabled then we need to register non-null
 269   // referent with the SATB barrier.
 270   if (UseG1GC) {
 271     bool needs_barrier = false;
 272 
 273     if (ret != NULL) {
 274       if (offset == java_lang_ref_Reference::referent_offset && obj != NULL) {
 275         oop o = JNIHandles::resolve(obj);
 276         Klass* k = o->klass();
 277         if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
 278           assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
 279           needs_barrier = true;
 280         }
 281       }
 282     }
 283 
 284     if (needs_barrier) {
 285       oop referent = JNIHandles::resolve(ret);
 286       G1SATBCardTableModRefBS::enqueue(referent);
 287     }
 288   }
 289 #endif // INCLUDE_ALL_GCS
 290   return ret;
 291 UNSAFE_END
 292 
 293 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
 294   UnsafeWrapper("Unsafe_SetObject");
 295   oop x = JNIHandles::resolve(x_h);
 296   oop p = JNIHandles::resolve(obj);
 297   if (UseCompressedOops) {
 298     oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
 299   } else {
 300     oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
 301   }
 302 UNSAFE_END
 303 
 304 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
 305   UnsafeWrapper("Unsafe_GetObjectVolatile");
 306   oop p = JNIHandles::resolve(obj);
 307   void* addr = index_oop_from_field_offset_long(p, offset);
 308   volatile oop v;
 309   if (UseCompressedOops) {
 310     volatile narrowOop n = *(volatile narrowOop*) addr;
 311     (void)const_cast<oop&>(v = oopDesc::decode_heap_oop(n));
 312   } else {
 313     (void)const_cast<oop&>(v = *(volatile oop*) addr);
 314   }



 315   OrderAccess::acquire();
 316   return JNIHandles::make_local(env, v);
 317 UNSAFE_END
 318 
 319 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
 320   UnsafeWrapper("Unsafe_SetObjectVolatile");
 321   oop x = JNIHandles::resolve(x_h);
 322   oop p = JNIHandles::resolve(obj);
 323   void* addr = index_oop_from_field_offset_long(p, offset);
 324   OrderAccess::release();
 325   if (UseCompressedOops) {
 326     oop_store((narrowOop*)addr, x);
 327   } else {
 328     oop_store((oop*)addr, x);
 329   }
 330   OrderAccess::fence();
 331 UNSAFE_END
 332 
 333 #ifndef SUPPORTS_NATIVE_CX8
 334 




 182 
 183 #define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
 184   oop p = JNIHandles::resolve(obj); \
 185   OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), truncate_##type_name(x));
 186 
 187 // Macros for oops that check UseCompressedOops
 188 
 189 #define GET_OOP_FIELD(obj, offset, v) \
 190   oop p = JNIHandles::resolve(obj);   \
 191   oop v;                              \
 192   if (UseCompressedOops) {            \
 193     narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \
 194     v = oopDesc::decode_heap_oop(n);                                \
 195   } else {                            \
 196     v = *(oop*)index_oop_from_field_offset_long(p, offset);                 \
 197   }
 198 
 199 
 200 // Get/SetObject must be special-cased, since it works with handles.
 201 
 202 // We could be accessing the referent field in a reference
 203 // object. If G1 is enabled then we need to register non-null
 204 // referent with the SATB barrier.
 205 


 206 #if INCLUDE_ALL_GCS
 207 static bool is_java_lang_ref_Reference_access(oop o, jlong offset) {
 208   if (offset == java_lang_ref_Reference::referent_offset && o != NULL) {







 209     Klass* k = o->klass();
 210     if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
 211       assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
 212       return true;

 213     }
 214   }
 215  return false;
 216 }
 217 #endif
 218 
 219 static void ensure_satb_referent_alive(oop o, jlong offset, oop v) {
 220 #if INCLUDE_ALL_GCS
 221   if (UseG1GC && v != NULL && is_java_lang_ref_Reference_access(o, offset)) {
 222     G1SATBCardTableModRefBS::enqueue(v);
 223   }
 224 #endif
 225 }
 226 
 227 // The xxx140 variants for backward compatibility do not allow a full-width offset.
 228 UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset))
 229   UnsafeWrapper("Unsafe_GetObject");
 230   if (obj == NULL)  THROW_0(vmSymbols::java_lang_NullPointerException());
 231   GET_OOP_FIELD(obj, offset, v)
 232 
 233   ensure_satb_referent_alive(p, offset, v);
 234 
 235   return JNIHandles::make_local(env, v);
 236 UNSAFE_END
 237 
 238 UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h))
 239   UnsafeWrapper("Unsafe_SetObject");
 240   if (obj == NULL)  THROW(vmSymbols::java_lang_NullPointerException());
 241   oop x = JNIHandles::resolve(x_h);
 242   //SET_FIELD(obj, offset, oop, x);
 243   oop p = JNIHandles::resolve(obj);
 244   if (UseCompressedOops) {
 245     if (x != NULL) {
 246       // If there is a heap base pointer, we are obliged to emit a store barrier.
 247       oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
 248     } else {
 249       narrowOop n = oopDesc::encode_heap_oop_not_null(x);
 250       *(narrowOop*)index_oop_from_field_offset_long(p, offset) = n;
 251     }
 252   } else {
 253     if (x != NULL) {
 254       // If there is a heap base pointer, we are obliged to emit a store barrier.
 255       oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
 256     } else {
 257       *(oop*)index_oop_from_field_offset_long(p, offset) = x;
 258     }
 259   }
 260 UNSAFE_END
 261 
 262 // The normal variants 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_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
 266   UnsafeWrapper("Unsafe_GetObject");
 267   GET_OOP_FIELD(obj, offset, v)


















 268 
 269   ensure_satb_referent_alive(p, offset, v);
 270 
 271   return JNIHandles::make_local(env, v);




 272 UNSAFE_END
 273 
 274 UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
 275   UnsafeWrapper("Unsafe_SetObject");
 276   oop x = JNIHandles::resolve(x_h);
 277   oop p = JNIHandles::resolve(obj);
 278   if (UseCompressedOops) {
 279     oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
 280   } else {
 281     oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
 282   }
 283 UNSAFE_END
 284 
 285 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
 286   UnsafeWrapper("Unsafe_GetObjectVolatile");
 287   oop p = JNIHandles::resolve(obj);
 288   void* addr = index_oop_from_field_offset_long(p, offset);
 289   volatile oop v;
 290   if (UseCompressedOops) {
 291     volatile narrowOop n = *(volatile narrowOop*) addr;
 292     (void)const_cast<oop&>(v = oopDesc::decode_heap_oop(n));
 293   } else {
 294     (void)const_cast<oop&>(v = *(volatile oop*) addr);
 295   }
 296 
 297   ensure_satb_referent_alive(p, offset, v);
 298 
 299   OrderAccess::acquire();
 300   return JNIHandles::make_local(env, v);
 301 UNSAFE_END
 302 
 303 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
 304   UnsafeWrapper("Unsafe_SetObjectVolatile");
 305   oop x = JNIHandles::resolve(x_h);
 306   oop p = JNIHandles::resolve(obj);
 307   void* addr = index_oop_from_field_offset_long(p, offset);
 308   OrderAccess::release();
 309   if (UseCompressedOops) {
 310     oop_store((narrowOop*)addr, x);
 311   } else {
 312     oop_store((oop*)addr, x);
 313   }
 314   OrderAccess::fence();
 315 UNSAFE_END
 316 
 317 #ifndef SUPPORTS_NATIVE_CX8
 318 


< prev index next >