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 ...
随机推荐
- windows 7系统安装与配置Tomcat服务器环境
windows 7系统安装与配置Tomcat服务器环境 学习了一个月的java基础,终于要迈向java web领域.学习java web开发就离不开服务器的支持,由于本人是菜鸟,只好求助度娘谷哥.在此 ...
- MySQL的自增ID用完了,怎么办?
既然这块知识点不清楚,那回头就自己动手实践下. 首先,创建一个最简单的表,只包含一个自增id,并插入一条数据. create table t0(id int unsigned auto_increme ...
- SCP,SSH应用
- DOS命令行(3)——Windows运行窗口打开特定功能
cmd 开启命令解释权或启用Windows中的某程序 cmd /c 执行完命令后关闭命令窗口 cmd /k 执行完命令后不关闭命令窗口 winver 查看Windows版本信息版权信息授权信息 ...
- Java知识复习(四)
最近准备跳槽,又要好好复习基本知识了.过了个年,前面刚接触的springboot也只能先放放了.就先把自己复习了哪些罗列出来吧. Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用== ...
- Linux网络命令与脚本使用
作为系统管理员,经常需要诊断和解决网络问题,而配置.监控与保护网络有助于发现问题并在事情范围扩大前得意解决,并且网络的性能与安全也是管理与诊断网络的重要部分.这里总结一下常用与Linux网络管理的命令 ...
- OSPF路由协议
一.OSPF的工作过程 二.OSPF的基本概念 三.DR与BDR 四.OSPF数据包类型 五.OSPF邻接关系的建立 六.OSPF的路由器类型 一.OSPF的工作过程 OSPF路由协议针对每一个区域分 ...
- js更改HTML样式
<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content=&q ...
- Redis热点key优化
热门新闻事件或商品通常会给系统带来巨大的流量,对存储这类信息的Redis来说却是一个巨大的挑战.以Redis Cluster为例,它会造成整体流量的不均知,个别节点出现OPS过大的情况,极端情况下热点 ...
- 3.QT屏幕分辨率适配
需求:qt的窗口.组件.字体需要适配屏幕分辨率. 思路:qt是根据显示器的物理长度或者宽度于分辨率的关系来计算dpi 实现: #if(QT_VERSION >= QT_VERSION_CHECK ...