任何人都可以将这个C ++代码(从OpenJDK6)解释为普通英语吗?
这是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在multithreading环境中仍然是正确的。 此外,由于CAS需要三个参数,地址,旧值和新值,因此此过程需要现代CPU。
编辑
使用新的C ++ 0x标准 (现在还没有正式发布?),是否意味着JVM不需要被调整? 至少,在源代码级别。 二进制文件仍然可以拆分,但它将由C ++编译器处理。
它是CAS API的JNI包装器,具有IA64体系结构的 内存屏障 。
编辑:有关CAS的说明:
将dest与比较值进行比较 ,如果匹配则将交换值分配给dest 。
这是一个primefaces操作 ,这意味着在操作执行时没有其他处理器可以更改dest的值。
这里列出了没有primefaces操作可能发生的典型问题,“ABA问题”
http://en.wikipedia.org/wiki/ABA_problem
为什么要使用CASfunction?
简单示例是一个计数器,如果您有多个线程递增计数器,请考虑增量过程的作用:
int i; read the value of i add one to the current value save the value back to i.
当另一个处理器读取i的值并在此处理器完成之前保存i + 1时会发生什么?
你最终得到i + 1而不是i + 2 。
这里有一些解释
- 什么是oop,为什么要压缩?
HotSpot用语中的“oop”或“普通对象指针”是指向对象的托管指针。 它通常与本机机器指针的大小相同,这意味着LP64系统上的64位。 在ILP32系统上,最大堆大小略小于4Gb,这对于许多应用程序来说是不够的。
- 哪些oops被压缩了?
在ILP32模式JVM中,或者如果在LP64模式下关闭UseCompressedOops标志,则所有oops都是本机机器字大小。
如果UseCompressedOops为true,则将压缩堆中的以下oops:
•每个对象的klass字段•每个oop实例字段•oop数组的每个元素(objArray)
有关详细信息,请查看此sun wiki