jni如何获取hotspot中的oop结构体
Java jni 中:
环境:Mac M1 arm64 jdk17
问题描述:
传递Java 对象obj到native C++层时,C++收到的参数是obj
但是我两次分别传递不同对象时,发现obj的值和其地址都是相同的
我向其传递null空指针,obj也为NULL
按理说,obj是我传递的对象的引用,应该会随着我传递不同对象而发生改变,但是现在没有,请问这是为什么?
希望:传入不同对象返回不同对象的地址
本地方法:
public static native long getAddress(Object obj);
C++代码
#include "address_NativeLibrary.h"
#include <iostream>
JNIEXPORT jlong JNICALL Java_address_NativeLibrary_getAddress
(JNIEnv * env, jclass jclazz, jobject obj){
if(obj== NULL) {
std::cout << "obj 为空!!" << obj << std::endl;
return -1;
}
std::cout << " "<< obj << " ";
std::cout << " "<< &obj << " ";
long ret = (long)(&obj);
return ret;
}
调用代码
package address;
public class Main {
public static void main(String[] args) {
Integer a = 21;
Integer b = 21;
NativeLibrary.getAddress(a);
NativeLibrary.getAddress(b);
}
}
运行结果:(没有换行,我换个行,更直观)
0x16b962b08 0x16b962a50
0x16b962b08 0x16b962a50
我看到Object 类 hashCode native的源码中是可以获取到地址的
static inline intptr_t get_next_hash(Thread* current, oop obj) {
intptr_t value = 0;
if (hashCode == 0) {
// This form uses global Park-Miller RNG.
// On MP system we'll have lots of RW access to a global, so the
// mechanism induces lots of coherency traffic.
value = os::random();
} else if (hashCode == 1) {
// This variation has the property of being stable (idempotent)
// between STW operations. This can be useful in some of the 1-0
// synchronization schemes.
intptr_t addr_bits = cast_from_oop<intptr_t>(obj) >> 3;
value = addr_bits ^ (addr_bits >> 5) ^ GVars.stw_random;
} else if (hashCode == 2) {
value = 1; // for sensitivity testing
} else if (hashCode == 3) {
value = ++GVars.hc_sequence;
} else if (hashCode == 4) {
value = cast_from_oop<intptr_t>(obj);
} else {
// Marsaglia's xor-shift scheme with thread-specific state
// This is probably the best overall implementation -- we'll
// likely make this the default in future releases.
unsigned t = current->_hashStateX;
t ^= (t << 11);
current->_hashStateX = current->_hashStateY;
current->_hashStateY = current->_hashStateZ;
current->_hashStateZ = current->_hashStateW;
unsigned v = current->_hashStateW;
v = (v ^ (v >> 19)) ^ (t ^ (t >> 8));
current->_hashStateW = v;
value = v;
}
value &= markWord::hash_mask;
if (value == 0) value = 0xBAD;
assert(value != markWord::no_hash, "invariant");
return value;
}
这里当hashCode为4时返回的就是Java对象的地址,我通过jdk中的jhsdb工具验证了
但是oop结构体好像拿不到
Objec hashCode源码参考连接:https://www.yuque.com/yuqueyonghu1o4dun/uh2m8v/iwgwirqq7zrfvx2w?singleDoc# 《JNI (Java Native Interface)》