起因:了解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修饰了下 然后直接返回了
至此结束
|