任何人都可以将这个C ++代码(从OpenJDK6)解释为普通英语吗?

时间:2011-08-24 02:58:36

标签: c++ jvm java-native-interface openjdk compare-and-swap

以下是OpenJDK6's 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在这里被拆分了。

修改

正如史蒂夫-O所指出的那样,CAS有其作为ABA问题的弱点,因此这里需要内存屏障以确保CAS在多线程环境中仍然是正确的。此外,CAS需要三个参数,地址,旧值和新值,因此此过程需要现代CPU。

修改

使用新的C++0x standard(现在还没有正式发布?),这是否意味着JVM不需要被调整?至少,在源代码级别。二进制文件仍然可以拆分,但它将由C ++编译器处理。

2 个答案:

答案 0 :(得分:5)

它是CAS API的JNI包装器,memory barriersIA64 architecture

编辑了解CAS的说明:

dest 比较值进行比较,如果匹配,则将交换值 dest 匹配。

这是一个atomic operation,这意味着当操作执行时,没有其他处理器可以更改 dest 的值。

此处列出了没有原子操作可能发生的典型问题,即“ABA问题”

http://en.wikipedia.org/wiki/ABA_problem

为什么要使用CAS功能?

简单示例是一个计数器,如果您有多个线程递增计数器,请考虑增量过程的作用:

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

答案 1 :(得分:1)

以下是关于

的一些解释
  • 什么是oop,为什么要压缩它们?


HotSpot用语中的“oop”或“普通对象指针”是指向对象的托管指针。它通常与本机机器指针的大小相同,这意味着LP64系统上的64位。在ILP32系统上,最大堆大小略小于4Gb,这对于许多应用程序来说还不够。

  • 哪些oops被压缩了?

在ILP32模式JVM中,或者如果在LP64模式下关闭UseCompressedOops标志,则所有oops都是本机机器字大小。

如果UseCompressedOops为true,则将压缩堆中的以下oops:

•每个对象的klass字段 •每个oop实例字段 •oop数组的每个元素(objArray)

有关详细信息,请查看此sun wiki