当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的更多相关文章

  1. JVM 源码解读之 CMS 何时会进行 Full GC

    t点击上方"涤生的博客",关注我 转载请注明原创出处,谢谢!如果读完觉得有收获的话,欢迎点赞加关注. 前言 本文内容是基于 JDK 8 在文章 JVM 源码解读之 CMS GC 触 ...

  2. jvm源码解读--17 Java的wait()、notify()学习

    write and debug by 张艳涛 wait()和notify()的通常用法 A线程取得锁,执行wait(),释放锁; B线程取得锁,完成业务后执行notify(),再释放锁; B线程释放锁 ...

  3. jvm源码解读--04 常量池 常量项的解析CONSTANT_Class_info

    接上篇的继续 ConstantPool* constant_pool = ConstantPool::allocate(_loader_data, length, CHECK_(nullHandle) ...

  4. jvm源码解读--03 常量池的解析ConstantPool

    先看bt栈 (gdb) bt #0 ConstantPool::allocate (loader_data=0x7fe21802e868, length=87, __the_thread__=0x7f ...

  5. jvm源码解读--08 创建oop对象,将static静态变量放置在oop的96 offset处

    之前分析的已经加载的.Class文件中都没有Static 静态变量,所以也就没这部分的解析,自己也是不懂hotspot 将静态变量放哪里去了,追踪源码之后,看清楚了整个套路,总体上来说,可以举例来说对 ...

  6. jvm源码解读--12 invokspecial指令的解读

    先看代码 package com.zyt.jvmbook; public class Girl extends Person{ public Girl() { int a; } @Override p ...

  7. jvm源码解读--09 创建oop对象,将static静态变量放置在oop的96 offset处 第二篇

    先打断点systemDictionary.cpp 1915行 Universe::fixup_mirrors(CHECK); 进入 void Universe::fixup_mirrors(TRAPS ...

  8. C# ArrayPool 源码解读之 byte[] 池化

    一:背景 1. 讲故事最近在分析一个 dump 的过程中发现其在 gen2 和 LOH 上有不少size较大的free,仔细看了下,这些free生前大多都是模板引擎生成的html片段的byte[]数组 ...

  9. jvm源码解读--16 cas 用法解析

    CAS的意思是campare and sweep比较交换 这个如果不用代码会比较抽象,那么在源码中进行解释 void ATTR ObjectMonitor::enter(TRAPS) { // The ...

随机推荐

  1. .Net Core with 微服务 - Consul 注册中心

    上一次我们介绍了 Ocelot 网关的基本用法.这次我们开始介绍服务注册发现组件 Consul 的简单使用方法. 服务注册发现 首先先让我们回顾下服务注册发现的概念. 在实施微服务之后,我们的调用都变 ...

  2. TOP-5错误率

    TOP-5错误率是指每幅图像同时用5个类别标签进行预测:如果其中任何一次预测正确,就认为预测正确,如果5次预测的结果都错了,才认为预测错误,这时的分类错误率就是TOP-5错误率.

  3. 从零开始学架构(三)UML建模

    文章大纲 1.  文章介绍 2.  UML概述 3.  静态模型 4.  动态模型 5.  UML建模的一般过程 一.文章介绍 1.1为什么学习UML (1)UML是一种软件架构的模型表现方法,用于项 ...

  4. NOIP模拟测试23「mine·water·gcd」

    mine 题解 一道比较水的dp 考试因为初始化挂掉了只有$80$分 代码有注释 #include<bits/stdc++.h> using namespace std; //无脑dp # ...

  5. Linux定时任务-cronie

    1.cronie服务介绍 Linux crontab(cronie)是用来定期执行程序的命令. 当安装完成操作系统之后,默认就会启动此任务调度命令. crond 命令每分钟会定期检查是否有要执行的工作 ...

  6. 基于xtrabackup的主从同步

    基于xtrabackup的主从同步 作者 刘畅 时间 2020-9-21 服务器版本:CentOS Linux release 7.5.1804 主机名 ip地址 服务器配置 安装软件 密码 mysq ...

  7. 11、ssh自动化脚本编写

    11.1.如何一键自动化安装50台规模集群网站搭建: 1.自动化思路: kickstart无人值守安装linux系统(自动创建用户.密码.优化): 分发机上创建秘钥对.批量发走公钥(expect): ...

  8. 浅读tomcat架构设计之tomcat容器Container(3)

    浅读tomcat架构设计和tomcat启动过程(1) https://www.cnblogs.com/piaomiaohongchen/p/14977272.html 浅读tomcat架构设计之tom ...

  9. SpringBoot:SpringBoot项目的配置文件放在Jar包外加载

    SpringBoot读取配置文件的优先级为: 第一.项目jar包同级下的config文件夹是优先级最高的,是在执行命令的目录下建config文件夹.(在jar包的同一目录下建config文件夹,执行命 ...

  10. docker进入容器所在虚拟机的指令

    sudo docker inspect -f {{.State.Pid}} 44fc0f0582d9 在拿到该进程PID之后我们就可以使用nsenter命令访问该容器了. $ sudo nsenter ...