< prev index next >
src/hotspot/share/prims/unsafe.cpp
Print this page
rev 48017 : 8186787: clang-4.0 SIGSEGV in Unsafe_PutByte
Reviewed-by: coleenp, dholmes
rev 48018 : imported patch Access_unsafe_mo_volatile_v2
@@ -144,31 +144,38 @@
* Helper class for accessing memory.
*
* Normalizes values and wraps accesses in
* JavaThread::doing_unsafe_access() if needed.
*/
+template <typename T>
class MemoryAccess : StackObj {
JavaThread* _thread;
oop _obj;
ptrdiff_t _offset;
- // Resolves and returns the address of the memory access
- void* addr() {
- return index_oop_from_field_offset_long(_obj, _offset);
+ // Resolves and returns the address of the memory access.
+ // This raw memory access may fault, so we make sure it happens within the
+ // guarded scope by making the access volatile at least. Since the store
+ // of Thread::set_doing_unsafe_access() is also volatile, these accesses
+ // can not be reordered by the compiler. Therefore, if the access triggers
+ // a fault, we will know that Thread::doing_unsafe_access() returns true.
+ volatile T* addr() {
+ void* addr = index_oop_from_field_offset_long(_obj, _offset);
+ return static_cast<volatile T*>(addr);
}
- template <typename T>
- T normalize_for_write(T x) {
+ template <typename U>
+ U normalize_for_write(U x) {
return x;
}
jboolean normalize_for_write(jboolean x) {
return x & 1;
}
- template <typename T>
- T normalize_for_read(T x) {
+ template <typename U>
+ U normalize_for_read(U x) {
return x;
}
jboolean normalize_for_read(jboolean x) {
return x != 0;
@@ -197,50 +204,46 @@
MemoryAccess(JavaThread* thread, jobject obj, jlong offset)
: _thread(thread), _obj(JNIHandles::resolve(obj)), _offset((ptrdiff_t)offset) {
assert_field_offset_sane(_obj, offset);
}
- template <typename T>
T get() {
if (oopDesc::is_null(_obj)) {
GuardUnsafeAccess guard(_thread);
- T ret = RawAccess<>::load((volatile T*)addr());
+ T ret = RawAccess<>::load(addr());
return normalize_for_read(ret);
} else {
T ret = HeapAccess<>::load_at(_obj, _offset);
return normalize_for_read(ret);
}
}
- template <typename T>
void put(T x) {
if (oopDesc::is_null(_obj)) {
GuardUnsafeAccess guard(_thread);
- RawAccess<>::store((volatile T*)addr(), normalize_for_write(x));
+ RawAccess<>::store(addr(), normalize_for_write(x));
} else {
HeapAccess<>::store_at(_obj, _offset, normalize_for_write(x));
}
}
- template <typename T>
T get_volatile() {
if (oopDesc::is_null(_obj)) {
GuardUnsafeAccess guard(_thread);
- volatile T ret = RawAccess<MO_SEQ_CST>::load((volatile T*)addr());
+ volatile T ret = RawAccess<MO_SEQ_CST>::load(addr());
return normalize_for_read(ret);
} else {
T ret = HeapAccess<MO_SEQ_CST>::load_at(_obj, _offset);
return normalize_for_read(ret);
}
}
- template <typename T>
void put_volatile(T x) {
if (oopDesc::is_null(_obj)) {
GuardUnsafeAccess guard(_thread);
- RawAccess<MO_SEQ_CST>::store((volatile T*)addr(), normalize_for_write(x));
+ RawAccess<MO_SEQ_CST>::store(addr(), normalize_for_write(x));
} else {
HeapAccess<MO_SEQ_CST>::store_at(_obj, _offset, normalize_for_write(x));
}
}
};
@@ -294,15 +297,15 @@
} UNSAFE_END
#define DEFINE_GETSETOOP(java_type, Type) \
\
UNSAFE_ENTRY(java_type, Unsafe_Get##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
- return MemoryAccess(thread, obj, offset).get<java_type>(); \
+ return MemoryAccess<java_type>(thread, obj, offset).get(); \
} UNSAFE_END \
\
UNSAFE_ENTRY(void, Unsafe_Put##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
- MemoryAccess(thread, obj, offset).put<java_type>(x); \
+ MemoryAccess<java_type>(thread, obj, offset).put(x); \
} UNSAFE_END \
\
// END DEFINE_GETSETOOP.
DEFINE_GETSETOOP(jboolean, Boolean)
@@ -317,15 +320,15 @@
#undef DEFINE_GETSETOOP
#define DEFINE_GETSETOOP_VOLATILE(java_type, Type) \
\
UNSAFE_ENTRY(java_type, Unsafe_Get##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \
- return MemoryAccess(thread, obj, offset).get_volatile<java_type>(); \
+ return MemoryAccess<java_type>(thread, obj, offset).get_volatile(); \
} UNSAFE_END \
\
UNSAFE_ENTRY(void, Unsafe_Put##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \
- MemoryAccess(thread, obj, offset).put_volatile<java_type>(x); \
+ MemoryAccess<java_type>(thread, obj, offset).put_volatile(x); \
} UNSAFE_END \
\
// END DEFINE_GETSETOOP_VOLATILE.
DEFINE_GETSETOOP_VOLATILE(jboolean, Boolean)
< prev index next >