类加载流程005

在jvm初始化的时候,会调用Universe::genesis(Thread* the_thread),在该方法中,会创建一系列klassOop,这点在之前的博客中都有介绍.接下来,执行如下代码:

vmSymbols::initialize(CHECK);

SystemDictionary::initialize(CHECK); //  这里会创建java/lang/Object,java/lang/Class等类

本文就首先介绍一下vmSymbols::initialize(CHECK).

解析

vmSymbols的类图如下:

在这里插入图片描述
此外,该类还定义了一个枚举,用于计算包含symbolOops的数组的位置和大小.代码如下:

enum SID {
    NO_SID = 0,

    #define VM_SYMBOL_ENUM(name, string) VM_SYMBOL_ENUM_NAME(name),
    VM_SYMBOLS_DO(VM_SYMBOL_ENUM, VM_ALIAS_IGNORE)
    #undef VM_SYMBOL_ENUM

    SID_LIMIT,

    #define VM_ALIAS_ENUM(name, def) VM_SYMBOL_ENUM_NAME(name) = VM_SYMBOL_ENUM_NAME(def),
    VM_SYMBOLS_DO(VM_SYMBOL_IGNORE, VM_ALIAS_ENUM)
    #undef VM_ALIAS_ENUM

    FIRST_SID = NO_SID + 1
};

可以看到,这里用到了宏,第一个宏展开的结果如下:

  java_lang_System_enum,                         \
  java_lang_Object_enum,                         \
  java_lang_Class_enum,                          \
  java_lang_String_enum,                         \
  java_lang_StringValue_enum,                    \
  java_lang_StringCache_enum,        \
  java_lang_Thread_enum,                         \
  java_lang_ThreadGroup_enum,                    \
  java_lang_Cloneable_enum,  
  
  ......

第二个宏展开的结果如下:

register_method_signature_enum = object_void_signature_enum,
putOrderedLong_signature_enum = putLong_signature_enum,
appendToClassPathForInstrumentation_signature_enum = string_void_signature_enum,  
...

此外,在vmSymbols.hpp中,有如下代码:

  #define VM_SYMBOL_DECLARE(name, ignore) \
    static symbolOop name() { return _symbols[VM_SYMBOL_ENUM_NAME(name)]; }
  VM_SYMBOLS_DO(VM_SYMBOL_DECLARE, VM_SYMBOL_DECLARE)
  #undef VM_SYMBOL_DECLARE

宏展开,结果如下:

static symbolOop java_lang_System() { return _symbols[java_lang_System_enum]; }                         \
  static symbolOop java_lang_Object() { return _symbols[java_lang_Object_enum]; }                         \
  static symbolOop java_lang_Class() { return _symbols[java_lang_Class_enum]; }                          \
  static symbolOop java_lang_String() { return _symbols[java_lang_String_enum]; }                         \
  static symbolOop java_lang_StringValue() { return _symbols[java_lang_StringValue_enum]; }                    \
  static symbolOop java_lang_StringCache() { return _symbols[java_lang_StringCache_enum]; }        \
  static symbolOop java_lang_Thread() { return _symbols[java_lang_Thread_enum]; } 
  
  .....   

此外,在vmSymbols.cpp中有如下代码:

#define VM_SYMBOL_BODY(name, string) string "\0"
static const char* vm_symbol_bodies = VM_SYMBOLS_DO(VM_SYMBOL_BODY, VM_ALIAS_IGNORE);

此处,宏展开后如下:

static const char* vm_symbol_bodies = "java/lang/System" "\0"                         \
  "java/lang/Object" "\0"                         \
  "java/lang/Class" "\0"                          \
  "java/lang/String" "\0"                         \
  "java/lang/StringValue" "\0"                    \
  "java/lang/StringValue$StringCache" "\0"        \
  "java/lang/Thread" "\0"                         \
  "java/lang/ThreadGroup" "\0"                    \
  "java/lang/Cloneable" "\0"                      \
  "java/lang/Throwable" "\0"                      \
  "java/lang/ClassLoader" "\0"                    \
  "java/lang/ClassLoader\x024NativeLibrary" "\0"  \
  "java/lang/ThreadDeath" "\0"                    \
  "java/lang/Boolean" "\0"                        \
  "java/lang/Character" "\0"                      \
  "java/lang/Character$CharacterCache" "\0"       \
  ......

在vmSymbols::initialize中,代码如下:

  if (!UseSharedSpaces) {// 宏展开为false
    const char* string = &vm_symbol_bodies[0];
    for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
       // 建立符号
      symbolOop sym = oopFactory::new_symbol(string, CHECK);
      _symbols[index] = sym;
      string += strlen(string); // skip string body 跳过字符串中的内容
      string += 1;              // skip trailing null 跳过空字符
    }

    _type_signatures[T_BYTE]    = byte_signature(); // == return _symbols[byte_signature_enum]; 等于 byte_signature_enum 所对应的符号
    _type_signatures[T_CHAR]    = char_signature(); // char_signature_enum
    _type_signatures[T_DOUBLE]  = double_signature();
    _type_signatures[T_FLOAT]   = float_signature();
    _type_signatures[T_INT]     = int_signature();
    _type_signatures[T_LONG]    = long_signature();
    _type_signatures[T_SHORT]   = short_signature();
    _type_signatures[T_BOOLEAN] = bool_signature();
    _type_signatures[T_VOID]    = void_signature();
    // no single signatures for T_OBJECT or T_ARRAY
  }
  
   {
    for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
      vm_symbol_index[index] = (SID)index;
    }
    int num_sids = SID_LIMIT-FIRST_SID;
    // 快排,按照地址进行比较
    qsort(&vm_symbol_index[FIRST_SID], num_sids, sizeof(vm_symbol_index[0]),
          compare_vmsymbol_sid);
  }

因此,此处的代码做了三件事:

  1. 建立symbolOop

  2. 获得基本类型所对应的symbolOop.分别如下:

“B”
“C”
“D”
“F”
“I”
“J”
“S”
“Z”
“V”
```
3. 对vm_symbol_index 进行快排,生成索引

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值