< prev index next >
src/share/vm/prims/unsafe.cpp
Print this page
@@ -119,10 +119,11 @@
jlong byte_offset = field_offset_to_byte_offset(field_offset);
#ifdef ASSERT
if (p != NULL) {
assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset");
if (byte_offset == (jint)byte_offset) {
+ p = oopDesc::bs()->write_barrier(p);
void* ptr_plus_disp = (address)p + byte_offset;
assert((void*)p->obj_field_addr<oop>((jint)byte_offset) == ptr_plus_disp,
"raw [ptr+disp] must be consistent with oop::field_base");
}
jlong p_size = HeapWordSize * (jlong)(p->size());
@@ -153,25 +154,29 @@
///// Data in the Java heap.
#define GET_FIELD(obj, offset, type_name, v) \
oop p = JNIHandles::resolve(obj); \
+ p = oopDesc::bs()->read_barrier(p); \
type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset)
#define SET_FIELD(obj, offset, type_name, x) \
oop p = JNIHandles::resolve(obj); \
+ p = oopDesc::bs()->write_barrier(p); \
*(type_name*)index_oop_from_field_offset_long(p, offset) = x
#define GET_FIELD_VOLATILE(obj, offset, type_name, v) \
oop p = JNIHandles::resolve(obj); \
+ p = oopDesc::bs()->read_barrier(p); \
if (support_IRIW_for_not_multiple_copy_atomic_cpu) { \
OrderAccess::fence(); \
} \
volatile type_name v = OrderAccess::load_acquire((volatile type_name*)index_oop_from_field_offset_long(p, offset));
#define SET_FIELD_VOLATILE(obj, offset, type_name, x) \
oop p = JNIHandles::resolve(obj); \
+ p = oopDesc::bs()->write_barrier(p); \
OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), x);
// Get/SetObject must be special-cased, since it works with handles.
@@ -179,10 +184,11 @@
// 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))
UnsafeWrapper("Unsafe_GetObject");
oop p = JNIHandles::resolve(obj);
+ p = oopDesc::bs()->read_barrier(p);
oop v;
if (UseCompressedOops) {
narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset);
v = oopDesc::decode_heap_oop(n);
} else {
@@ -191,11 +197,11 @@
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) {
+ if (UseG1GC || UseShenandoahGC) {
bool needs_barrier = false;
if (ret != NULL) {
if (offset == java_lang_ref_Reference::referent_offset && obj != NULL) {
oop o = JNIHandles::resolve(obj);
@@ -216,22 +222,23 @@
return ret;
UNSAFE_END
UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
UnsafeWrapper("Unsafe_SetObject");
- oop x = JNIHandles::resolve(x_h);
- oop p = JNIHandles::resolve(obj);
+ oop x = oopDesc::bs()->read_barrier(JNIHandles::resolve(x_h));
+ oop p = oopDesc::bs()->write_barrier(JNIHandles::resolve(obj));
if (UseCompressedOops) {
oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
} else {
oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
}
UNSAFE_END
UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
UnsafeWrapper("Unsafe_GetObjectVolatile");
oop p = JNIHandles::resolve(obj);
+ p = oopDesc::bs()->read_barrier(p);
void* addr = index_oop_from_field_offset_long(p, offset);
volatile oop v;
if (UseCompressedOops) {
volatile narrowOop n = *(volatile narrowOop*) addr;
(void)const_cast<oop&>(v = oopDesc::decode_heap_oop(n));
@@ -244,10 +251,12 @@
UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
UnsafeWrapper("Unsafe_SetObjectVolatile");
oop x = JNIHandles::resolve(x_h);
oop p = JNIHandles::resolve(obj);
+ x = oopDesc::bs()->read_barrier(x);
+ p = oopDesc::bs()->write_barrier(p);
void* addr = index_oop_from_field_offset_long(p, offset);
OrderAccess::release();
if (UseCompressedOops) {
oop_store((narrowOop*)addr, x);
} else {
@@ -310,11 +319,11 @@
if (VM_Version::supports_cx8()) {
GET_FIELD_VOLATILE(obj, offset, jlong, v);
return v;
}
else {
- Handle p (THREAD, JNIHandles::resolve(obj));
+ Handle p (THREAD, oopDesc::bs()->read_barrier(JNIHandles::resolve(obj)));
jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
jlong value = Atomic::load(addr);
return value;
}
@@ -326,11 +335,11 @@
{
if (VM_Version::supports_cx8()) {
SET_FIELD_VOLATILE(obj, offset, jlong, x);
}
else {
- Handle p (THREAD, JNIHandles::resolve(obj));
+ Handle p (THREAD, oopDesc::bs()->write_barrier(JNIHandles::resolve(obj)));
jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
Atomic::store(x, addr);
}
}
@@ -433,10 +442,12 @@
UNSAFE_ENTRY(void, Unsafe_SetOrderedObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
UnsafeWrapper("Unsafe_SetOrderedObject");
oop x = JNIHandles::resolve(x_h);
oop p = JNIHandles::resolve(obj);
+ x = oopDesc::bs()->read_barrier(x);
+ p = oopDesc::bs()->write_barrier(p);
void* addr = index_oop_from_field_offset_long(p, offset);
OrderAccess::release();
if (UseCompressedOops) {
oop_store((narrowOop*)addr, x);
} else {
@@ -454,11 +465,11 @@
{
if (VM_Version::supports_cx8()) {
SET_FIELD_VOLATILE(obj, offset, jlong, x);
}
else {
- Handle p (THREAD, JNIHandles::resolve(obj));
+ Handle p (THREAD, oopDesc::bs()->write_barrier(JNIHandles::resolve(obj)));
jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag);
Atomic::store(x, addr);
}
}
@@ -633,10 +644,11 @@
size_t sz = (size_t)size;
if (sz != (julong)size || size < 0) {
THROW(vmSymbols::java_lang_IllegalArgumentException());
}
oop base = JNIHandles::resolve(obj);
+ base = oopDesc::bs()->write_barrier(base);
void* p = index_oop_from_field_offset_long(base, offset);
Copy::fill_to_memory_atomic(p, sz, value);
UNSAFE_END
UNSAFE_ENTRY(void, Unsafe_CopyMemory(JNIEnv *env, jobject unsafe, jobject srcObj, jlong srcOffset, jobject dstObj, jlong dstOffset, jlong size))
@@ -648,10 +660,12 @@
if (sz != (julong)size || size < 0) {
THROW(vmSymbols::java_lang_IllegalArgumentException());
}
oop srcp = JNIHandles::resolve(srcObj);
oop dstp = JNIHandles::resolve(dstObj);
+ srcp = oopDesc::bs()->read_barrier(srcp);
+ dstp = oopDesc::bs()->write_barrier(dstp);
if (dstp != NULL && !dstp->is_typeArray()) {
// NYI: This works only for non-oop arrays at present.
// Generalizing it would be reasonable, but requires card marking.
// Also, autoboxing a Long from 0L in copyMemory(x,y, 0L,z, n) would be bad.
THROW(vmSymbols::java_lang_IllegalArgumentException());
@@ -1080,31 +1094,43 @@
// JSR166 ------------------------------------------------------------------
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h))
UnsafeWrapper("Unsafe_CompareAndSwapObject");
- oop x = JNIHandles::resolve(x_h);
- oop e = JNIHandles::resolve(e_h);
- oop p = JNIHandles::resolve(obj);
+ // We are about to write to this entry so check to see if we need to copy it.
+ oop p = oopDesc::bs()->write_barrier(JNIHandles::resolve(obj));
HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset);
- oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e, true);
- jboolean success = (res == e);
+ oop x = JNIHandles::resolve(x_h);
+ x = oopDesc::bs()->read_barrier(x);
+ oop old = JNIHandles::resolve(e_h);
+ jboolean success;
+ if (UseShenandoahGC) {
+ oop expected;
+ do {
+ expected = old;
+ old = oopDesc::atomic_compare_exchange_oop(x, addr, expected, true);
+ success = (old == expected);
+ } while ((! success) && oopDesc::bs()->read_barrier(old) == oopDesc::bs()->read_barrier(expected));
+ } else {
+ success = (old == oopDesc::atomic_compare_exchange_oop(x, addr, old, true));
+ }
if (success)
update_barrier_set((void*)addr, x);
return success;
UNSAFE_END
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))
UnsafeWrapper("Unsafe_CompareAndSwapInt");
- oop p = JNIHandles::resolve(obj);
+ // We are about to write to this entry so check to see if we need to copy it.
+ oop p = oopDesc::bs()->write_barrier(JNIHandles::resolve(obj));
jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
UNSAFE_END
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x))
UnsafeWrapper("Unsafe_CompareAndSwapLong");
- Handle p (THREAD, JNIHandles::resolve(obj));
+ Handle p (THREAD, oopDesc::bs()->write_barrier(JNIHandles::resolve(obj)));
jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
#ifdef SUPPORTS_NATIVE_CX8
return (jlong)(Atomic::cmpxchg(x, addr, e)) == e;
#else
if (VM_Version::supports_cx8())
< prev index next >