在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);
}
因此,此处的代码做了三件事:
-
建立symbolOop
-
获得基本类型所对应的symbolOop.分别如下:
“B”
“C”
“D”
“F”
“I”
“J”
“S”
“Z”
“V”
```
3. 对vm_symbol_index 进行快排,生成索引