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に依存し、32ビット/64ビットに依存します。したがって、JVMはここで分割されます。
編集
steve-Oが指摘したように、CASにはABA問題としての弱点があるため、マルチスレッド環境でCASが正しいことを確認するには、ここでメモリバリアが必要です。また、CASにはアドレス、古い値、新しい値の3つのパラメーターが必要になるため、このプロセスには最新のCPUが必要です。
編集
新しいC++0x標準(現在正式に公開されていませんか?)では、JVMを分割する必要がないということですか?少なくとも、ソースコードレベルでは。バイナリは引き続き分割できますが、C++コンパイラによって処理されます。