任何人都可以将这个C ++代码(来自OpenJDK6)解释为简单的英语? [英] Can anyone interpret this C++ code (from OpenJDK6) into plain English?

查看:212
本文介绍了任何人都可以将这个C ++代码(来自OpenJDK6)解释为简单的英语?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是来自 OpenJDK6的 hotspot / src / share / vm / prims / unsafe.cpp (从第1082行开始):

  // JSR166 ------------------------------ ------------------------------------ 

UNSAFE_ENTRY(jboolean,Unsafe_CompareAndSwapObject( JNIEnv * env,jobject unsafe,jobjectobj,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){
//编码交换和比较值从oop到T
narrowOop val = encode_heap_oop(exchange_value);
narrowOop cmp = encode_heap_oop(compare_value);

narrowOop old =(narrowOop)Atomic :: cmpxchg(val,(narrowOop *)dest,cmp);
//将old从T解码为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 会成为操作系统& CPU& 32bit / 64bit依赖。所以JVM在这里拆分。



EDIT



Steve-O指出, ABA问题,所以内存屏障在这里是必要的,以确保CAS在多线程环境中仍然正确。



EDIT p>

使用新的 C ++ 0x标准(不是正式发布吗?),这是否意味着JVM不需要spliited呢?至少,在源代码级别。二进制可以仍然拆分,但它将由C ++编译器处理。

解决方案

这是一个JNI封装器,用于 CAS API,并内存屏障对于 IA64架构



edit:以获取CAS的说明:



比较比较值匹配分配



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



这里列出了没有原子操作的典型问题:ABA问题



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



你使用CAS函数?



简单的例子是一个计数器,如果你有多个线程增加一个计数器考虑增量过程:

  int i; 
读取i
的值将一个值添加到当前值
将值保存回i。

当另一个处理器读取 i 的值并保存 > i + 1 ,而不是 i + 1 2 。


Here's a code snippet from OpenJDK6's hotspot/src/share/vm/prims/unsafe.cpp (starting on line 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

The key method oopDesc::atomic_compare_exchange_oop is added also.

 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);
      }
    }

What is the purpose of this code in the context of the JVM? I'm not experienced in C++.

Atomic::cmpxchg & Atomic::cmpxchg_ptr becomes OS & CPU & 32bit/64bit dependent. So JVMs are splitted here.

EDIT

As steve-O pointed out, CAS has its weakness as ABA problem, so memory barrier is necessary here to ensure the CAS is still correct in multithread environment. Also as CAS would need three paramter the address,old value and new value,so modern CPU is required for this process.

EDIT

With the new C++0x standard (not formal published now?) , does it mean that JVM don't need to be spliited then? At least, in the source code level. The binary could be still splitted but it will be handled by the C++ compiler.

解决方案

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:

int i;
read the value of i
add one to the current value
save the value back to i.

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.

这篇关于任何人都可以将这个C ++代码(来自OpenJDK6)解释为简单的英语?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆