Вот фрагмент кода из 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 становится зависимой от ОС и ЦП и зависит от 32-битной и 64-битной систем. Таким образом, JVM разделены здесь.
EDIT
Как указал steve-O, CAS имеет свою слабость как проблему ABA, поэтому здесь необходим барьер памяти, чтобы гарантировать, что CAS все еще корректен в многопоточной среде. Кроме того, поскольку CAS потребуется три параметра: адрес, старое значение и новое значение, для этого требуется современный ЦП.
EDIT
С новым C ++ 0x стандартом (формально не опубликовано сейчас?), Значит ли это, что JVM не нужно тогда расщеплять? По крайней мере, на уровне исходного кода. Бинарный файл все еще может быть разделен, но он будет обрабатываться компилятором C ++.