谁能解释一下这个 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++ 经验。
原子::cmpxchg & Atomic::cmpxchg_ptr 成为 OS &中央处理器和32 位/64 位相关。所以这里对JVM进行了拆分。
编辑
正如 steve-O 指出的,CAS 有其弱点(如 ABA 问题),因此这里需要内存屏障来确保 CAS 在多线程环境中仍然正确。另外,由于 CAS 需要三个参数:地址、旧值和新值,因此该过程需要现代 CPU。
编辑
使用新的C++0x标准(不是现在正式发布了?),那是不是说明JVM就不需要拆分了呢?至少,在源代码级别。二进制文件仍然可以被分割,但它将由 C++ 编译器处理。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
它是 CAS API 的 JNI 包装器,具有 >IA64架构。
编辑:对于 CAS 的描述:
将dest与比较值进行比较,如果它们匹配,则将交换值分配给< em>目的地。
这是一个原子操作,这意味着没有其他处理器可以更改dest的值当操作执行时。
这里列出了在没有原子操作的情况下可能发生的典型问题,“ABA 问题”
http://en.wikipedia。 org/wiki/ABA_problem
为什么要使用 CAS 函数?
简单的例子是计数器,如果您有多个线程递增计数器,请考虑递增过程的作用:
当另一个处理器时会发生什么读取值i 并在此处理器完成之前保存 i + 1?
最终得到的是 i + 1 而不是 i + 2。
It is a JNI wrapper for the CAS API, with memory barriers for IA64 architecture.
edit: for a description of CAS:
Compare dest with compare value and if they match assign exchange value to dest.
It is an atomic operation which means no other processor can change the value of dest whilst the operation executes.
Typical problems that can occur without atomic operations are listed here, the "ABA problem"
http://en.wikipedia.org/wiki/ABA_problem
Why would you use a CAS function?
Easy example is a counter, if you have multiple threads incrementing a counter consider what the increment process does:
What happens when another processor reads the value of i and saves i + 1 before this processor has completed?
You end up with i + 1 instead of i + 2.
一些解释
?
HotSpot 术语中的“oop”或“普通对象指针”是指向对象的托管指针。它通常与本机机器指针大小相同,这意味着 LP64 系统上为 64 位。在 ILP32 系统上,最大堆大小略小于 4Gb,这对于许多应用程序来说是不够的。
在 ILP32 模式 JVM 中,或者如果在 LP64 模式下关闭 UseCompressedOops 标志,则所有 oop 都是本机机器字大小。
如果 UseCompressedOops 为 true,则堆中的以下 oops 将被压缩:
• 每个对象的 klass 字段
•每个oop实例字段
• oop 数组 (objArray) 的每个元素
有关详细信息,请查看此 sun wiki
Here are some interprets about
An "oop", or "ordinary object pointer" in HotSpot parlance is a managed pointer to an object. It is normally the same size as a native machine pointer, which means 64 bits on an LP64 system. On an ILP32 system, there is a maximum heap size of somewhat less than 4Gb, which is not enough for many applications.
In an ILP32-mode JVM, or if the UseCompressedOops flag is turned off in LP64 mode, all oops are the native machine word size.
If UseCompressedOops is true, the following oops in the heap will be compressed:
•the klass field of every object
•every oop instance field
•every element of an oop array (objArray)
For details, looks into this sun wiki