Mercurial > hg > icedtea8-forest > hotspot
changeset 9904:7f6e1069a571 icedtea-3.8.0pre02
8165489, PR3589: Missing G1 barrier in Unsafe_GetObjectVolatile
Summary: Add missing barrier, sharing code with Unsafe_GetObject.
Reviewed-by: kbarrett, mgerdin, pliden, tschatzl
author | mdoerr |
---|---|
date | Tue, 06 Sep 2016 13:01:27 +0200 |
parents | b8fc1e640c4c |
children | 999983606f5c |
files | src/share/vm/prims/unsafe.cpp |
diffstat | 1 files changed, 32 insertions(+), 48 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/vm/prims/unsafe.cpp Fri May 11 20:12:10 2018 +0100 +++ b/src/share/vm/prims/unsafe.cpp Tue Sep 06 13:01:27 2016 +0200 @@ -199,37 +199,40 @@ // Get/SetObject 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 +} + // The xxx140 variants for backward compatibility do not allow a full-width offset. UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset)) UnsafeWrapper("Unsafe_GetObject"); if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException()); GET_OOP_FIELD(obj, offset, v) - 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 a non-null - // referent with the SATB barrier. - if (UseG1GC) { - bool needs_barrier = false; - if (ret != NULL) { - if (offset == java_lang_ref_Reference::referent_offset) { - oop o = JNIHandles::resolve_non_null(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; - } - } - } + ensure_satb_referent_alive(p, offset, v); - 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_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h)) @@ -262,32 +265,10 @@ UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) UnsafeWrapper("Unsafe_GetObject"); GET_OOP_FIELD(obj, offset, v) - 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; - } - } - } + ensure_satb_referent_alive(p, offset, v); - 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_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) @@ -312,6 +293,9 @@ } else { (void)const_cast<oop&>(v = *(volatile oop*) addr); } + + ensure_satb_referent_alive(p, offset, v); + OrderAccess::acquire(); return JNIHandles::make_local(env, v); UNSAFE_END