8004318: JEP-171: Support Unsafe fences intrinsics
Summary: Add three memory-ordering intrinsics to the sun.misc.Unsafe class.
Reviewed-by: twisti, kvn
Contributed-by: Aleksey Shipilev <aleksey.shipilev@oracle.com>
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Tue Dec 18 10:47:23 2012 -0800
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Tue Dec 18 17:37:44 2012 -0800
@@ -3442,6 +3442,11 @@
preserves_state = true;
break;
+ case vmIntrinsics::_loadFence :
+ case vmIntrinsics::_storeFence:
+ case vmIntrinsics::_fullFence :
+ break;
+
default : return false; // do not inline
}
// create intrinsic node
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Tue Dec 18 10:47:23 2012 -0800
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Tue Dec 18 17:37:44 2012 -0800
@@ -2977,6 +2977,16 @@
do_CompareAndSwap(x, longType);
break;
+ case vmIntrinsics::_loadFence :
+ if (os::is_MP()) __ membar_acquire();
+ break;
+ case vmIntrinsics::_storeFence:
+ if (os::is_MP()) __ membar_release();
+ break;
+ case vmIntrinsics::_fullFence :
+ if (os::is_MP()) __ membar();
+ break;
+
case vmIntrinsics::_Reference_get:
do_Reference_get(x);
break;
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Tue Dec 18 10:47:23 2012 -0800
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Tue Dec 18 17:37:44 2012 -0800
@@ -756,6 +756,15 @@
do_intrinsic(_unpark, sun_misc_Unsafe, unpark_name, unpark_signature, F_RN) \
do_name( unpark_name, "unpark") \
do_alias( unpark_signature, /*(LObject;)V*/ object_void_signature) \
+ do_intrinsic(_loadFence, sun_misc_Unsafe, loadFence_name, loadFence_signature, F_RN) \
+ do_name( loadFence_name, "loadFence") \
+ do_alias( loadFence_signature, void_method_signature) \
+ do_intrinsic(_storeFence, sun_misc_Unsafe, storeFence_name, storeFence_signature, F_RN) \
+ do_name( storeFence_name, "storeFence") \
+ do_alias( storeFence_signature, void_method_signature) \
+ do_intrinsic(_fullFence, sun_misc_Unsafe, fullFence_name, fullFence_signature, F_RN) \
+ do_name( fullFence_name, "fullFence") \
+ do_alias( fullFence_signature, void_method_signature) \
\
/* unsafe memory references (there are a lot of them...) */ \
do_signature(getObject_signature, "(Ljava/lang/Object;J)Ljava/lang/Object;") \
--- a/hotspot/src/share/vm/opto/library_call.cpp Tue Dec 18 10:47:23 2012 -0800
+++ b/hotspot/src/share/vm/opto/library_call.cpp Tue Dec 18 17:37:44 2012 -0800
@@ -282,6 +282,7 @@
typedef enum { LS_xadd, LS_xchg, LS_cmpxchg } LoadStoreKind;
bool inline_unsafe_load_store(BasicType type, LoadStoreKind kind);
bool inline_unsafe_ordered_store(BasicType type);
+ bool inline_unsafe_fence(vmIntrinsics::ID id);
bool inline_fp_conversions(vmIntrinsics::ID id);
bool inline_number_methods(vmIntrinsics::ID id);
bool inline_reference_get();
@@ -334,6 +335,9 @@
case vmIntrinsics::_getAndSetInt:
case vmIntrinsics::_getAndSetLong:
case vmIntrinsics::_getAndSetObject:
+ case vmIntrinsics::_loadFence:
+ case vmIntrinsics::_storeFence:
+ case vmIntrinsics::_fullFence:
break; // InlineNatives does not control String.compareTo
case vmIntrinsics::_Reference_get:
break; // InlineNatives does not control Reference.get
@@ -732,6 +736,10 @@
case vmIntrinsics::_getAndSetLong: return inline_unsafe_load_store(T_LONG, LS_xchg);
case vmIntrinsics::_getAndSetObject: return inline_unsafe_load_store(T_OBJECT, LS_xchg);
+ case vmIntrinsics::_loadFence:
+ case vmIntrinsics::_storeFence:
+ case vmIntrinsics::_fullFence: return inline_unsafe_fence(intrinsic_id());
+
case vmIntrinsics::_currentThread: return inline_native_currentThread();
case vmIntrinsics::_isInterrupted: return inline_native_isInterrupted();
@@ -2840,6 +2848,26 @@
return true;
}
+bool LibraryCallKit::inline_unsafe_fence(vmIntrinsics::ID id) {
+ // Regardless of form, don't allow previous ld/st to move down,
+ // then issue acquire, release, or volatile mem_bar.
+ insert_mem_bar(Op_MemBarCPUOrder);
+ switch(id) {
+ case vmIntrinsics::_loadFence:
+ insert_mem_bar(Op_MemBarAcquire);
+ return true;
+ case vmIntrinsics::_storeFence:
+ insert_mem_bar(Op_MemBarRelease);
+ return true;
+ case vmIntrinsics::_fullFence:
+ insert_mem_bar(Op_MemBarVolatile);
+ return true;
+ default:
+ fatal_unexpected_iid(id);
+ return false;
+ }
+}
+
//----------------------------inline_unsafe_allocate---------------------------
// public native Object sun.mics.Unsafe.allocateInstance(Class<?> cls);
bool LibraryCallKit::inline_unsafe_allocate() {
--- a/hotspot/src/share/vm/prims/unsafe.cpp Tue Dec 18 10:47:23 2012 -0800
+++ b/hotspot/src/share/vm/prims/unsafe.cpp Tue Dec 18 17:37:44 2012 -0800
@@ -468,6 +468,21 @@
#endif
UNSAFE_END
+UNSAFE_ENTRY(void, Unsafe_LoadFence(JNIEnv *env, jobject unsafe))
+ UnsafeWrapper("Unsafe_LoadFence");
+ OrderAccess::acquire();
+UNSAFE_END
+
+UNSAFE_ENTRY(void, Unsafe_StoreFence(JNIEnv *env, jobject unsafe))
+ UnsafeWrapper("Unsafe_StoreFence");
+ OrderAccess::release();
+UNSAFE_END
+
+UNSAFE_ENTRY(void, Unsafe_FullFence(JNIEnv *env, jobject unsafe))
+ UnsafeWrapper("Unsafe_FullFence");
+ OrderAccess::fence();
+UNSAFE_END
+
////// Data in the C heap.
// Note: These do not throw NullPointerException for bad pointers.
@@ -1550,6 +1565,9 @@
{CC"putOrderedObject", CC"("OBJ"J"OBJ")V", FN_PTR(Unsafe_SetOrderedObject)},
{CC"putOrderedInt", CC"("OBJ"JI)V", FN_PTR(Unsafe_SetOrderedInt)},
{CC"putOrderedLong", CC"("OBJ"JJ)V", FN_PTR(Unsafe_SetOrderedLong)},
+ {CC"loadFence", CC"()V", FN_PTR(Unsafe_LoadFence)},
+ {CC"storeFence", CC"()V", FN_PTR(Unsafe_StoreFence)},
+ {CC"fullFence", CC"()V", FN_PTR(Unsafe_FullFence)},
{CC"park", CC"(ZJ)V", FN_PTR(Unsafe_Park)},
{CC"unpark", CC"("OBJ")V", FN_PTR(Unsafe_Unpark)}