目录
二、CompileBroker::compilation_init
三、CompileBroker::compiler_thread_loop
四、CompileBroker::compile_method
本篇博客接着上一篇《Hotspot 方法编译之CompileTask 源码解析》,上一篇讲解了表示编译任务的CompileTask,表示编译任务队列的CompileQueue,表示后台编译线程的CompilerThread和表示编译器实现的AbstractCompiler等CompileBroker依赖的类的实现,本篇博客通过讲解CompileBroker 的三个关键入口方法的实现将这些类的初始化和使用完整的串联起来,从而全面的了解方法编译的整体流程与实现。
一、CompileBroker 定义
CompileBroker定义在compileBroker.hpp中,表示一个负责接收并处理编译请求的经纪人,提供对外的编译相关的高度封装的方法。CompileBroker定义的属性都是静态属性,关键属性如下:
- _initialized/_should_block:bool,CompileBroker状态
- _should_compile_new_jobs:jint,打标用,用来表示是否停止编译或者开启编译
- _compilers:AbstractCompiler数组,长度固定为2,安装的编译器实例
- _compilation_id/_osr_compilation_id: jint,临时保存的编译ID
- _last_compile_type:int,上一次编译的编译类型,是一个枚举值,no_compile, normal_compile, osr_compile, native_compile
- _last_compile_level:int,上一次的编译级别
- _last_method_compiled:char数组,上一次编译的方法名
- _c2_compile_queue/_c1_compile_queue: CompileQueue*,C1和C2的编译任务队列
- _compiler_threads:GrowableArray<CompilerThread*>*,编译线程数组
除此之外还有统计编译次数等数据的PerfCounter,PerfVariable类的属性。
CompileBroker定义的public方法都是static方法,重点关注以下几个方法的实现。
二、CompileBroker::compilation_init
compilation_init方法负责初始化编译相关组件,包括编译器实现,编译线程,计数器等,其调用链如下:
其源码说明如下:
void CompileBroker::compilation_init() {
_last_method_compiled[0] = '\0';
//如果不使用编译
if (!UseCompiler) {
return;
}
//通常情况是定义COMPILER1和COMPILER2,不会定义SHARK
#ifndef SHARK
//最终返回CompilationPolicy中c1_count和c2_count属性的值,参考AdvancedThresholdPolicy::initialize()的实现
int c1_count = CompilationPolicy::policy()->compiler_count(CompLevel_simple);
int c2_count = CompilationPolicy::policy()->compiler_count(CompLevel_full_optimization);
//初始化Compiler
#ifdef COMPILER1
if (c1_count > 0) {
_compilers[0] = new Compiler();
}
#endif // COMPILER1
//初始化C2Compiler
#ifdef COMPILER2
if (c2_count > 0) {
_compilers[1] = new C2Compiler();
}
#endif // COMPILER2
#else // SHARK
int c1_count = 0;
int c2_count = 1;
_compilers[1] = new SharkCompiler();
#endif // SHARK
//初始化CompilerThreads和CompileQueue
init_compiler_threads(c1_count, c2_count);
//初始化性能统计相关计数器
{
EXCEPTION_MARK;
_perf_total_compilation =
PerfDataManager::create_counter(JAVA_CI, "totalTime",
PerfData::U_Ticks, CHECK);
}
if (UsePerfData) {
EXCEPTION_MARK;
_perf_osr_compilation =
PerfDataManager::create_counter(SUN_CI, "osrTime",
PerfData::U_Ticks, CHECK);
_perf_standard_compilation =
PerfDataManager::create_counter(SUN_CI, "standardTime",
PerfData::U_Ticks, CHECK);
}
_initialized = true;
}
void CompileBroker::init_compiler_threads(int c1_compiler_count, int c2_compiler_count) {
EXCEPTION_MARK;
#if !defined(ZERO) && !defined(SHARK)
//非SHARK且非ZERO编译模式下,要求c2_compiler_count或者c1_compiler_count大于0
assert(c2_compiler_count > 0 || c1_compiler_count > 0, "No compilers?");
#endif // !ZERO && !SHARK
// Initialize the compilation queue
if (c2_compiler_count > 0) {
//初始化CompileQueue
_c2_compile_queue = new CompileQueue("C2 CompileQueue", MethodCompileQueue_lock);
//设置编译线程数量
_compilers[1]->set_num_compiler_threads(c2_compiler_count);
}
if (c1_compiler_count > 0) {
_c1_compile_queue = new CompileQueue("C1 CompileQueue", MethodCompileQueue_lock);
_compilers[0]->set_num_compiler_threads(c1_compiler_count);
}
int compiler_count = c1_compiler_count + c2_compiler_count;
//初始化CompilerThread数组
_compiler_threads =
new (ResourceObj::C_HEAP, mtCompiler) GrowableArray<CompilerThread*>(compiler_count, true);
char name_buffer[256];
for (int i = 0; i < c2_compiler_count; i++) {
// Create a name for our thread.
sprintf(name_buffer, "C2 CompilerThread%d", i);
CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK);
//初始化指定数量的C2编译线程,将其添加到CompilerThread数组中
CompilerThread* new_thread = make_compiler_thread(name_buffer, _c2_compile_queue, counters, _compilers[1], CHECK);
_compiler_threads->append(new_thread);
}
for (int i = c2_compiler_count; i < compiler_count; i++) {
// Create a name for our thread.
sprintf(name_buffer, "C1 CompilerThread%d", i);
CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK);
//初始化指定数量的C1编译线程,将其添加到CompilerThread数组中
CompilerThread* new_thread = make_compiler_thread(name_buffer, _c1_compile_queue, counters, _compilers[0], CHECK);
_compiler_threads->append(new_thread);
}
if (UsePerfData) {
PerfDataManager::create_constant(SUN_CI, "threads", PerfData::U_Bytes, compiler_count, CHECK);
}
}
CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters,
AbstractCompiler* comp, TRAPS) {
CompilerThread* compiler_thread = NULL;
//获取java.lang.Thread对应的Klass
Klass* k =
SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(),
true, CHECK_0);
instanceKlassHandle klass (THREAD, k);
instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_0);
//创建一个java.lang.String
Handle string = java_lang_String::create_from_str(name, CHECK_0);
//获取system threadGroup 对应的Handle
Handle thread_group (THREAD, Universe::system_thread_group());
JavaValue result(T_VOID);
//实际调用Thread(ThreadGroup group, String name)构造方法创建一个新的Thread实例,实例保存到thr