这是OpenJDK6 的hotspot/src/share/vm/prims/unsafe.cpp
代码片段(从第 1082 行开始):
// JSR166 ------------------------------------------------------------------
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject e_h, jobject x_h))
UnsafeWrapper("Unsafe_CompareAndSwapObject");
oop x = JNIHandles::resolve(x_h);
oop e = JNIHandles::resolve(e_h);
oop p = JNIHandles::resolve(obj);
HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset);
if (UseCompressedOops) {
update_barrier_set_pre((narrowOop*)addr, e);
} else {
update_barrier_set_pre((oop*)addr, e);
}
oop res = oopDesc::atomic_compare_exchange_oop(x, addr, e);
jboolean success = (res == e);
if (success)
update_barrier_set((void*)addr, x);
return success;
UNSAFE_END
还添加了关键方法oopDesc::atomic_compare_exchange_oop。
inline oop oopDesc::atomic_compare_exchange_oop(oop exchange_value,
volatile HeapWord *dest,
oop compare_value) {
if (UseCompressedOops) {
// encode exchange and compare value from oop to T
narrowOop val = encode_heap_oop(exchange_value);
narrowOop cmp = encode_heap_oop(compare_value);
narrowOop old = (narrowOop) Atomic::cmpxchg(val, (narrowOop*)dest, cmp);
// decode old from T to oop
return decode_heap_oop(old);
} else {
return (oop)Atomic::cmpxchg_ptr(exchange_value, (oop*)dest, compare_value);
}
}
这段代码在 JVM 上下文中的目的是什么?我在 C++ 方面没有经验。
Atomic::cmpxchg & Atomic::cmpxchg_ptr依赖于 OS & CPU & 32bit/64bit。所以 JVM 在这里被拆分。
编辑
正如 steve-O 所指出的,CAS 有其作为 ABA 问题的弱点,因此这里需要内存屏障以确保 CAS 在多线程环境中仍然正确。此外,由于 CAS 需要地址、旧值和新值三个参数,因此此过程需要现代 CPU。
编辑
有了新的C++0x 标准(现在还没有正式发布?),是不是意味着 JVM 就不需要拆分了?至少,在源代码级别。二进制文件仍然可以拆分,但将由 C++ 编译器处理。