diff -r 14aa557af8ba -r 09c41c4913d9 src/hotspot/os_cpu/solaris_sparc/atomic_solaris_sparc.hpp --- a/src/hotspot/os_cpu/solaris_sparc/atomic_solaris_sparc.hpp Tue Oct 03 06:48:40 2017 +0200 +++ b/src/hotspot/os_cpu/solaris_sparc/atomic_solaris_sparc.hpp Tue Sep 26 21:37:01 2017 +0200 @@ -43,16 +43,6 @@ inline void Atomic::store(jlong store_value, volatile jlong* dest) { *dest = store_value; } inline jlong Atomic::load(const volatile jlong* src) { return *src; } - -// This is the interface to the atomic instructions in solaris_sparc.il. -// It's very messy because we need to support v8 and these instructions -// are illegal there. When sparc v8 is dropped, we can drop out lots of -// this code. Also compiler2 does not support v8 so the conditional code -// omits the instruction set check. - -extern "C" jint _Atomic_swap32(jint exchange_value, volatile jint* dest); -extern "C" intptr_t _Atomic_swap64(intptr_t exchange_value, volatile intptr_t* dest); - // Implement ADD using a CAS loop. template struct Atomic::PlatformAdd VALUE_OBJ_CLASS_SPEC { @@ -69,16 +59,30 @@ } }; -inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { - return _Atomic_swap32(exchange_value, dest); +template<> +template +inline T Atomic::PlatformXchg<4>::operator()(T exchange_value, + T volatile* dest) const { + STATIC_ASSERT(4 == sizeof(T)); + __asm__ volatile ( "swap [%2],%0" + : "=r" (exchange_value) + : "0" (exchange_value), "r" (dest) + : "memory"); + return exchange_value; } -inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { - return _Atomic_swap64(exchange_value, dest); -} - -inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { - return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest); +template<> +template +inline T Atomic::PlatformXchg<8>::operator()(T exchange_value, + T volatile* dest) const { + STATIC_ASSERT(8 == sizeof(T)); + T old_value = *dest; + while (true) { + T result = cmpxchg(exchange_value, dest, old_value); + if (result == old_value) break; + old_value = result; + } + return old_value; } // No direct support for cmpxchg of bytes; emulate using int.