# HG changeset patch # User mikael # Date 1462575566 25200 # Node ID fe30fdab0f62fe88f528d1926b0eebf99e9f8e76 # Parent b2a58604e0467aefc140100ac69fc931b7ead2ae 8150921: Update Unsafe getters/setters to use double-register variants Reviewed-by: dholmes, shade, psandoz, jrose diff -r b2a58604e046 -r fe30fdab0f62 hotspot/src/share/vm/c1/c1_Compiler.cpp --- a/hotspot/src/share/vm/c1/c1_Compiler.cpp Fri May 06 13:00:21 2016 -0700 +++ b/hotspot/src/share/vm/c1/c1_Compiler.cpp Fri May 06 15:59:26 2016 -0700 @@ -198,20 +198,6 @@ case vmIntrinsics::_putLongVolatile: case vmIntrinsics::_putFloatVolatile: case vmIntrinsics::_putDoubleVolatile: - case vmIntrinsics::_getByte_raw: - case vmIntrinsics::_getShort_raw: - case vmIntrinsics::_getChar_raw: - case vmIntrinsics::_getInt_raw: - case vmIntrinsics::_getLong_raw: - case vmIntrinsics::_getFloat_raw: - case vmIntrinsics::_getDouble_raw: - case vmIntrinsics::_putByte_raw: - case vmIntrinsics::_putShort_raw: - case vmIntrinsics::_putChar_raw: - case vmIntrinsics::_putInt_raw: - case vmIntrinsics::_putLong_raw: - case vmIntrinsics::_putFloat_raw: - case vmIntrinsics::_putDouble_raw: case vmIntrinsics::_getShortUnaligned: case vmIntrinsics::_getCharUnaligned: case vmIntrinsics::_getIntUnaligned: diff -r b2a58604e046 -r fe30fdab0f62 hotspot/src/share/vm/c1/c1_GraphBuilder.cpp --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri May 06 13:00:21 2016 -0700 +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri May 06 15:59:26 2016 -0700 @@ -3465,20 +3465,6 @@ case vmIntrinsics::_putLongVolatile : append_unsafe_put_obj(callee, T_LONG, true); return; case vmIntrinsics::_putFloatVolatile : append_unsafe_put_obj(callee, T_FLOAT, true); return; case vmIntrinsics::_putDoubleVolatile : append_unsafe_put_obj(callee, T_DOUBLE, true); return; - case vmIntrinsics::_getByte_raw : append_unsafe_get_raw(callee, T_BYTE ); return; - case vmIntrinsics::_getShort_raw : append_unsafe_get_raw(callee, T_SHORT ); return; - case vmIntrinsics::_getChar_raw : append_unsafe_get_raw(callee, T_CHAR ); return; - case vmIntrinsics::_getInt_raw : append_unsafe_get_raw(callee, T_INT ); return; - case vmIntrinsics::_getLong_raw : append_unsafe_get_raw(callee, T_LONG ); return; - case vmIntrinsics::_getFloat_raw : append_unsafe_get_raw(callee, T_FLOAT ); return; - case vmIntrinsics::_getDouble_raw : append_unsafe_get_raw(callee, T_DOUBLE); return; - case vmIntrinsics::_putByte_raw : append_unsafe_put_raw(callee, T_BYTE ); return; - case vmIntrinsics::_putShort_raw : append_unsafe_put_raw(callee, T_SHORT ); return; - case vmIntrinsics::_putChar_raw : append_unsafe_put_raw(callee, T_CHAR ); return; - case vmIntrinsics::_putInt_raw : append_unsafe_put_raw(callee, T_INT ); return; - case vmIntrinsics::_putLong_raw : append_unsafe_put_raw(callee, T_LONG ); return; - case vmIntrinsics::_putFloat_raw : append_unsafe_put_raw(callee, T_FLOAT ); return; - case vmIntrinsics::_putDouble_raw : append_unsafe_put_raw(callee, T_DOUBLE); return; case vmIntrinsics::_compareAndSwapLong: case vmIntrinsics::_compareAndSwapInt: case vmIntrinsics::_compareAndSwapObject: append_unsafe_CAS(callee); return; diff -r b2a58604e046 -r fe30fdab0f62 hotspot/src/share/vm/classfile/vmSymbols.cpp --- a/hotspot/src/share/vm/classfile/vmSymbols.cpp Fri May 06 13:00:21 2016 -0700 +++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp Fri May 06 15:59:26 2016 -0700 @@ -578,20 +578,6 @@ case vmIntrinsics::_putLongOpaque: case vmIntrinsics::_putFloatOpaque: case vmIntrinsics::_putDoubleOpaque: - case vmIntrinsics::_getByte_raw: - case vmIntrinsics::_getShort_raw: - case vmIntrinsics::_getChar_raw: - case vmIntrinsics::_getInt_raw: - case vmIntrinsics::_getLong_raw: - case vmIntrinsics::_getFloat_raw: - case vmIntrinsics::_getDouble_raw: - case vmIntrinsics::_putByte_raw: - case vmIntrinsics::_putShort_raw: - case vmIntrinsics::_putChar_raw: - case vmIntrinsics::_putInt_raw: - case vmIntrinsics::_putLong_raw: - case vmIntrinsics::_putFloat_raw: - case vmIntrinsics::_putDouble_raw: case vmIntrinsics::_getAndAddInt: case vmIntrinsics::_getAndAddLong: case vmIntrinsics::_getAndSetInt: @@ -632,8 +618,6 @@ case vmIntrinsics::_putIntUnaligned: case vmIntrinsics::_putLongUnaligned: case vmIntrinsics::_allocateInstance: - case vmIntrinsics::_getAddress_raw: - case vmIntrinsics::_putAddress_raw: if (!InlineUnsafeOps || !UseUnalignedAccesses) return true; break; case vmIntrinsics::_hashCode: diff -r b2a58604e046 -r fe30fdab0f62 hotspot/src/share/vm/classfile/vmSymbols.hpp --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Fri May 06 13:00:21 2016 -0700 +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Fri May 06 15:59:26 2016 -0700 @@ -1231,43 +1231,6 @@ do_intrinsic(_putIntUnaligned, jdk_internal_misc_Unsafe, putIntUnaligned_name, putInt_signature, F_R) \ do_intrinsic(_putLongUnaligned, jdk_internal_misc_Unsafe, putLongUnaligned_name, putLong_signature, F_R) \ \ - /* %%% these are redundant except perhaps for getAddress, but Unsafe has native methods for them */ \ - do_signature(getByte_raw_signature, "(J)B") \ - do_signature(putByte_raw_signature, "(JB)V") \ - do_signature(getShort_raw_signature, "(J)S") \ - do_signature(putShort_raw_signature, "(JS)V") \ - do_signature(getChar_raw_signature, "(J)C") \ - do_signature(putChar_raw_signature, "(JC)V") \ - do_signature(putInt_raw_signature, "(JI)V") \ - do_alias(getLong_raw_signature, /*(J)J*/ long_long_signature) \ - do_alias(putLong_raw_signature, /*(JJ)V*/ long_long_void_signature) \ - do_signature(getFloat_raw_signature, "(J)F") \ - do_signature(putFloat_raw_signature, "(JF)V") \ - do_alias(getDouble_raw_signature, /*(J)D*/ long_double_signature) \ - do_signature(putDouble_raw_signature, "(JD)V") \ - do_alias(getAddress_raw_signature, /*(J)J*/ long_long_signature) \ - do_alias(putAddress_raw_signature, /*(JJ)V*/ long_long_void_signature) \ - \ - do_name( getAddress_name, "getAddress") \ - do_name( putAddress_name, "putAddress") \ - \ - do_intrinsic(_getByte_raw, jdk_internal_misc_Unsafe, getByte_name, getByte_raw_signature, F_R) \ - do_intrinsic(_getShort_raw, jdk_internal_misc_Unsafe, getShort_name, getShort_raw_signature, F_R) \ - do_intrinsic(_getChar_raw, jdk_internal_misc_Unsafe, getChar_name, getChar_raw_signature, F_R) \ - do_intrinsic(_getInt_raw, jdk_internal_misc_Unsafe, getInt_name, long_int_signature, F_R) \ - do_intrinsic(_getLong_raw, jdk_internal_misc_Unsafe, getLong_name, getLong_raw_signature, F_R) \ - do_intrinsic(_getFloat_raw, jdk_internal_misc_Unsafe, getFloat_name, getFloat_raw_signature, F_R) \ - do_intrinsic(_getDouble_raw, jdk_internal_misc_Unsafe, getDouble_name, getDouble_raw_signature, F_R) \ - do_intrinsic(_getAddress_raw, jdk_internal_misc_Unsafe, getAddress_name, getAddress_raw_signature, F_R) \ - do_intrinsic(_putByte_raw, jdk_internal_misc_Unsafe, putByte_name, putByte_raw_signature, F_R) \ - do_intrinsic(_putShort_raw, jdk_internal_misc_Unsafe, putShort_name, putShort_raw_signature, F_R) \ - do_intrinsic(_putChar_raw, jdk_internal_misc_Unsafe, putChar_name, putChar_raw_signature, F_R) \ - do_intrinsic(_putInt_raw, jdk_internal_misc_Unsafe, putInt_name, putInt_raw_signature, F_R) \ - do_intrinsic(_putLong_raw, jdk_internal_misc_Unsafe, putLong_name, putLong_raw_signature, F_R) \ - do_intrinsic(_putFloat_raw, jdk_internal_misc_Unsafe, putFloat_name, putFloat_raw_signature, F_R) \ - do_intrinsic(_putDouble_raw, jdk_internal_misc_Unsafe, putDouble_name, putDouble_raw_signature, F_R) \ - do_intrinsic(_putAddress_raw, jdk_internal_misc_Unsafe, putAddress_name, putAddress_raw_signature, F_R) \ - \ do_signature(compareAndSwapObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z") \ do_signature(compareAndExchangeObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;") \ do_signature(compareAndSwapLong_signature, "(Ljava/lang/Object;JJJ)Z") \ diff -r b2a58604e046 -r fe30fdab0f62 hotspot/src/share/vm/opto/c2compiler.cpp --- a/hotspot/src/share/vm/opto/c2compiler.cpp Fri May 06 13:00:21 2016 -0700 +++ b/hotspot/src/share/vm/opto/c2compiler.cpp Fri May 06 15:59:26 2016 -0700 @@ -409,22 +409,6 @@ case vmIntrinsics::_putLong: case vmIntrinsics::_putFloat: case vmIntrinsics::_putDouble: - case vmIntrinsics::_getByte_raw: - case vmIntrinsics::_getShort_raw: - case vmIntrinsics::_getChar_raw: - case vmIntrinsics::_getInt_raw: - case vmIntrinsics::_getLong_raw: - case vmIntrinsics::_getFloat_raw: - case vmIntrinsics::_getDouble_raw: - case vmIntrinsics::_getAddress_raw: - case vmIntrinsics::_putByte_raw: - case vmIntrinsics::_putShort_raw: - case vmIntrinsics::_putChar_raw: - case vmIntrinsics::_putInt_raw: - case vmIntrinsics::_putLong_raw: - case vmIntrinsics::_putFloat_raw: - case vmIntrinsics::_putDouble_raw: - case vmIntrinsics::_putAddress_raw: case vmIntrinsics::_getObjectVolatile: case vmIntrinsics::_getBooleanVolatile: case vmIntrinsics::_getByteVolatile: diff -r b2a58604e046 -r fe30fdab0f62 hotspot/src/share/vm/opto/library_call.cpp --- a/hotspot/src/share/vm/opto/library_call.cpp Fri May 06 13:00:21 2016 -0700 +++ b/hotspot/src/share/vm/opto/library_call.cpp Fri May 06 15:59:26 2016 -0700 @@ -93,7 +93,7 @@ Node* _result; // the result node, if any int _reexecute_sp; // the stack pointer when bytecode needs to be reexecuted - const TypeOopPtr* sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type, bool is_native_ptr = false); + const TypeOopPtr* sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type); public: LibraryCallKit(JVMState* jvms, LibraryIntrinsic* intrinsic) @@ -247,7 +247,7 @@ void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar); typedef enum { Relaxed, Opaque, Volatile, Acquire, Release } AccessKind; - bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, AccessKind kind, bool is_unaligned); + bool inline_unsafe_access(bool is_store, BasicType type, AccessKind kind, bool is_unaligned); static bool klass_needs_init_guard(Node* kls); bool inline_unsafe_allocate(); bool inline_unsafe_newArray(bool uninitialized); @@ -475,7 +475,6 @@ // Handle symbolic names for otherwise undistinguished boolean switches: const bool is_store = true; const bool is_compress = true; - const bool is_native_ptr = true; const bool is_static = true; const bool is_volatile = true; @@ -555,113 +554,95 @@ case vmIntrinsics::_inflateStringC: case vmIntrinsics::_inflateStringB: return inline_string_copy(!is_compress); - case vmIntrinsics::_getObject: return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, Relaxed, false); - case vmIntrinsics::_getBoolean: return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, Relaxed, false); - case vmIntrinsics::_getByte: return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE, Relaxed, false); - case vmIntrinsics::_getShort: return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT, Relaxed, false); - case vmIntrinsics::_getChar: return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, Relaxed, false); - case vmIntrinsics::_getInt: return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, Relaxed, false); - case vmIntrinsics::_getLong: return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, Relaxed, false); - case vmIntrinsics::_getFloat: return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT, Relaxed, false); - case vmIntrinsics::_getDouble: return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE, Relaxed, false); - - case vmIntrinsics::_putObject: return inline_unsafe_access(!is_native_ptr, is_store, T_OBJECT, Relaxed, false); - case vmIntrinsics::_putBoolean: return inline_unsafe_access(!is_native_ptr, is_store, T_BOOLEAN, Relaxed, false); - case vmIntrinsics::_putByte: return inline_unsafe_access(!is_native_ptr, is_store, T_BYTE, Relaxed, false); - case vmIntrinsics::_putShort: return inline_unsafe_access(!is_native_ptr, is_store, T_SHORT, Relaxed, false); - case vmIntrinsics::_putChar: return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, Relaxed, false); - case vmIntrinsics::_putInt: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, Relaxed, false); - case vmIntrinsics::_putLong: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, Relaxed, false); - case vmIntrinsics::_putFloat: return inline_unsafe_access(!is_native_ptr, is_store, T_FLOAT, Relaxed, false); - case vmIntrinsics::_putDouble: return inline_unsafe_access(!is_native_ptr, is_store, T_DOUBLE, Relaxed, false); - - case vmIntrinsics::_getByte_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_BYTE, Relaxed, false); - case vmIntrinsics::_getShort_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_SHORT, Relaxed, false); - case vmIntrinsics::_getChar_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_CHAR, Relaxed, false); - case vmIntrinsics::_getInt_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_INT, Relaxed, false); - case vmIntrinsics::_getLong_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_LONG, Relaxed, false); - case vmIntrinsics::_getFloat_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_FLOAT, Relaxed, false); - case vmIntrinsics::_getDouble_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_DOUBLE, Relaxed, false); - case vmIntrinsics::_getAddress_raw: return inline_unsafe_access( is_native_ptr, !is_store, T_ADDRESS, Relaxed, false); - - case vmIntrinsics::_putByte_raw: return inline_unsafe_access( is_native_ptr, is_store, T_BYTE, Relaxed, false); - case vmIntrinsics::_putShort_raw: return inline_unsafe_access( is_native_ptr, is_store, T_SHORT, Relaxed, false); - case vmIntrinsics::_putChar_raw: return inline_unsafe_access( is_native_ptr, is_store, T_CHAR, Relaxed, false); - case vmIntrinsics::_putInt_raw: return inline_unsafe_access( is_native_ptr, is_store, T_INT, Relaxed, false); - case vmIntrinsics::_putLong_raw: return inline_unsafe_access( is_native_ptr, is_store, T_LONG, Relaxed, false); - case vmIntrinsics::_putFloat_raw: return inline_unsafe_access( is_native_ptr, is_store, T_FLOAT, Relaxed, false); - case vmIntrinsics::_putDouble_raw: return inline_unsafe_access( is_native_ptr, is_store, T_DOUBLE, Relaxed, false); - case vmIntrinsics::_putAddress_raw: return inline_unsafe_access( is_native_ptr, is_store, T_ADDRESS, Relaxed, false); - - case vmIntrinsics::_getObjectVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, Volatile, false); - case vmIntrinsics::_getBooleanVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, Volatile, false); - case vmIntrinsics::_getByteVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE, Volatile, false); - case vmIntrinsics::_getShortVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT, Volatile, false); - case vmIntrinsics::_getCharVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, Volatile, false); - case vmIntrinsics::_getIntVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, Volatile, false); - case vmIntrinsics::_getLongVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, Volatile, false); - case vmIntrinsics::_getFloatVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT, Volatile, false); - case vmIntrinsics::_getDoubleVolatile: return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE, Volatile, false); - - case vmIntrinsics::_putObjectVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_OBJECT, Volatile, false); - case vmIntrinsics::_putBooleanVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_BOOLEAN, Volatile, false); - case vmIntrinsics::_putByteVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_BYTE, Volatile, false); - case vmIntrinsics::_putShortVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_SHORT, Volatile, false); - case vmIntrinsics::_putCharVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, Volatile, false); - case vmIntrinsics::_putIntVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, Volatile, false); - case vmIntrinsics::_putLongVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, Volatile, false); - case vmIntrinsics::_putFloatVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_FLOAT, Volatile, false); - case vmIntrinsics::_putDoubleVolatile: return inline_unsafe_access(!is_native_ptr, is_store, T_DOUBLE, Volatile, false); - - case vmIntrinsics::_getShortUnaligned: return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT, Relaxed, true); - case vmIntrinsics::_getCharUnaligned: return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, Relaxed, true); - case vmIntrinsics::_getIntUnaligned: return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, Relaxed, true); - case vmIntrinsics::_getLongUnaligned: return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, Relaxed, true); - - case vmIntrinsics::_putShortUnaligned: return inline_unsafe_access(!is_native_ptr, is_store, T_SHORT, Relaxed, true); - case vmIntrinsics::_putCharUnaligned: return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, Relaxed, true); - case vmIntrinsics::_putIntUnaligned: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, Relaxed, true); - case vmIntrinsics::_putLongUnaligned: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, Relaxed, true); - - case vmIntrinsics::_getObjectAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, Acquire, false); - case vmIntrinsics::_getBooleanAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, Acquire, false); - case vmIntrinsics::_getByteAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE, Acquire, false); - case vmIntrinsics::_getShortAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT, Acquire, false); - case vmIntrinsics::_getCharAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, Acquire, false); - case vmIntrinsics::_getIntAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, Acquire, false); - case vmIntrinsics::_getLongAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, Acquire, false); - case vmIntrinsics::_getFloatAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT, Acquire, false); - case vmIntrinsics::_getDoubleAcquire: return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE, Acquire, false); - - case vmIntrinsics::_putObjectRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_OBJECT, Release, false); - case vmIntrinsics::_putBooleanRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_BOOLEAN, Release, false); - case vmIntrinsics::_putByteRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_BYTE, Release, false); - case vmIntrinsics::_putShortRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_SHORT, Release, false); - case vmIntrinsics::_putCharRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, Release, false); - case vmIntrinsics::_putIntRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, Release, false); - case vmIntrinsics::_putLongRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, Release, false); - case vmIntrinsics::_putFloatRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_FLOAT, Release, false); - case vmIntrinsics::_putDoubleRelease: return inline_unsafe_access(!is_native_ptr, is_store, T_DOUBLE, Release, false); - - case vmIntrinsics::_getObjectOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, Opaque, false); - case vmIntrinsics::_getBooleanOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, Opaque, false); - case vmIntrinsics::_getByteOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE, Opaque, false); - case vmIntrinsics::_getShortOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT, Opaque, false); - case vmIntrinsics::_getCharOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR, Opaque, false); - case vmIntrinsics::_getIntOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_INT, Opaque, false); - case vmIntrinsics::_getLongOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, Opaque, false); - case vmIntrinsics::_getFloatOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT, Opaque, false); - case vmIntrinsics::_getDoubleOpaque: return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE, Opaque, false); - - case vmIntrinsics::_putObjectOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_OBJECT, Opaque, false); - case vmIntrinsics::_putBooleanOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_BOOLEAN, Opaque, false); - case vmIntrinsics::_putByteOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_BYTE, Opaque, false); - case vmIntrinsics::_putShortOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_SHORT, Opaque, false); - case vmIntrinsics::_putCharOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_CHAR, Opaque, false); - case vmIntrinsics::_putIntOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_INT, Opaque, false); - case vmIntrinsics::_putLongOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_LONG, Opaque, false); - case vmIntrinsics::_putFloatOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_FLOAT, Opaque, false); - case vmIntrinsics::_putDoubleOpaque: return inline_unsafe_access(!is_native_ptr, is_store, T_DOUBLE, Opaque, false); + case vmIntrinsics::_getObject: return inline_unsafe_access(!is_store, T_OBJECT, Relaxed, false); + case vmIntrinsics::_getBoolean: return inline_unsafe_access(!is_store, T_BOOLEAN, Relaxed, false); + case vmIntrinsics::_getByte: return inline_unsafe_access(!is_store, T_BYTE, Relaxed, false); + case vmIntrinsics::_getShort: return inline_unsafe_access(!is_store, T_SHORT, Relaxed, false); + case vmIntrinsics::_getChar: return inline_unsafe_access(!is_store, T_CHAR, Relaxed, false); + case vmIntrinsics::_getInt: return inline_unsafe_access(!is_store, T_INT, Relaxed, false); + case vmIntrinsics::_getLong: return inline_unsafe_access(!is_store, T_LONG, Relaxed, false); + case vmIntrinsics::_getFloat: return inline_unsafe_access(!is_store, T_FLOAT, Relaxed, false); + case vmIntrinsics::_getDouble: return inline_unsafe_access(!is_store, T_DOUBLE, Relaxed, false); + + case vmIntrinsics::_putObject: return inline_unsafe_access( is_store, T_OBJECT, Relaxed, false); + case vmIntrinsics::_putBoolean: return inline_unsafe_access( is_store, T_BOOLEAN, Relaxed, false); + case vmIntrinsics::_putByte: return inline_unsafe_access( is_store, T_BYTE, Relaxed, false); + case vmIntrinsics::_putShort: return inline_unsafe_access( is_store, T_SHORT, Relaxed, false); + case vmIntrinsics::_putChar: return inline_unsafe_access( is_store, T_CHAR, Relaxed, false); + case vmIntrinsics::_putInt: return inline_unsafe_access( is_store, T_INT, Relaxed, false); + case vmIntrinsics::_putLong: return inline_unsafe_access( is_store, T_LONG, Relaxed, false); + case vmIntrinsics::_putFloat: return inline_unsafe_access( is_store, T_FLOAT, Relaxed, false); + case vmIntrinsics::_putDouble: return inline_unsafe_access( is_store, T_DOUBLE, Relaxed, false); + + case vmIntrinsics::_getObjectVolatile: return inline_unsafe_access(!is_store, T_OBJECT, Volatile, false); + case vmIntrinsics::_getBooleanVolatile: return inline_unsafe_access(!is_store, T_BOOLEAN, Volatile, false); + case vmIntrinsics::_getByteVolatile: return inline_unsafe_access(!is_store, T_BYTE, Volatile, false); + case vmIntrinsics::_getShortVolatile: return inline_unsafe_access(!is_store, T_SHORT, Volatile, false); + case vmIntrinsics::_getCharVolatile: return inline_unsafe_access(!is_store, T_CHAR, Volatile, false); + case vmIntrinsics::_getIntVolatile: return inline_unsafe_access(!is_store, T_INT, Volatile, false); + case vmIntrinsics::_getLongVolatile: return inline_unsafe_access(!is_store, T_LONG, Volatile, false); + case vmIntrinsics::_getFloatVolatile: return inline_unsafe_access(!is_store, T_FLOAT, Volatile, false); + case vmIntrinsics::_getDoubleVolatile: return inline_unsafe_access(!is_store, T_DOUBLE, Volatile, false); + + case vmIntrinsics::_putObjectVolatile: return inline_unsafe_access( is_store, T_OBJECT, Volatile, false); + case vmIntrinsics::_putBooleanVolatile: return inline_unsafe_access( is_store, T_BOOLEAN, Volatile, false); + case vmIntrinsics::_putByteVolatile: return inline_unsafe_access( is_store, T_BYTE, Volatile, false); + case vmIntrinsics::_putShortVolatile: return inline_unsafe_access( is_store, T_SHORT, Volatile, false); + case vmIntrinsics::_putCharVolatile: return inline_unsafe_access( is_store, T_CHAR, Volatile, false); + case vmIntrinsics::_putIntVolatile: return inline_unsafe_access( is_store, T_INT, Volatile, false); + case vmIntrinsics::_putLongVolatile: return inline_unsafe_access( is_store, T_LONG, Volatile, false); + case vmIntrinsics::_putFloatVolatile: return inline_unsafe_access( is_store, T_FLOAT, Volatile, false); + case vmIntrinsics::_putDoubleVolatile: return inline_unsafe_access( is_store, T_DOUBLE, Volatile, false); + + case vmIntrinsics::_getShortUnaligned: return inline_unsafe_access(!is_store, T_SHORT, Relaxed, true); + case vmIntrinsics::_getCharUnaligned: return inline_unsafe_access(!is_store, T_CHAR, Relaxed, true); + case vmIntrinsics::_getIntUnaligned: return inline_unsafe_access(!is_store, T_INT, Relaxed, true); + case vmIntrinsics::_getLongUnaligned: return inline_unsafe_access(!is_store, T_LONG, Relaxed, true); + + case vmIntrinsics::_putShortUnaligned: return inline_unsafe_access( is_store, T_SHORT, Relaxed, true); + case vmIntrinsics::_putCharUnaligned: return inline_unsafe_access( is_store, T_CHAR, Relaxed, true); + case vmIntrinsics::_putIntUnaligned: return inline_unsafe_access( is_store, T_INT, Relaxed, true); + case vmIntrinsics::_putLongUnaligned: return inline_unsafe_access( is_store, T_LONG, Relaxed, true); + + case vmIntrinsics::_getObjectAcquire: return inline_unsafe_access(!is_store, T_OBJECT, Acquire, false); + case vmIntrinsics::_getBooleanAcquire: return inline_unsafe_access(!is_store, T_BOOLEAN, Acquire, false); + case vmIntrinsics::_getByteAcquire: return inline_unsafe_access(!is_store, T_BYTE, Acquire, false); + case vmIntrinsics::_getShortAcquire: return inline_unsafe_access(!is_store, T_SHORT, Acquire, false); + case vmIntrinsics::_getCharAcquire: return inline_unsafe_access(!is_store, T_CHAR, Acquire, false); + case vmIntrinsics::_getIntAcquire: return inline_unsafe_access(!is_store, T_INT, Acquire, false); + case vmIntrinsics::_getLongAcquire: return inline_unsafe_access(!is_store, T_LONG, Acquire, false); + case vmIntrinsics::_getFloatAcquire: return inline_unsafe_access(!is_store, T_FLOAT, Acquire, false); + case vmIntrinsics::_getDoubleAcquire: return inline_unsafe_access(!is_store, T_DOUBLE, Acquire, false); + + case vmIntrinsics::_putObjectRelease: return inline_unsafe_access( is_store, T_OBJECT, Release, false); + case vmIntrinsics::_putBooleanRelease: return inline_unsafe_access( is_store, T_BOOLEAN, Release, false); + case vmIntrinsics::_putByteRelease: return inline_unsafe_access( is_store, T_BYTE, Release, false); + case vmIntrinsics::_putShortRelease: return inline_unsafe_access( is_store, T_SHORT, Release, false); + case vmIntrinsics::_putCharRelease: return inline_unsafe_access( is_store, T_CHAR, Release, false); + case vmIntrinsics::_putIntRelease: return inline_unsafe_access( is_store, T_INT, Release, false); + case vmIntrinsics::_putLongRelease: return inline_unsafe_access( is_store, T_LONG, Release, false); + case vmIntrinsics::_putFloatRelease: return inline_unsafe_access( is_store, T_FLOAT, Release, false); + case vmIntrinsics::_putDoubleRelease: return inline_unsafe_access( is_store, T_DOUBLE, Release, false); + + case vmIntrinsics::_getObjectOpaque: return inline_unsafe_access(!is_store, T_OBJECT, Opaque, false); + case vmIntrinsics::_getBooleanOpaque: return inline_unsafe_access(!is_store, T_BOOLEAN, Opaque, false); + case vmIntrinsics::_getByteOpaque: return inline_unsafe_access(!is_store, T_BYTE, Opaque, false); + case vmIntrinsics::_getShortOpaque: return inline_unsafe_access(!is_store, T_SHORT, Opaque, false); + case vmIntrinsics::_getCharOpaque: return inline_unsafe_access(!is_store, T_CHAR, Opaque, false); + case vmIntrinsics::_getIntOpaque: return inline_unsafe_access(!is_store, T_INT, Opaque, false); + case vmIntrinsics::_getLongOpaque: return inline_unsafe_access(!is_store, T_LONG, Opaque, false); + case vmIntrinsics::_getFloatOpaque: return inline_unsafe_access(!is_store, T_FLOAT, Opaque, false); + case vmIntrinsics::_getDoubleOpaque: return inline_unsafe_access(!is_store, T_DOUBLE, Opaque, false); + + case vmIntrinsics::_putObjectOpaque: return inline_unsafe_access( is_store, T_OBJECT, Opaque, false); + case vmIntrinsics::_putBooleanOpaque: return inline_unsafe_access( is_store, T_BOOLEAN, Opaque, false); + case vmIntrinsics::_putByteOpaque: return inline_unsafe_access( is_store, T_BYTE, Opaque, false); + case vmIntrinsics::_putShortOpaque: return inline_unsafe_access( is_store, T_SHORT, Opaque, false); + case vmIntrinsics::_putCharOpaque: return inline_unsafe_access( is_store, T_CHAR, Opaque, false); + case vmIntrinsics::_putIntOpaque: return inline_unsafe_access( is_store, T_INT, Opaque, false); + case vmIntrinsics::_putLongOpaque: return inline_unsafe_access( is_store, T_LONG, Opaque, false); + case vmIntrinsics::_putFloatOpaque: return inline_unsafe_access( is_store, T_FLOAT, Opaque, false); + case vmIntrinsics::_putDoubleOpaque: return inline_unsafe_access( is_store, T_DOUBLE, Opaque, false); case vmIntrinsics::_compareAndSwapObject: return inline_unsafe_load_store(T_OBJECT, LS_cmp_swap, Volatile); case vmIntrinsics::_compareAndSwapInt: return inline_unsafe_load_store(T_INT, LS_cmp_swap, Volatile); @@ -2196,8 +2177,6 @@ //----------------------------inline_unsafe_access---------------------------- -const static BasicType T_ADDRESS_HOLDER = T_LONG; - // Helper that guards and inserts a pre-barrier. void LibraryCallKit::insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar) { @@ -2298,13 +2277,12 @@ } -const TypeOopPtr* LibraryCallKit::sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type, bool is_native_ptr) { +const TypeOopPtr* LibraryCallKit::sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type) { // Attempt to infer a sharper value type from the offset and base type. ciKlass* sharpened_klass = NULL; // See if it is an instance field, with an object type. if (alias_type->field() != NULL) { - assert(!is_native_ptr, "native pointer op cannot use a java address"); if (alias_type->field()->type()->is_klass()) { sharpened_klass = alias_type->field()->type()->as_klass(); } @@ -2337,7 +2315,7 @@ return NULL; } -bool LibraryCallKit::inline_unsafe_access(const bool is_native_ptr, bool is_store, const BasicType type, const AccessKind kind, const bool unaligned) { +bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, const AccessKind kind, const bool unaligned) { if (callee()->is_static()) return false; // caller must have the capability! guarantee(!is_store || kind != Acquire, "Acquire accesses can be produced only for loads"); guarantee( is_store || kind != Release, "Release accesses can be produced only for stores"); @@ -2352,31 +2330,17 @@ if (!is_store) { // Object getObject(Object base, int/long offset), etc. BasicType rtype = sig->return_type()->basic_type(); - if (rtype == T_ADDRESS_HOLDER && callee()->name() == ciSymbol::getAddress_name()) - rtype = T_ADDRESS; // it is really a C void* assert(rtype == type, "getter must return the expected value"); - if (!is_native_ptr) { - assert(sig->count() == 2, "oop getter has 2 arguments"); - assert(sig->type_at(0)->basic_type() == T_OBJECT, "getter base is object"); - assert(sig->type_at(1)->basic_type() == T_LONG, "getter offset is correct"); - } else { - assert(sig->count() == 1, "native getter has 1 argument"); - assert(sig->type_at(0)->basic_type() == T_LONG, "getter base is long"); - } + assert(sig->count() == 2, "oop getter has 2 arguments"); + assert(sig->type_at(0)->basic_type() == T_OBJECT, "getter base is object"); + assert(sig->type_at(1)->basic_type() == T_LONG, "getter offset is correct"); } else { // void putObject(Object base, int/long offset, Object x), etc. assert(sig->return_type()->basic_type() == T_VOID, "putter must not return a value"); - if (!is_native_ptr) { - assert(sig->count() == 3, "oop putter has 3 arguments"); - assert(sig->type_at(0)->basic_type() == T_OBJECT, "putter base is object"); - assert(sig->type_at(1)->basic_type() == T_LONG, "putter offset is correct"); - } else { - assert(sig->count() == 2, "native putter has 2 arguments"); - assert(sig->type_at(0)->basic_type() == T_LONG, "putter base is long"); - } + assert(sig->count() == 3, "oop putter has 3 arguments"); + assert(sig->type_at(0)->basic_type() == T_OBJECT, "putter base is object"); + assert(sig->type_at(1)->basic_type() == T_LONG, "putter offset is correct"); BasicType vtype = sig->type_at(sig->count()-1)->basic_type(); - if (vtype == T_ADDRESS_HOLDER && callee()->name() == ciSymbol::putAddress_name()) - vtype = T_ADDRESS; // it is really a C void* assert(vtype == type, "putter must accept the expected value"); } #endif // ASSERT @@ -2393,27 +2357,22 @@ Node* offset = top(); Node* val; - if (!is_native_ptr) { - // The base is either a Java object or a value produced by Unsafe.staticFieldBase - Node* base = argument(1); // type: oop - // The offset is a value produced by Unsafe.staticFieldOffset or Unsafe.objectFieldOffset - offset = argument(2); // type: long - // We currently rely on the cookies produced by Unsafe.xxxFieldOffset - // to be plain byte offsets, which are also the same as those accepted - // by oopDesc::field_base. - assert(Unsafe_field_offset_to_byte_offset(11) == 11, - "fieldOffset must be byte-scaled"); - // 32-bit machines ignore the high half! - offset = ConvL2X(offset); - adr = make_unsafe_address(base, offset); + // The base is either a Java object or a value produced by Unsafe.staticFieldBase + Node* base = argument(1); // type: oop + // The offset is a value produced by Unsafe.staticFieldOffset or Unsafe.objectFieldOffset + offset = argument(2); // type: long + // We currently rely on the cookies produced by Unsafe.xxxFieldOffset + // to be plain byte offsets, which are also the same as those accepted + // by oopDesc::field_base. + assert(Unsafe_field_offset_to_byte_offset(11) == 11, + "fieldOffset must be byte-scaled"); + // 32-bit machines ignore the high half! + offset = ConvL2X(offset); + adr = make_unsafe_address(base, offset); + if (_gvn.type(base)->isa_ptr() != TypePtr::NULL_PTR) { heap_base_oop = base; - val = is_store ? argument(4) : NULL; - } else { - Node* ptr = argument(1); // type: long - ptr = ConvL2X(ptr); // adjust Java long to machine word - adr = make_unsafe_address(NULL, ptr); - val = is_store ? argument(3) : NULL; - } + } + val = is_store ? argument(4) : NULL; const TypePtr *adr_type = _gvn.type(adr)->isa_ptr(); @@ -2494,11 +2453,11 @@ // SATB log buffer using the pre-barrier mechanism. // Also we need to add memory barrier to prevent commoning reads // from this field across safepoint since GC can change its value. - bool need_read_barrier = !is_native_ptr && !is_store && + bool need_read_barrier = !is_store && offset != top() && heap_base_oop != top(); if (!is_store && type == T_OBJECT) { - const TypeOopPtr* tjp = sharpen_unsafe_type(alias_type, adr_type, is_native_ptr); + const TypeOopPtr* tjp = sharpen_unsafe_type(alias_type, adr_type); if (tjp != NULL) { value_type = tjp; } diff -r b2a58604e046 -r fe30fdab0f62 hotspot/src/share/vm/prims/unsafe.cpp --- a/hotspot/src/share/vm/prims/unsafe.cpp Fri May 06 13:00:21 2016 -0700 +++ b/hotspot/src/share/vm/prims/unsafe.cpp Fri May 06 15:59:26 2016 -0700 @@ -131,38 +131,137 @@ } -///// Data in the Java heap. +///// Data read/writes on the Java heap and in native (off-heap) memory + +/** + * Helper class for accessing memory. + * + * Normalizes values and wraps accesses in + * JavaThread::doing_unsafe_access() if needed. + */ +class MemoryAccess : StackObj { + JavaThread* _thread; + jobject _obj; + jlong _offset; -#define truncate_jboolean(x) ((x) & 1) -#define truncate_jbyte(x) (x) -#define truncate_jshort(x) (x) -#define truncate_jchar(x) (x) -#define truncate_jint(x) (x) -#define truncate_jlong(x) (x) -#define truncate_jfloat(x) (x) -#define truncate_jdouble(x) (x) + // Resolves and returns the address of the memory access + void* addr() { + return index_oop_from_field_offset_long(JNIHandles::resolve(_obj), _offset); + } + + template + T normalize(T x) { + return x; + } -#define GET_FIELD(obj, offset, type_name, v) \ - oop p = JNIHandles::resolve(obj); \ - type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset) + jboolean normalize(jboolean x) { + return x & 1; + } + + /** + * Helper class to wrap memory accesses in JavaThread::doing_unsafe_access() + */ + class GuardUnsafeAccess { + JavaThread* _thread; + bool _active; -#define SET_FIELD(obj, offset, type_name, x) \ - oop p = JNIHandles::resolve(obj); \ - *(type_name*)index_oop_from_field_offset_long(p, offset) = truncate_##type_name(x) + public: + GuardUnsafeAccess(JavaThread* thread, jobject _obj) : _thread(thread) { + if (JNIHandles::resolve(_obj) == NULL) { + // 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); + _active = true; + } else { + _active = false; + } + } + + ~GuardUnsafeAccess() { + if (_active) { + _thread->set_doing_unsafe_access(false); + } + } + }; -#define GET_FIELD_VOLATILE(obj, offset, type_name, v) \ - oop p = JNIHandles::resolve(obj); \ - if (support_IRIW_for_not_multiple_copy_atomic_cpu) { \ - OrderAccess::fence(); \ - } \ - volatile type_name v = OrderAccess::load_acquire((volatile type_name*)index_oop_from_field_offset_long(p, offset)); +public: + MemoryAccess(JavaThread* thread, jobject obj, jlong offset) + : _thread(thread), _obj(obj), _offset(offset) { + } + + template + T get() { + GuardUnsafeAccess guard(_thread, _obj); + + T* p = (T*)addr(); -#define SET_FIELD_VOLATILE(obj, offset, type_name, x) \ - oop p = JNIHandles::resolve(obj); \ - OrderAccess::release_store_fence((volatile type_name*)index_oop_from_field_offset_long(p, offset), truncate_##type_name(x)); + T x = *p; + + return x; + } + + template + void put(T x) { + GuardUnsafeAccess guard(_thread, _obj); + + T* p = (T*)addr(); + + *p = normalize(x); + } -// Get/SetObject must be special-cased, since it works with handles. + template + T get_volatile() { + GuardUnsafeAccess guard(_thread, _obj); + + T* p = (T*)addr(); + + if (support_IRIW_for_not_multiple_copy_atomic_cpu) { + OrderAccess::fence(); + } + + T x = OrderAccess::load_acquire((volatile T*)p); + + return x; + } + + template + void put_volatile(T x) { + GuardUnsafeAccess guard(_thread, _obj); + + T* p = (T*)addr(); + + OrderAccess::release_store_fence((volatile T*)p, normalize(x)); + } + + +#ifndef SUPPORTS_NATIVE_CX8 + jlong get_jlong_locked() { + GuardUnsafeAccess guard(_thread, _obj); + + MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag); + + jlong* p = (jlong*)addr(); + + jlong x = Atomic::load(p); + + return x; + } + + void put_jlong_locked(jlong x) { + GuardUnsafeAccess guard(_thread, _obj); + + MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag); + + jlong* p = (jlong*)addr(); + + Atomic::store(normalize(x), p); + } +#endif +}; + +// Get/PutObject must be special-cased, since it works with handles. // These functions allow a null base pointer with an arbitrary address. // But if the base pointer is non-null, the offset should make some sense. @@ -208,7 +307,7 @@ return ret; } UNSAFE_END -UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) { +UNSAFE_ENTRY(void, Unsafe_PutObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) { oop x = JNIHandles::resolve(x_h); oop p = JNIHandles::resolve(obj); @@ -236,7 +335,7 @@ return JNIHandles::make_local(env, v); } UNSAFE_END -UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) { +UNSAFE_ENTRY(void, Unsafe_PutObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) { oop x = JNIHandles::resolve(x_h); oop p = JNIHandles::resolve(obj); void* addr = index_oop_from_field_offset_long(p, offset); @@ -301,25 +400,17 @@ UNSAFE_ENTRY(jlong, Unsafe_GetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { if (VM_Version::supports_cx8()) { - GET_FIELD_VOLATILE(obj, offset, jlong, v); - return v; + return MemoryAccess(thread, obj, offset).get_volatile(); } else { - Handle p (THREAD, JNIHandles::resolve(obj)); - jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); - MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag); - jlong value = Atomic::load(addr); - return value; + return MemoryAccess(thread, obj, offset).get_jlong_locked(); } } UNSAFE_END -UNSAFE_ENTRY(void, Unsafe_SetLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x)) { +UNSAFE_ENTRY(void, Unsafe_PutLongVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong x)) { if (VM_Version::supports_cx8()) { - SET_FIELD_VOLATILE(obj, offset, jlong, x); + MemoryAccess(thread, obj, offset).put_volatile(x); } else { - Handle p (THREAD, JNIHandles::resolve(obj)); - jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); - MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag); - Atomic::store(x, addr); + MemoryAccess(thread, obj, offset).put_jlong_locked(x); } } UNSAFE_END @@ -337,15 +428,14 @@ return UseUnalignedAccesses; } UNSAFE_END -#define DEFINE_GETSETOOP(java_type, Type) \ +#define DEFINE_GETSETOOP(java_type, Type) \ \ UNSAFE_ENTRY(java_type, Unsafe_Get##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \ - GET_FIELD(obj, offset, java_type, v); \ - return v; \ + return MemoryAccess(thread, obj, offset).get(); \ } UNSAFE_END \ \ -UNSAFE_ENTRY(void, Unsafe_Set##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \ - SET_FIELD(obj, offset, java_type, x); \ +UNSAFE_ENTRY(void, Unsafe_Put##Type(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \ + MemoryAccess(thread, obj, offset).put(x); \ } UNSAFE_END \ \ // END DEFINE_GETSETOOP. @@ -364,12 +454,11 @@ #define DEFINE_GETSETOOP_VOLATILE(java_type, Type) \ \ UNSAFE_ENTRY(java_type, Unsafe_Get##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) { \ - GET_FIELD_VOLATILE(obj, offset, java_type, v); \ - return v; \ + return MemoryAccess(thread, obj, offset).get_volatile(); \ } UNSAFE_END \ \ -UNSAFE_ENTRY(void, Unsafe_Set##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \ - SET_FIELD_VOLATILE(obj, offset, java_type, x); \ +UNSAFE_ENTRY(void, Unsafe_Put##Type##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, java_type x)) { \ + MemoryAccess(thread, obj, offset).put_volatile(x); \ } UNSAFE_END \ \ // END DEFINE_GETSETOOP_VOLATILE. @@ -400,98 +489,6 @@ OrderAccess::fence(); } UNSAFE_END -////// Data in the C heap. - -// Note: These do not throw NullPointerException for bad pointers. -// They just crash. Only a oop base pointer can generate a NullPointerException. -// -#define DEFINE_GETSETNATIVE(java_type, Type, native_type) \ - \ -UNSAFE_ENTRY(java_type, Unsafe_GetNative##Type(JNIEnv *env, jobject unsafe, jlong addr)) { \ - void* p = addr_from_java(addr); \ - JavaThread* t = JavaThread::current(); \ - t->set_doing_unsafe_access(true); \ - java_type x = *(volatile native_type*)p; \ - t->set_doing_unsafe_access(false); \ - return x; \ -} UNSAFE_END \ - \ -UNSAFE_ENTRY(void, Unsafe_SetNative##Type(JNIEnv *env, jobject unsafe, jlong addr, java_type x)) { \ - JavaThread* t = JavaThread::current(); \ - t->set_doing_unsafe_access(true); \ - void* p = addr_from_java(addr); \ - *(volatile native_type*)p = x; \ - t->set_doing_unsafe_access(false); \ -} UNSAFE_END \ - \ -// END DEFINE_GETSETNATIVE. - -DEFINE_GETSETNATIVE(jbyte, Byte, signed char) -DEFINE_GETSETNATIVE(jshort, Short, signed short); -DEFINE_GETSETNATIVE(jchar, Char, unsigned short); -DEFINE_GETSETNATIVE(jint, Int, jint); -// no long -- handled specially -DEFINE_GETSETNATIVE(jfloat, Float, float); -DEFINE_GETSETNATIVE(jdouble, Double, double); - -#undef DEFINE_GETSETNATIVE - -UNSAFE_ENTRY(jlong, Unsafe_GetNativeLong(JNIEnv *env, jobject unsafe, jlong addr)) { - JavaThread* t = JavaThread::current(); - // We do it this way to avoid problems with access to heap using 64 - // bit loads, as jlong in heap could be not 64-bit aligned, and on - // some CPUs (SPARC) it leads to SIGBUS. - t->set_doing_unsafe_access(true); - void* p = addr_from_java(addr); - jlong x; - - if (is_ptr_aligned(p, sizeof(jlong)) == 0) { - // jlong is aligned, do a volatile access - x = *(volatile jlong*)p; - } else { - jlong_accessor acc; - acc.words[0] = ((volatile jint*)p)[0]; - acc.words[1] = ((volatile jint*)p)[1]; - x = acc.long_value; - } - - t->set_doing_unsafe_access(false); - - return x; -} UNSAFE_END - -UNSAFE_ENTRY(void, Unsafe_SetNativeLong(JNIEnv *env, jobject unsafe, jlong addr, jlong x)) { - JavaThread* t = JavaThread::current(); - // see comment for Unsafe_GetNativeLong - t->set_doing_unsafe_access(true); - void* p = addr_from_java(addr); - - if (is_ptr_aligned(p, sizeof(jlong))) { - // jlong is aligned, do a volatile access - *(volatile jlong*)p = x; - } else { - jlong_accessor acc; - acc.long_value = x; - ((volatile jint*)p)[0] = acc.words[0]; - ((volatile jint*)p)[1] = acc.words[1]; - } - - t->set_doing_unsafe_access(false); -} UNSAFE_END - - -UNSAFE_LEAF(jlong, Unsafe_GetNativeAddress(JNIEnv *env, jobject unsafe, jlong addr)) { - void* p = addr_from_java(addr); - - return addr_to_java(*(void**)p); -} UNSAFE_END - -UNSAFE_LEAF(void, Unsafe_SetNativeAddress(JNIEnv *env, jobject unsafe, jlong addr, jlong x)) { - void* p = addr_from_java(addr); - *(void**)p = addr_from_java(x); -} UNSAFE_END - - ////// Allocation requests UNSAFE_ENTRY(jobject, Unsafe_AllocateInstance(JNIEnv *env, jobject unsafe, jclass cls)) { @@ -980,8 +977,8 @@ } UNSAFE_END UNSAFE_ENTRY(jlong, Unsafe_CompareAndExchangeLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x)) { - Handle p (THREAD, JNIHandles::resolve(obj)); - jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); + Handle p(THREAD, JNIHandles::resolve(obj)); + jlong* addr = (jlong*)index_oop_from_field_offset_long(p(), offset); #ifdef SUPPORTS_NATIVE_CX8 return (jlong)(Atomic::cmpxchg(x, addr, e)); @@ -1017,7 +1014,7 @@ UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) { oop p = JNIHandles::resolve(obj); - jint* addr = (jint *) index_oop_from_field_offset_long(p, offset); + jint* addr = (jint *)index_oop_from_field_offset_long(p, offset); return (jint)(Atomic::cmpxchg(x, addr, e)) == e; } UNSAFE_END @@ -1143,20 +1140,16 @@ #define DECLARE_GETPUTOOP(Type, Desc) \ {CC "get" #Type, CC "(" OBJ "J)" #Desc, FN_PTR(Unsafe_Get##Type)}, \ - {CC "put" #Type, CC "(" OBJ "J" #Desc ")V", FN_PTR(Unsafe_Set##Type)}, \ + {CC "put" #Type, CC "(" OBJ "J" #Desc ")V", FN_PTR(Unsafe_Put##Type)}, \ {CC "get" #Type "Volatile", CC "(" OBJ "J)" #Desc, FN_PTR(Unsafe_Get##Type##Volatile)}, \ - {CC "put" #Type "Volatile", CC "(" OBJ "J" #Desc ")V", FN_PTR(Unsafe_Set##Type##Volatile)} + {CC "put" #Type "Volatile", CC "(" OBJ "J" #Desc ")V", FN_PTR(Unsafe_Put##Type##Volatile)} -#define DECLARE_GETPUTNATIVE(Byte, B) \ - {CC "get" #Byte, CC "(" ADR ")" #B, FN_PTR(Unsafe_GetNative##Byte)}, \ - {CC "put" #Byte, CC "(" ADR#B ")V", FN_PTR(Unsafe_SetNative##Byte)} - static JNINativeMethod jdk_internal_misc_Unsafe_methods[] = { {CC "getObject", CC "(" OBJ "J)" OBJ "", FN_PTR(Unsafe_GetObject)}, - {CC "putObject", CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_SetObject)}, + {CC "putObject", CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_PutObject)}, {CC "getObjectVolatile",CC "(" OBJ "J)" OBJ "", FN_PTR(Unsafe_GetObjectVolatile)}, - {CC "putObjectVolatile",CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_SetObjectVolatile)}, + {CC "putObjectVolatile",CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_PutObjectVolatile)}, {CC "getUncompressedObject", CC "(" ADR ")" OBJ, FN_PTR(Unsafe_GetUncompressedObject)}, {CC "getJavaMirror", CC "(" ADR ")" CLS, FN_PTR(Unsafe_GetJavaMirror)}, @@ -1171,17 +1164,6 @@ DECLARE_GETPUTOOP(Float, F), DECLARE_GETPUTOOP(Double, D), - DECLARE_GETPUTNATIVE(Byte, B), - DECLARE_GETPUTNATIVE(Short, S), - DECLARE_GETPUTNATIVE(Char, C), - DECLARE_GETPUTNATIVE(Int, I), - DECLARE_GETPUTNATIVE(Long, J), - DECLARE_GETPUTNATIVE(Float, F), - DECLARE_GETPUTNATIVE(Double, D), - - {CC "getAddress", CC "(" ADR ")" ADR, FN_PTR(Unsafe_GetNativeAddress)}, - {CC "putAddress", CC "(" ADR "" ADR ")V", FN_PTR(Unsafe_SetNativeAddress)}, - {CC "allocateMemory0", CC "(J)" ADR, FN_PTR(Unsafe_AllocateMemory0)}, {CC "reallocateMemory0", CC "(" ADR "J)" ADR, FN_PTR(Unsafe_ReallocateMemory0)}, {CC "freeMemory0", CC "(" ADR ")V", FN_PTR(Unsafe_FreeMemory0)}, @@ -1239,7 +1221,6 @@ #undef DAC_Args #undef DECLARE_GETPUTOOP -#undef DECLARE_GETPUTNATIVE // This function is exported, used by NativeLookup.