From 9688a4eb5cda356aabca374bdbc2cb1b8686e740 Mon Sep 17 00:00:00 2001 From: kvn Date: Tue, 18 Dec 2012 17:37:44 -0800 Subject: [PATCH] 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 --- src/share/vm/c1/c1_GraphBuilder.cpp | 5 +++++ src/share/vm/c1/c1_LIRGenerator.cpp | 10 ++++++++++ src/share/vm/classfile/vmSymbols.hpp | 9 +++++++++ src/share/vm/opto/library_call.cpp | 28 ++++++++++++++++++++++++++++ src/share/vm/prims/unsafe.cpp | 18 ++++++++++++++++++ 5 files changed, 70 insertions(+) diff --git a/src/share/vm/c1/c1_GraphBuilder.cpp b/src/share/vm/c1/c1_GraphBuilder.cpp index 70b691575..85c3aa1c9 100644 --- a/src/share/vm/c1/c1_GraphBuilder.cpp +++ b/src/share/vm/c1/c1_GraphBuilder.cpp @@ -3442,6 +3442,11 @@ bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) { preserves_state = true; break; + case vmIntrinsics::_loadFence : + case vmIntrinsics::_storeFence: + case vmIntrinsics::_fullFence : + break; + default : return false; // do not inline } // create intrinsic node diff --git a/src/share/vm/c1/c1_LIRGenerator.cpp b/src/share/vm/c1/c1_LIRGenerator.cpp index cf865f1b5..65bc34e3d 100644 --- a/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/src/share/vm/c1/c1_LIRGenerator.cpp @@ -2977,6 +2977,16 @@ void LIRGenerator::do_Intrinsic(Intrinsic* x) { 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; diff --git a/src/share/vm/classfile/vmSymbols.hpp b/src/share/vm/classfile/vmSymbols.hpp index 940aac3c2..530df9660 100644 --- a/src/share/vm/classfile/vmSymbols.hpp +++ b/src/share/vm/classfile/vmSymbols.hpp @@ -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;") \ diff --git a/src/share/vm/opto/library_call.cpp b/src/share/vm/opto/library_call.cpp index ff979d655..313339edf 100644 --- a/src/share/vm/opto/library_call.cpp +++ b/src/share/vm/opto/library_call.cpp @@ -282,6 +282,7 @@ class LibraryCallKit : public GraphKit { 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 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { 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 @@ bool LibraryCallKit::try_to_inline() { 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 @@ bool LibraryCallKit::inline_unsafe_ordered_store(BasicType type) { 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() { diff --git a/src/share/vm/prims/unsafe.cpp b/src/share/vm/prims/unsafe.cpp index cb7f0fcf3..e56277b65 100644 --- a/src/share/vm/prims/unsafe.cpp +++ b/src/share/vm/prims/unsafe.cpp @@ -468,6 +468,21 @@ UNSAFE_ENTRY(void, Unsafe_SetOrderedLong(JNIEnv *env, jobject unsafe, jobject ob #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 @@ static JNINativeMethod methods[] = { {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)} -- GitLab