# HG changeset patch # User mdoerr # Date 1473159687 -7200 # Node ID 2ce2f1c582ca0ac57c11235db00fa03e92deecf5 # Parent 6268665d2fd768748aabe90af315c0f5090a42a7 8165489: Missing G1 barrier in Unsafe_GetObjectVolatile Summary: Add missing barrier, sharing code with Unsafe_GetObject. Reviewed-by: kbarrett, mgerdin, pliden diff -r 6268665d2fd7 -r 2ce2f1c582ca hotspot/src/share/vm/prims/unsafe.cpp --- a/hotspot/src/share/vm/prims/unsafe.cpp Fri Sep 16 13:15:01 2016 -0700 +++ b/hotspot/src/share/vm/prims/unsafe.cpp Tue Sep 06 13:01:27 2016 +0200 @@ -272,6 +272,31 @@ // 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. + +#if INCLUDE_ALL_GCS +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; +} +#endif + +static void ensure_satb_referent_alive(oop o, jlong offset, oop v) { +#if INCLUDE_ALL_GCS + if (UseG1GC && v != NULL && is_java_lang_ref_Reference_access(o, offset)) { + 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]. @@ -286,34 +311,9 @@ 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; + ensure_satb_referent_alive(p, offset, v); - 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; + return JNIHandles::make_local(env, v); } UNSAFE_END UNSAFE_ENTRY(void, Unsafe_PutObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) { @@ -344,6 +344,8 @@ (void)const_cast(v = *(volatile oop*) addr); } + ensure_satb_referent_alive(p, offset, v); + OrderAccess::acquire(); return JNIHandles::make_local(env, v); } UNSAFE_END