--- 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<ON_UNKNOWN_OOP_REF>::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)},