unsafe类的getAndSetInt方法探索

起因:了解java层面的unsafe类跟unsafe.cpp是如何对应的

getAndSetInt类的方法为

    public final int getAndSetInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var4));

        return var5;
    }

    public native int getIntVolatile(Object var1, long var2);

    public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

可以看到getAndSetInt方法中调用的两个方法均为native方法

直接粘getIntVolatile去unsafe.cpp文件中搜索不到,按道理说是不应该的,而后通过查资料了解到

/*
 * used in RegisterNatives to describe native method name, signature,
 * and function pointer.
 */
在注册表中用于描述本地方法名称、签名、和函数指针。

typedef struct {
    char *name;
    char *signature;
    void *fnPtr;
} JNINativeMethod;

JNINativeMethod结构定义了一个本地方法

再往下定义了一些常量,目的猜测是为了减少重复的写

/// JVM_RegisterUnsafeMethods

#define ADR "J"

#define LANG "Ljava/lang/"

#define OBJ LANG"Object;"
#define CLS LANG"Class;"
#define CTR LANG"reflect/Constructor;"
#define FLD LANG"reflect/Field;"
#define MTH LANG"reflect/Method;"
#define THR LANG"Throwable;"

#define DC0_Args LANG"String;[BII"
#define DC_Args  DC0_Args LANG"ClassLoader;" "Ljava/security/ProtectionDomain;"

#define CC (char*)  /*cast a literal from (const char*)*/
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)

之后还有个这样的模板定义,目的Boolean和Z均自定义

// Note:  In 1.5.0, there are volatile versions too
#define DECLARE_GETSETOOP(Boolean, Z) \
    {CC"get"#Boolean,      CC"("OBJ"J)"#Z,      FN_PTR(Unsafe_Get##Boolean)}, \
    {CC"put"#Boolean,      CC"("OBJ"J"#Z")V",   FN_PTR(Unsafe_Set##Boolean)}, \
    {CC"get"#Boolean"Volatile",      CC"("OBJ"J)"#Z,      FN_PTR(Unsafe_Get##Boolean##Volatile)}, \
    {CC"put"#Boolean"Volatile",      CC"("OBJ"J"#Z")V",   FN_PTR(Unsafe_Set##Boolean##Volatile)}

上面对应的方法是

UNSAFE_ENTRY(jboolean, Unsafe_Get##Boolean(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) \
  UnsafeWrapper("Unsafe_Get"#Boolean); \
  GET_FIELD(obj, offset, jboolean, v); \
  return v; \
UNSAFE_END \
 \
UNSAFE_ENTRY(void, Unsafe_Set##Boolean(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jboolean x)) \
  UnsafeWrapper("Unsafe_Set"#Boolean); \
  SET_FIELD(obj, offset, jboolean, x); \
UNSAFE_END \
 \
// END DEFINE_GETSETOOP.


#define DEFINE_GETSETOOP_VOLATILE(jboolean, Boolean) \
 \
UNSAFE_ENTRY(jboolean, Unsafe_Get##Boolean##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) \
  UnsafeWrapper("Unsafe_Get"#Boolean); \
  GET_FIELD_VOLATILE(obj, offset, jboolean, v); \
  return v; \
UNSAFE_END \
 \
UNSAFE_ENTRY(void, Unsafe_Set##Boolean##Volatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jboolean x)) \
  UnsafeWrapper("Unsafe_Set"#Boolean); \
  SET_FIELD_VOLATILE(obj, offset, jboolean, x); \
UNSAFE_END \
 \
// END DEFINE_GETSETOOP_VOLATILE.

最后调用GET_FIELD_VOLATILE来获取

inline jint     OrderAccess::load_acquire(volatile jint*    p) { return *p; }

只是用c语言的volatitle修饰了下 然后直接返回了

至此结束

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半块橘子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值