您的位置:首页 > 编程语言 > Java开发

java 原子操作在x86下的实现

2011-06-26 23:29 274 查看
JVM 6里面可以看到很多的CAS的操作,而我们来看看JVM里面是怎么实现CAS的操作,至于原子操作的语义在这里我们就不介绍了

核心java源码是unsafe.java

compareAndSwapObject

compareAndSwapInt

compareAndSwapLong

。。。。

具体我们主要来看看 如何实现compareAndSwapObject的方法

unsafe.cpp

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


首先通过offset找到object 里的所要修改的field 的地址,接着就是在这个地址上内容交换,这里的要改变的内容实际上就是object的地址。

oopDesc::atomic_compare_exchange_oop

其中对压缩的object的地址重新计算,在opp.inline.hpp的文件中

inline narrowOop oopDesc::encode_heap_oop_not_null(oop v) {
assert(!is_null(v), "oop value can never be zero");
assert(check_obj_alignment(v), "Address not aligned");
assert(Universe::heap()->is_in_reserved(v), "Address not in heap");
address base = Universe::narrow_oop_base();
int    shift = Universe::narrow_oop_shift();
uint64_t  pd = (uint64_t)(pointer_delta((void*)v, (void*)base, 1));
assert(OopEncodingHeapMax > pd, "change encoding max if new encoding");
uint64_t result = pd >> shift;
assert((result & CONST64(0xffffffff00000000)) == 0, "narrow oop overflow");
assert(decode_heap_oop(result) == v, "reversibility");
return (narrowOop)result;
}


让我们看看最后在x86里面linux下所调用的原子指令,在c++里面使用内联汇编,定义在atomic_linux_x86.include.hpp里

inline jlong    Atomic::cmpxchg    (jlong    exchange_value, volatile jlong*    dest, jlong    compare_value) {
bool mp = os::is_MP();
__asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)"
: "=a" (exchange_value)
: "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
: "cc", "memory");
return exchange_value;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: