类元数据++java_JVM里面的 mirror类 与 类的元数据有什么联系和区别?

这里JNI返回的实际是间接引用,不是object对象地址.

比如这里返回的jclass是0x5c6, 这个间接引用实际代表的object是0x732359f8

template

inline T JNIEnvExt::AddLocalReference(mirror::Object* obj) {

IndirectRef ref = locals.Add(local_ref_cookie, obj);

return reinterpret_cast(ref);

}

local.Add()的实现为

87IndirectRef IndirectReferenceTable::Add(uint32_t cookie, mirror::Object* obj) {

88 IRTSegmentState prevState;

89 prevState.all = cookie;

90 size_t topIndex = segment_state_.parts.topIndex;

91

92 CHECK(obj != NULL);

93 VerifyObject(obj);

94 DCHECK(table_ != NULL);

95 DCHECK_GE(segment_state_.parts.numHoles, prevState.parts.numHoles);

96

97 if (topIndex == max_entries_) {

98 LOG(FATAL) << "JNI ERROR (app bug): " << kind_ << " table overflow "

99 << "(max=" << max_entries_ << ")\n"

100 << MutatorLockedDumpable(*this);

101 }

102

103 // We know there's enough room in the table. Now we just need to find

104 // the right spot. If there's a hole, find it and fill it; otherwise,

105 // add to the end of the list.

106 IndirectRef result;

107 int numHoles = segment_state_.parts.numHoles - prevState.parts.numHoles;

108 size_t index;

109 if (numHoles > 0) {

110 DCHECK_GT(topIndex, 1U);

111 // Find the first hole; likely to be near the end of the list.

112 IrtEntry* pScan = &table_[topIndex - 1];

113 DCHECK(!pScan->GetReference()->IsNull());

114 --pScan;

115 while (!pScan->GetReference()->IsNull()) {

116 DCHECK_GE(pScan, table_ + prevState.parts.topIndex);

117 --pScan;

118 }

119 index = pScan - table_;

120 segment_state_.parts.numHoles--;

121 } else {

122 // Add to the end.

123 index = topIndex++;

124 segment_state_.parts.topIndex = topIndex;

125 }

126 table_[index].Add(obj);

127 result = ToIndirectRef(index);

128 if (false) {

129 LOG(INFO) << "+++ added at " << ExtractIndex(result) << " top=" << segment_state_.parts.topIndex

130 << " holes=" << segment_state_.parts.numHoles;

131 }

132

133 DCHECK(result != NULL);

134 return result;

135}

里面最重要的转换如下:

result = ToIndirectRef(index);

函数实现如下:

364 IndirectRef ToIndirectRef(uint32_t tableIndex) const {

365 DCHECK_LT(tableIndex, 65536U);

366 uint32_t serialChunk = table_[tableIndex].GetSerial();

367 uintptr_t uref = (serialChunk << 20) | (tableIndex << 2) | kind_;

368 return reinterpret_cast(uref);

369 }

看到这里就一目了然了实际对象存储在IndirectReferenceTable的table_[]数组中

返回的jClass实际是serial/table_idx/ref type三者的OR值

举例如下

0x74deaa3000:0x000000010x7012e9100x6fb9d7200x00000000

0x74deaa3010:0x000000020x000000000x6fbd6d200x732333c8

0x74deaa3020:0x000000000x732358880x6fba70b80x6fbd3ca0

0x74deaa3030:0x000000000x732358c00x6fb4c3c80x6fbbb758

table_中每条entry四个word,第1个word是serial,表示当前正在使用的index(0/1/2)

后面3个word用于存储实际的object, 具体使用哪个由前面的serial指定

黑体部分表示当前使用的object

下次使用时,再通过ExtractIndex()转换回来,就使用到真正的object了.

另外,art/mirror/下面的很多类实际就是Java类的c++版本实现, 供ART虚拟机使用.

Java对象的内存布局以art::mirror里面声明的成员的顺序依次进行存储,成员的大小是一致的,但声明顺序有可能不同.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值