diff -r 13588c901957 -r 9cf78a70fa4f src/hotspot/share/prims/unsafe.cpp --- a/src/hotspot/share/prims/unsafe.cpp Thu Oct 17 20:27:44 2019 +0100 +++ b/src/hotspot/share/prims/unsafe.cpp Thu Oct 17 20:53:35 2019 +0100 @@ -44,6 +44,7 @@ #include "runtime/jniHandles.inline.hpp" #include "runtime/orderAccess.hpp" #include "runtime/reflection.hpp" +#include "runtime/sharedRuntime.hpp" #include "runtime/thread.hpp" #include "runtime/threadSMR.hpp" #include "runtime/vm_version.hpp" @@ -149,6 +150,25 @@ ///// 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. * * Normalizes values and wraps accesses in @@ -189,25 +209,6 @@ 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 +400,14 @@ 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 +423,11 @@ 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,11 +438,54 @@ 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 +UNSAFE_LEAF (void, Unsafe_WriteBack0(JNIEnv *env, jobject unsafe, jlong line)) { + assert(VM_Version::supports_data_cache_line_flush(), "should not get here"); +#ifdef ASSERT + if (TraceMemoryWriteback) { + tty->print_cr("Unsafe: writeback 0x%p", addr_from_java(line)); + } +#endif + + assert(StubRoutines::data_cache_writeback() != NULL, "sanity"); + (StubRoutines::DataCacheWriteback_stub())(addr_from_java(line)); +} UNSAFE_END + +static void doWriteBackSync0(bool is_pre) +{ + assert(StubRoutines::data_cache_writeback_sync() != NULL, "sanity"); + (StubRoutines::DataCacheWritebackSync_stub())(is_pre); +} + +UNSAFE_LEAF (void, Unsafe_WriteBackPreSync0(JNIEnv *env, jobject unsafe)) { + assert(VM_Version::supports_data_cache_line_flush(), "should not get here"); +#ifdef ASSERT + if (TraceMemoryWriteback) { + tty->print_cr("Unsafe: writeback pre-sync"); + } +#endif + + doWriteBackSync0(true); +} UNSAFE_END + +UNSAFE_LEAF (void, Unsafe_WriteBackPostSync0(JNIEnv *env, jobject unsafe)) { + assert(VM_Version::supports_data_cache_line_flush(), "should not get here"); +#ifdef ASSERT + if (TraceMemoryWriteback) { + tty->print_cr("Unsafe: writeback pre-sync"); + } +#endif + + doWriteBackSync0(false); +} UNSAFE_END + ////// Random queries static jlong find_field_offset(jclass clazz, jstring name, TRAPS) { @@ -615,7 +669,7 @@ ClassLoader::unsafe_defineClassCallCounter()->inc(); } - body = NEW_C_HEAP_ARRAY(jbyte, length, mtInternal); + body = NEW_C_HEAP_ARRAY_RETURN_NULL(jbyte, length, mtInternal); if (body == NULL) { throw_new(env, "java/lang/OutOfMemoryError"); return 0; @@ -631,7 +685,7 @@ int unicode_len = env->GetStringLength(name); if (len >= sizeof(buf)) { - utfName = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal); + utfName = NEW_C_HEAP_ARRAY_RETURN_NULL(char, len + 1, mtInternal); if (utfName == NULL) { throw_new(env, "java/lang/OutOfMemoryError"); goto free_body; @@ -736,7 +790,7 @@ int class_bytes_length = (int) length; - u1* class_bytes = NEW_C_HEAP_ARRAY(u1, length, mtInternal); + u1* class_bytes = NEW_C_HEAP_ARRAY_RETURN_NULL(u1, length, mtInternal); if (class_bytes == NULL) { THROW_0(vmSymbols::java_lang_OutOfMemoryError()); } @@ -821,9 +875,7 @@ } // try/finally clause: - if (temp_alloc != NULL) { - FREE_C_HEAP_ARRAY(u1, temp_alloc); - } + FREE_C_HEAP_ARRAY(u1, temp_alloc); // The anonymous class loader data has been artificially been kept alive to // this point. The mirror and any instances of this class have to keep @@ -883,7 +935,7 @@ oop p = JNIHandles::resolve(obj); assert_field_offset_sane(p, offset); oop ret = HeapAccess::oop_atomic_cmpxchg_at(x, p, (ptrdiff_t)offset, e); - return oopDesc::equals(ret, e); + return ret == e; } UNSAFE_END UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) { @@ -1060,6 +1112,9 @@ {CC "copyMemory0", CC "(" OBJ "J" OBJ "JJ)V", FN_PTR(Unsafe_CopyMemory0)}, {CC "copySwapMemory0", CC "(" OBJ "J" OBJ "JJJ)V", FN_PTR(Unsafe_CopySwapMemory0)}, + {CC "writeback0", CC "(" "J" ")V", FN_PTR(Unsafe_WriteBack0)}, + {CC "writebackPreSync0", CC "()V", FN_PTR(Unsafe_WriteBackPreSync0)}, + {CC "writebackPostSync0", CC "()V", FN_PTR(Unsafe_WriteBackPostSync0)}, {CC "setMemory0", CC "(" OBJ "JJB)V", FN_PTR(Unsafe_SetMemory0)}, {CC "defineAnonymousClass0", CC "(" DAC_Args ")" CLS, FN_PTR(Unsafe_DefineAnonymousClass0)},