8191278: MappedByteBuffer bulk access memory failures are not handled gracefully

Unsafe.copy*Memory access failures are handled gracefully.

Co-authored-by: Harold Seigel <harold.seigel@oracle.com>
Reviewed-by: kvn, dcubed, thartmann, coleenp, aph
This commit is contained in:
Jamsheed Mohammed C M 2019-06-24 11:37:56 -07:00
parent 4a7e2b57ea
commit aedbb75803
26 changed files with 1827 additions and 1242 deletions

View file

@ -148,6 +148,25 @@ jlong Unsafe_field_offset_from_byte_offset(jlong byte_offset) {
///// Data read/writes on the Java heap and in native (off-heap) memory
/**
* Helper class to wrap memory accesses in JavaThread::doing_unsafe_access()
*/
class GuardUnsafeAccess {
JavaThread* _thread;
public:
GuardUnsafeAccess(JavaThread* thread) : _thread(thread) {
// native/off-heap access which may raise SIGBUS if accessing
// memory mapped file data in a region of the file which has
// been truncated and is now invalid.
_thread->set_doing_unsafe_access(true);
}
~GuardUnsafeAccess() {
_thread->set_doing_unsafe_access(false);
}
};
/**
* Helper class for accessing memory.
*
@ -189,25 +208,6 @@ class MemoryAccess : StackObj {
return x != 0;
}
/**
* Helper class to wrap memory accesses in JavaThread::doing_unsafe_access()
*/
class GuardUnsafeAccess {
JavaThread* _thread;
public:
GuardUnsafeAccess(JavaThread* thread) : _thread(thread) {
// native/off-heap access which may raise SIGBUS if accessing
// memory mapped file data in a region of the file which has
// been truncated and is now invalid
_thread->set_doing_unsafe_access(true);
}
~GuardUnsafeAccess() {
_thread->set_doing_unsafe_access(false);
}
};
public:
MemoryAccess(JavaThread* thread, jobject obj, jlong offset)
: _thread(thread), _obj(JNIHandles::resolve(obj)), _offset((ptrdiff_t)offset) {
@ -399,8 +399,14 @@ UNSAFE_ENTRY(void, Unsafe_CopyMemory0(JNIEnv *env, jobject unsafe, jobject srcOb
void* src = index_oop_from_field_offset_long(srcp, srcOffset);
void* dst = index_oop_from_field_offset_long(dstp, dstOffset);
Copy::conjoint_memory_atomic(src, dst, sz);
{
GuardUnsafeAccess guard(thread);
if (StubRoutines::unsafe_arraycopy() != NULL) {
StubRoutines::UnsafeArrayCopy_stub()(src, dst, sz);
} else {
Copy::conjoint_memory_atomic(src, dst, sz);
}
}
} UNSAFE_END
// This function is a leaf since if the source and destination are both in native memory
@ -416,7 +422,11 @@ UNSAFE_LEAF(void, Unsafe_CopySwapMemory0(JNIEnv *env, jobject unsafe, jobject sr
address src = (address)srcOffset;
address dst = (address)dstOffset;
Copy::conjoint_swap(src, dst, sz, esz);
{
JavaThread* thread = JavaThread::thread_from_jni_environment(env);
GuardUnsafeAccess guard(thread);
Copy::conjoint_swap(src, dst, sz, esz);
}
} else {
// At least one of src/dst are on heap, transition to VM to access raw pointers
@ -427,7 +437,10 @@ UNSAFE_LEAF(void, Unsafe_CopySwapMemory0(JNIEnv *env, jobject unsafe, jobject sr
address src = (address)index_oop_from_field_offset_long(srcp, srcOffset);
address dst = (address)index_oop_from_field_offset_long(dstp, dstOffset);
Copy::conjoint_swap(src, dst, sz, esz);
{
GuardUnsafeAccess guard(thread);
Copy::conjoint_swap(src, dst, sz, esz);
}
} JVM_END
}
} UNSAFE_END