--- old/src/os_cpu/linux_aarch64/vm/atomic_linux_aarch64.hpp 2017-07-20 11:32:07.144997270 +0200 +++ new/src/os_cpu/linux_aarch64/vm/atomic_linux_aarch64.hpp 2017-07-20 11:32:07.056997273 +0200 @@ -61,6 +61,13 @@ return res; } +template <> +inline Atomic::CanonicalPointer Atomic::specialized_xchg(Atomic::CanonicalPointer exchange_value, volatile Atomic::CanonicalPointer* dest) { + Atomic::CanonicalPointer res = __sync_lock_test_and_set (dest, exchange_value); + FULL_MEM_BARRIER; + return res; +} + template T generic_cmpxchg(T exchange_value, volatile T* dest, T compare_value, cmpxchg_memory_order order) { --- old/src/share/vm/runtime/atomic.hpp 2017-07-20 11:32:07.780997248 +0200 +++ new/src/share/vm/runtime/atomic.hpp 2017-07-20 11:32:07.692997251 +0200 @@ -26,6 +26,8 @@ #define SHARE_VM_RUNTIME_ATOMIC_HPP #include "memory/allocation.hpp" +#include "metaprogramming/conditional.hpp" +#include "metaprogramming/enableIf.hpp" #include "metaprogramming/integerTypes.hpp" #include "metaprogramming/isIntegral.hpp" #include "metaprogramming/isPointer.hpp" @@ -41,6 +43,31 @@ class Atomic : AllStatic { template class Never: public FalseType {}; + typedef char* CanonicalPointer; + + // The type is CanonicalPointer for pointers, otherwise canonical integer + template + struct CanonicalType : AllStatic { + typedef typename Conditional::value, CanonicalPointer, typename IntegerTypes::Signed::type>::type type; + }; + + template + static typename EnableIf::value, CanonicalPointer>::type + cast_to_canonical(T value) { return reinterpret_cast(value); } + + template + static typename EnableIf::value, typename IntegerTypes::Signed::type>::type + cast_to_canonical(T value) { return IntegerTypes::cast_to_signed(value); } + + template + static typename EnableIf::value, T>::type cast_from_canonical(U value) { + return reinterpret_cast(value); + } + + template + static typename EnableIf::value, T>::type cast_from_canonical(U value) { + return IntegerTypes::cast(value); + } template inline static void specialized_store(T store_value, volatile T* dest) { @@ -70,8 +97,17 @@ add(-1, dest); } + // If the platform does not offer a specialization for pointers, + // try using the canonical pointer integer instead template - inline static T specialized_xchg(T exchange_value, volatile T* dest) { + inline static typename EnableIf::value, T>::type specialized_xchg(T exchange_value, volatile T* dest) { + typedef typename IntegerTypes::Signed::type Raw; + Raw result = specialized_xchg(IntegerTypes::cast_to_signed(exchange_value), reinterpret_cast(dest)); + return IntegerTypes::cast(result); + } + + template + inline static typename EnableIf::value, T>::type specialized_xchg(T exchange_value, volatile T* dest) { STATIC_ASSERT(Never::value); return exchange_value; } @@ -286,11 +322,11 @@ template inline U Atomic::xchg(T exchange_value, volatile U* dest) { - typedef typename IntegerTypes::Signed::type Raw; + typedef typename CanonicalType::type Raw; U exchange_value_cast = exchange_value; - Raw result = specialized_xchg(IntegerTypes::cast_to_signed(exchange_value_cast), + Raw result = specialized_xchg(cast_to_canonical(exchange_value_cast), reinterpret_cast(dest)); - return IntegerTypes::cast(result); + return cast_from_canonical(result); } template