zoukankan      html  css  js  c++  java
  • 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 "253253253253253253253253253253253253253253253253205",
                                                                                   _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] = '';
        }
        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
  • 相关阅读:
    modprobe命令
    CentOS实验七:配置RPMForge软件源
    Makefile中的cd用法
    shell 脚本重定向【转】
    自动登陆CentOS
    用UltraISO制作启动光盘
    解决PATH中没有/sbin目录的问题
    Linux系统信息命令大全
    隐藏CentOS桌面图标
    IIS 操作必须使用一个可更新的查询的解决方法
  • 原文地址:https://www.cnblogs.com/zytcomeon/p/14592466.html
Copyright © 2011-2022 走看看