< prev index next >
src/share/vm/prims/unsafe.cpp
Print this page
rev 11938 : 8165489: Missing G1 barrier in Unsafe_GetObjectVolatile
Reviewed-by:
*** 261,270 ****
--- 261,285 ----
#endif
};
// Get/PutObject must be special-cased, since it works with handles.
+ #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.
+ inline void G1SATB_registerReference(oop o, jlong offset, oop v) {
+ if (UseG1GC && offset == java_lang_ref_Reference::referent_offset && o != NULL && v != NULL) {
+ Klass* k = o->klass();
+ if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
+ assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
+ 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);
*** 275,312 ****
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);
--- 290,304 ----
v = oopDesc::decode_heap_oop(n);
} else {
v = *(oop*)index_oop_from_field_offset_long(p, offset);
}
#if INCLUDE_ALL_GCS
! G1SATB_registerReference(p, offset, v);
! #endif
! 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);
*** 333,342 ****
--- 325,338 ----
(void)const_cast<oop&>(v = oopDesc::decode_heap_oop(n));
} else {
(void)const_cast<oop&>(v = *(volatile oop*) addr);
}
+ #if INCLUDE_ALL_GCS
+ G1SATB_registerReference(p, offset, v);
+ #endif
+
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 >