sun.misc.Unsafe
/**
* Atomically updates Java variable to {@code x} if it is currently
* holding {@code expected}.
*
* <p>This operation has memory semantics of a {@code volatile} read
* and write. Corresponds to C11 atomic_compare_exchange_strong.
*
* @return {@code true} if successful
*/
@ForceInline
public final boolean compareAndSwapInt(Object o, long offset,
int expected,
int x) {
return theInternalUnsafe.compareAndSetInt(o, offset, expected, x);
}
jdk.internal.misc.Unsafe
Unsafe.class
/**
* Atomically updates Java variable to {@code x} if it is currently
* holding {@code expected}.
*
* <p>This operation has memory semantics of a {@code volatile} read
* and write. Corresponds to C11 atomic_compare_exchange_strong.
*
* @return {@code true} if successful
*/
@HotSpotIntrinsicCandidate
public final native boolean compareAndSetInt(Object o, long offset,
int expected,
int x);
Unsafe.cpp
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) {
oop p = JNIHandles::resolve(obj);
if (p == NULL) {
volatile jint* addr = (volatile jint*)index_oop_from_field_offset_long(p, offset);
return RawAccess<>::atomic_cmpxchg(addr, e, x) == e;
} else {
assert_field_offset_sane(p, offset);
return HeapAccess<>::atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x) == e;
}
} UNSAFE_END
access.hpp
template <typename T>
static inline T atomic_cmpxchg_at(oop base, ptrdiff_t offset, T compare_value, T new_value) {
verify_primitive_decorators<atomic_cmpxchg_mo_decorators>();
return AccessInternal::atomic_cmpxchg_at<decorators>(base, offset, compare_value, new_value);
}
accessBackend.hpp
template <DecoratorSet decorators, typename T>
inline T atomic_xchg_at(oop base, ptrdiff_t offset, T new_value) {
verify_types<decorators, T>();
typedef typename Decay<T>::type DecayedT;
DecayedT new_decayed_value = new_value;
// atomic_xchg is only available in SEQ_CST flavour.
const DecoratorSet expanded_decorators = DecoratorFixup<decorators | MO_SEQ_CST |
(HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ?
INTERNAL_CONVERT_COMPRESSED_OOP : DECORATORS_NONE)>::value;
return PreRuntimeDispatch::atomic_xchg_at<expanded_decorators>(base, offset, new_decayed_value);
}
template<size_t byte_size>
struct Atomic::PlatformCmpxchg {
template<typename T>
T operator()(T volatile* dest,
T compare_value,
T exchange_value,
atomic_memory_order order) const;
};
template<>
template<typename T>
inline T Atomic::PlatformCmpxchg<4>::operator()(T volatile* dest,
T compare_value,
T exchange_value,
atomic_memory_order /* order */) const {
STATIC_ASSERT(4 == sizeof(T));
__asm__ volatile ("lock cmpxchgl %1,(%3)"
: "=a" (exchange_value)
: "r" (exchange_value), "a" (compare_value), "r" (dest)
: "cc", "memory");
return exchange_value;
}