jvm源码解读--05 常量池 常量项的解析JVM_CONSTANT_Utf8
当index=18的时候JVM_CONSTANT_Utf8
case JVM_CONSTANT_Utf8 :
{
cfs->guarantee_more(2, CHECK); // utf8_length
u2 utf8_length = cfs->get_u2_fast();
u1* utf8_buffer = cfs->get_u1_buffer();
assert(utf8_buffer != NULL, "null utf8 buffer");
// Got utf8 string, guarantee utf8_length+1 bytes, set stream position forward.
cfs->guarantee_more(utf8_length+1, CHECK); // utf8 string, tag/access_flags
cfs->skip_u1_fast(utf8_length); // Before storing the symbol, make sure it's legal
if (_need_verify) { //不进入
verify_legal_utf8((unsigned char*)utf8_buffer, utf8_length, CHECK);
} if (EnableInvokeDynamic && has_cp_patch_at(index)) { //不进入
Handle patch = clear_cp_patch_at(index);
guarantee_property(java_lang_String::is_instance(patch()),
"Illegal utf8 patch at %d in class file %s",
index, CHECK);
char* str = java_lang_String::as_utf8_string(patch());
// (could use java_lang_String::as_symbol instead, but might as well batch them)
utf8_buffer = (u1*) str;
utf8_length = (int) strlen(str);
} unsigned int hash; //has值 $35 = 1818100338
Symbol* result = SymbolTable::lookup_only((char*)utf8_buffer, utf8_length, hash); //$34 = (Symbol *) 0x7f258408b478
if (result == NULL) {
names[names_count] = (char*)utf8_buffer;
lengths[names_count] = utf8_length;
indices[names_count] = index;
hashValues[names_count++] = hash;
if (names_count == SymbolTable::symbol_alloc_batch_size) {
SymbolTable::new_symbols(_loader_data, _cp, names_count, names, lengths, indices, hashValues, CHECK);
names_count = 0;
}
} else {
_cp->symbol_at_put(index, result);
}
}
break;
//橘色的为Symbol,打印一下,看内容是什么
(gdb) p SymbolTable::_the_table
$32 = (SymbolTable *) 0x7f258002eab8
(gdb) p *SymbolTable::_the_table
$33 = (SymbolTable) {<Hashtable<Symbol*, 2304u>> = {<BasicHashtable<2304u>> = {<CHeapObj<2304u>> = {<AllocatedObj> = {_vptr.AllocatedObj = 0x7f2586b80af0 <vtable for SymbolTable+16>}, <No data fields>},
_table_size = 20011,
_buckets = 0x7f25876b3028,
_free_list = 0x0,
_first_free_entry = 0x7f25800519b8 "\361\..."
<incomplete sequence \361>..., _end_block = 0x7f2580054598 "\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\205",
_entry_size = 32,
_number_of_entries = 672,
_lookup_count = 0,
_lookup_length = 0},
static _seed = <optimized out>},
static _the_table = 0x7f258002eab8,
static _needs_rehashing = false,
static symbols_removed = 0,
static symbols_counted = 0,
static _arena = 0x7f258002eb28}
//里面是一个Hashtable,哈希表,里面有桶的
接着进入紫色的
void symbol_at_put(int which, Symbol* s) {
assert(s->refcount() != 0, "should have nonzero refcount");
tag_at_put(which, JVM_CONSTANT_Utf8);
*symbol_at_addr(which) = s;
} Symbol** symbol_at_addr(int which) const {
assert(is_within_bounds(which), "index out of bounds");
return (Symbol**) &base()[which];
}
打印一下这个Symbol
(gdb) p sizeof(Symbol)
$36 = 12 $38 = {<SymbolBase> = {<MetaspaceObj> = {<No data fields>}, _length = 6, _refcount = -1, _identity_hash = 1186001213},
_body = {60 '<'},
static _total_count = 0}
以上就完成了 JVM_CONSTANT_Utf8 的解析
查看经常用的函数p s->as_C_string()
char* Symbol::as_C_string() const {
int len = utf8_length();
char* str = NEW_RESOURCE_ARRAY(char, len + 1);
return as_C_string(str, len + 1);
}
int utf8_length() const { return _length; }
//
其中_length定义在SymbolBase的类中
class SymbolBase : public MetaspaceObj {
public:
ATOMIC_SHORT_PAIR(
volatile short _refcount, // needs atomic operation
unsigned short _length // number of UTF8 characters in the symbol (does not need atomic op)
);
int _identity_hash;
};
接着
char* Symbol::as_C_string(char* buf, int size) const {
if (size > 0) {
int len = MIN2(size - 1, utf8_length());
for (int i = 0; i < len; i++) {
buf[i] = byte_at(i);
}
buf[len] = '\0';
}
return buf;
}
int byte_at(int index) const {
assert(index >=0 && index < _length, "symbol index overflow");
return base()[index];
} const jbyte* base() const { return &_body[0]; } jbyte _body[1];
说明Symbol这个类,字符在_body字段中,长度在父类中
去符号表中查找,符号表实例,所以常量池中存储的是Symbol* 指针;
(gdb) p SymbolTable::_the_table
$32 = (SymbolTable *) 0x7f258002eab8
(gdb) p *SymbolTable::_the_table
jvm源码解读--05 常量池 常量项的解析JVM_CONSTANT_Utf8的更多相关文章
- JVM 源码解读之 CMS 何时会进行 Full GC
t点击上方"涤生的博客",关注我 转载请注明原创出处,谢谢!如果读完觉得有收获的话,欢迎点赞加关注. 前言 本文内容是基于 JDK 8 在文章 JVM 源码解读之 CMS GC 触 ...
- jvm源码解读--17 Java的wait()、notify()学习
write and debug by 张艳涛 wait()和notify()的通常用法 A线程取得锁,执行wait(),释放锁; B线程取得锁,完成业务后执行notify(),再释放锁; B线程释放锁 ...
- jvm源码解读--04 常量池 常量项的解析CONSTANT_Class_info
接上篇的继续 ConstantPool* constant_pool = ConstantPool::allocate(_loader_data, length, CHECK_(nullHandle) ...
- jvm源码解读--03 常量池的解析ConstantPool
先看bt栈 (gdb) bt #0 ConstantPool::allocate (loader_data=0x7fe21802e868, length=87, __the_thread__=0x7f ...
- jvm源码解读--08 创建oop对象,将static静态变量放置在oop的96 offset处
之前分析的已经加载的.Class文件中都没有Static 静态变量,所以也就没这部分的解析,自己也是不懂hotspot 将静态变量放哪里去了,追踪源码之后,看清楚了整个套路,总体上来说,可以举例来说对 ...
- jvm源码解读--12 invokspecial指令的解读
先看代码 package com.zyt.jvmbook; public class Girl extends Person{ public Girl() { int a; } @Override p ...
- jvm源码解读--09 创建oop对象,将static静态变量放置在oop的96 offset处 第二篇
先打断点systemDictionary.cpp 1915行 Universe::fixup_mirrors(CHECK); 进入 void Universe::fixup_mirrors(TRAPS ...
- C# ArrayPool 源码解读之 byte[] 池化
一:背景 1. 讲故事最近在分析一个 dump 的过程中发现其在 gen2 和 LOH 上有不少size较大的free,仔细看了下,这些free生前大多都是模板引擎生成的html片段的byte[]数组 ...
- jvm源码解读--16 cas 用法解析
CAS的意思是campare and sweep比较交换 这个如果不用代码会比较抽象,那么在源码中进行解释 void ATTR ObjectMonitor::enter(TRAPS) { // The ...
随机推荐
- python学习笔记05-条件分支与循环1
思考问题:100分制,90分以上为A,80-90为B,60-80为C,60以下为D,当用户输入成绩后,打印对应的字母 temp=input('请输入你的成绩:') score=int(temp) if ...
- Windows的静态库与动态库
Windows的静态库与动态库 1.静态库 1.1 静态库特点 运行不存在 静态库源码被链接到调用程序中 目标程序的归档 1.2 C语言静态库 C静态库的创建 创建一个静态库项目. 添加库程序,源文件 ...
- Centos8.3、mysql8.0主从复制实战记录
引言 最近又上线了一个项目,感觉自己这段时间收获不少就想把自己做这个项目用的技术总结梳理一下.这个项目是我自己发起,领导们不是特别重视所以得到资源有限,资源有限的情况我只能选择手动搭建数据库环境,资源 ...
- js笔记12
1.元素的属性 div.attributes是所有标签属性构成的数组集合 div.classList是所有class名构成的数组集合 在classList的原型链上可以看到add()和remove() ...
- golang变量与常量
变量 变量 在程序运行中可以改变的量 枚举 var ( a3 = 1 a4 = 2 ) golang不同类型变量不能替换 func main() { var a int = 10 a = 20 a = ...
- 乘风破浪,Windows11设计和开发指导,全新图标字体和云母材质
Windows11全新的布局设计 Windows 11全新的布局设计已设计为支持现代应用体验.渐进的圆角.嵌套元素和一致的排水沟相结合,营造出柔和.平静.平易近人的效果,强调目的的统一和易用性. ht ...
- 关于LCA的几点想法
倍增 这是最最最常见的写法了,一个fa[N][logN]的数组直接搞定 时间复杂度也不算太高 预处理 $ O(nlogn) $ 如果你想卡的话,可以卡到 $ O(nlogh) $ h为树的深度 查询 ...
- HDU 4292 Food 多源多汇入门题
Food 有F种食物和D种饮料,每种食物或饮料只能供有限次,且每个人只享用一种食物和一种饮料.现在有n个人,每个人都有自己喜欢的食物种类列表和饮料种类列表,问最多能使几个人同时享用到自己喜欢的食物和饮 ...
- AcWing 99. 激光炸弹
地图上有n个目标,用整数x,y表示目标在地图上的位置,每个目标都有一个价值Wi. 注意:不同目标可能在同一位置. 现在有一种新型的激光炸弹,可以摧毁一个包含r个位置的正方形内的所有目标. 激光炸弹的投 ...
- Hibernate框架(三)框架中的关系映射
在设计数据库时我们会考虑,表与表之间的关系,例如我们前边经常提到的一对一,一对多,多对多关系,在数据库中我们通过外键,第三张表等来实现这些关系.而Hibernate时间实体类和数据库中的表进行的映射, ...