< prev index next >

src/share/vm/prims/unsafe.cpp

Print this page
rev 11983 : 8165489: Missing G1 barrier in Unsafe_GetObjectVolatile
Reviewed-by: mgerdin

*** 270,279 **** --- 270,302 ---- #endif }; // Get/PutObject must be special-cased, since it works with handles. + // We could be accessing the referent field in a reference + // object. If G1 is enabled then we need to register non-null + // referent with the SATB barrier. + + static bool is_java_lang_ref_Reference_access(oop o, jlong offset) { + if (offset == java_lang_ref_Reference::referent_offset && o != NULL) { + Klass* k = o->klass(); + if (InstanceKlass::cast(k)->reference_type() != REF_NONE) { + assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity"); + return true; + } + } + return false; + } + + static void ensure_referent_alive(oop v) { + #if INCLUDE_ALL_GCS + if (UseG1GC && v != NULL) { + G1SATBCardTableModRefBS::enqueue(v); + } + #endif + } + // These functions allow a null base pointer with an arbitrary address. // But if the base pointer is non-null, the offset should make some sense. // That is, it should be in the range [0, MAX_OBJECT_SIZE]. UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { oop p = JNIHandles::resolve(obj);
*** 284,321 **** v = oopDesc::decode_heap_oop(n); } else { v = *(oop*)index_oop_from_field_offset_long(p, offset); } ! jobject ret = JNIHandles::make_local(env, v); ! ! #if INCLUDE_ALL_GCS ! // We could be accessing the referent field in a reference ! // object. If G1 is enabled then we need to register non-null ! // referent with the SATB barrier. ! if (UseG1GC) { ! bool needs_barrier = false; ! ! if (ret != NULL) { ! if (offset == java_lang_ref_Reference::referent_offset && obj != NULL) { ! oop o = JNIHandles::resolve(obj); ! Klass* k = o->klass(); ! if (InstanceKlass::cast(k)->reference_type() != REF_NONE) { ! assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity"); ! needs_barrier = true; ! } ! } ! } ! ! if (needs_barrier) { ! oop referent = JNIHandles::resolve(ret); ! G1SATBCardTableModRefBS::enqueue(referent); ! } } - #endif // INCLUDE_ALL_GCS ! return ret; } UNSAFE_END UNSAFE_ENTRY(void, Unsafe_PutObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) { oop x = JNIHandles::resolve(x_h); oop p = JNIHandles::resolve(obj); --- 307,321 ---- v = oopDesc::decode_heap_oop(n); } else { v = *(oop*)index_oop_from_field_offset_long(p, offset); } ! if (is_java_lang_ref_Reference_access(p, offset)) { ! ensure_referent_alive(v); } ! return JNIHandles::make_local(env, v); } UNSAFE_END UNSAFE_ENTRY(void, Unsafe_PutObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) { oop x = JNIHandles::resolve(x_h); oop p = JNIHandles::resolve(obj);
*** 342,351 **** --- 342,355 ---- (void)const_cast<oop&>(v = oopDesc::decode_heap_oop(n)); } else { (void)const_cast<oop&>(v = *(volatile oop*) addr); } + if (is_java_lang_ref_Reference_access(p, offset)) { + ensure_referent_alive(v); + } + OrderAccess::acquire(); return JNIHandles::make_local(env, v); } UNSAFE_END UNSAFE_ENTRY(void, Unsafe_PutObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
< prev index next >