上一篇主要分析了HotSpot模板解释器和汇编器的实现,相比于c解释器,通过汇编器和模板解释器将字节码指令编译成汇编指令,显著提升了HotSpot的性能。除此之外HotSpot更进一步实现了C1,C2编译器用于在服务端选择性的进一步编译优化指令。提供了Tiered分层编译,内置LLVM,AOT编译等,此外基于Java语言实现的 GraalVm 全栈编译器也势头强劲。
一.初始化C1编译器
hotspot/src/share/vm/runtime/thread.cpp
创建HotSpot虚拟机时会初始化编译器
jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
CompileBroker::compilation_init(CHECK_JNI_ERR);
}
hotspot/src/share/vm/compiler/compileBroker.cpp
void CompileBroker::compilation_init(TRAPS) {
init_compiler_sweeper_threads(c1_count, c2_count);
}
hotspot/src/share/vm/compiler/compileBroker.cpp
按c1_compiler_count值创建多个编译线程,线程持有编译任务队列
void CompileBroker::init_compiler_sweeper_threads(int c1_compiler_count, int c2_compiler_count) {
_c1_compile_queue = new CompileQueue("C1 compile queue");
for (int i = 0; i < c1_compiler_count; i++) {
CompilerCounters* counters = new CompilerCounters();
make_thread(name_buffer, _c1_compile_queue, counters, _compilers[1], compiler_thread, CHECK);
}
}
hotspot/src/share/vm/compiler/compileBroker.cpp
JavaThread* CompileBroker::make_thread(const char* name, CompileQueue* queue, CompilerCounters* counters,
AbstractCompiler* comp, bool compiler_thread, TRAPS) {
thread = new CompilerThread(queue, counters);
Thread::start(thread);
}
hotspot/src/share/vm/runtime/thread.cpp
初始化编译线程时挂载一个执行函数compiler_thread_entry
CompilerThread::CompilerThread(CompileQueue* queue,
CompilerCounters* counters)
: JavaThread(&compiler_thread_entry) {
_queue = queue;
_counters = counters;
_buffer_blob = NULL;
_compiler = NULL;
}
hotspot/src/share/vm/runtime/thread.cpp
执行函数会在线程创建完成之后调用compiler_thread_loop,通知编译器开始线程循环
static void compiler_thread_entry(JavaThread* thread, TRAPS) {
CompileBroker::compiler_thread_loop();
}
hotspot/src/share/vm/compiler/compileBroker.cpp
while循环执行,从任务队列中取出已提交的编译任务,调用invoke_compiler_on_method派发编译
void CompileBroker::compiler_thread_loop() {
CompilerThread* thread = CompilerThread::current();
CompileQueue* queue = thread->queue();
//初始化编译环境
init_compiler_runtime()
//循环从编译任务队列里取编译任务并执行
while (!is_compilation_disabled_forever()) {
CompileTask* task = queue->get();
// Assign the task to the current thread. Mark this compilation
// thread as active for the profiler.
CompileTaskWrapper ctw(task);
nmethodLocker result_handle; // (handle for the nmethod produced by this task)
task->set_code_handle(&result_handle);
methodHandle method(thread, task->method());
//......
//编译任务
invoke_compiler_on_method(task);
//......
// Shut down compiler runtime
shutdown_compiler_runtime(thread->compiler(), thread);
}
hotspot/src/share/vm/compiler/compileBroker.cpp
收到编译任务后,从task取出对应需要使用的编译器,调用compile_method
void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
CompilerThread* thread = CompilerThread::current();
uint compile_id = task->compile_id();
int osr_bci = task->osr_bci();
bool is_osr = (osr_bci != standard_entry_bci);
const int task_level = task->comp_level();
AbstractCompiler* comp = task->compiler();
methodHandle method(thread, task->method());
// Allocate a new set of JNI handles.
push_jni_handle_block();
Method* target_handle = task->method();
int compilable = ciEnv::MethodCompilable;
{
ciEnv ci_env(task, system_dictionary_modification_counter);
//执行编译
comp->compile_method(&ci_env, target, osr_bci, directive);
// Copy this bit to the enclosing block:
compilable = ci_env.compilable();
post_compile(thread, task, event, !ci_env.failing(), &ci_env);
}
// Remove the JNI handle block after the ciEnv destructor has run in
// the previous block.
pop_jni_handle_block();
// Disable compilation, if required.
switch (compilable) {
case ciEnv::MethodCompilable_never:
if (is_osr)
method->set_not_osr_compilable_quietly();
else
method->set_not_compilable_quietly();
break;
case ciEnv::MethodCompilable_not_at_tier:
if (is_osr)
method->set_not_osr_compilable_quietly(task_level);
else
method->set_not_compilable_quietly(task_level);
break;
}
}
hotspot/src/share/vm/c1/c1_Compiler.cpp
执行Compilation初始化,Compilation构造函数将调用compile_method
void Compiler::compile_method(ciEnv* env, ciMethod* method, int entry_bci, DirectiveSet* directive) {
BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob();
Compilation c(this, env, method, entry_bci, buffer_blob, directive);
}
二.触发和提交编译任务
hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp
编译器环境初始化好以后循环等待编译任务到来,HosSpot中在generate_normal_entry这个entry_point会埋点统计当前方法的执行次数,当方法执行次数超过指定阀值时会触发JIT
address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
......
// Handle overflow of counter and compile method
__ bind(invocation_counter_overflow);
generate_counter_overflow(continue_after_compile);
}
hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp
void TemplateInterpreterGenerator::generate_counter_overflow(Label& do_continue) {
__ call_VM(noreg,CAST_FROM_FN_PTR(address,InterpreterRuntime::frequency_counter_overflow),rarg);
__ movptr(rbx, Address(rbp, method_offset)); // restore Method*
__ jmp(do_continue, relocInfo::none);
}
hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
nmethod* InterpreterRuntime::frequency_counter_overflow(JavaThread* thread, address branch_bcp) {
nmethod* nm = frequency_counter_overflow_inner(thread, branch_bcp);
}
hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
触发编译执行策略
IRT_ENTRY(nmethod*,InterpreterRuntime::frequency_counter_overflow_inner(JavaThread* thread, address branch_bcp))
nmethod* osr_nm = CompilationPolicy::policy()->event(method, method, branch_bci, bci, CompLevel_none, NULL, thread);
hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp
nmethod* SimpleThresholdPolicy::event(const methodHandle& method, const methodHandle& inlinee,
int branch_bci, int bci, CompLevel comp_level, CompiledMethod* nm, JavaThread* thread) {
method_back_branch_event(method, inlinee, bci, comp_level, nm, thread);
}
hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp
void AdvancedThresholdPolicy::method_back_branch_event(const methodHandle& mh, const methodHandle& imh,
int bci, CompLevel level, CompiledMethod* nm, JavaThread* thread) {
compile(mh, InvocationEntryBci, next_level, thread);
}
hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp
提交编译
void SimpleThresholdPolicy::compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
submit_compile(mh, bci, level, thread);
}
hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp
void AdvancedThresholdPolicy::submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
update_rate(os::javaTimeMillis(), mh());
CompileBroker::compile_method(mh, bci, level, mh, hot_count, CompileTask::Reason_Tiered, thread);
}
hotspot/src/share/vm/compiler/compileBroker.cpp
nmethod* CompileBroker::compile_method(const methodHandle& method, ...) {
compile_method_base(method, osr_bci, comp_level, hot_method, hot_count, compile_reason, is_blocking, THREAD);
}
hotspot/src/share/vm/compiler/compileBroker.cpp
创建编译任务
void CompileBroker::compile_method_base(const methodHandle& method,int osr_bci,...) {
task = create_compile_task(queue,compile_id, method,osr_bci, comp_level,
hot_method, hot_count, compile_reason,
blocking);
}
hotspot/src/share/vm/compiler/compileBroker.cpp
创建任务并将编译任务加入到任务队列
CompileTask* CompileBroker::create_compile_task(CompileQueue* queue, ...) {
CompileTask* new_task = CompileTask::allocate();
new_task->initialize(compile_id, method, osr_bci, comp_level,
hot_method, hot_count, compile_reason,
blocking);
queue->add(new_task);
return new_task;
}
三.C1编译流程
hotspot/src/share/vm/c1/c1_Compilation.cpp
当编译线程循环从任务队列拿到一个编译任务时,会构造Compilation并执行compile_method
Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* method,int osr_bci, BufferBlob* buffer_blob, DirectiveSet* directive){
compile_method();
}
执行C1编译,安装编译好的代码
hotspot/src/share/vm/c1/c1_Compilation.cpp
void Compilation::compile_method() {
//初始化编译环境
initialize();
//这里开始真正执行java方法的编译
int frame_size = compile_java_method();
//编译完成以后进行原方法替换
install_code(frame_size);
totalInstructionNodes += Instruction::number_of_instructions();
}
hotspot/src/share/vm/c1/c1_Compilation.cpp
编译流程分三步:
- HIR阶段:构建CFG流程图,根据流程图进行数据流优化
- LIR阶段:为指令操作数分配虚拟寄存器,根据变量存活周期采用线性扫描算法分配物理寄存器
- 发射阶段:LIR宏汇编器优化,存储编译好的机器码到内存缓冲区
int Compilation::compile_java_method() {
//编译字节码为中间表示HIR
build_hir();
//编译HIR为低级表示LIR
emit_lir();
//编译结果存贮
return emit_code_body();
}
1.HIR阶段
hotspot/src/share/vm/c1/c1_Compilation.cpp
void Compilation::build_hir() {
//构建HIR
_hir = new IR(this, method(), osr_bci());
//各种编译优化
_hir->optimize_blocks();
_hir->split_critical_edges();
_hir->compute_code();
//访问越界优化
RangeCheckElimination::eliminate(_hir);
//null检查优化
_hir->eliminate_null_checks();
_hir->compute_use_counts();
}
hotspot/src/share/vm/c1/c1_IR.cpp
构建IR
IR::IR(Compilation* compilation, ciMethod* method, int osr_bci) :
_num_loops(0) {
// setup IR fields
_compilation = compilation;
_top_scope = new IRScope(compilation, NULL, -1, method, osr_bci, true);
_code = NULL;
}
hotspot/src/share/vm/c1/c1_IR.cpp
构建IRScope
IRScope::IRScope(Compilation* compilation, IRScope* caller, int caller_bci, ciMethod* method, int osr_bci, bool create_graph)
: _callees(2)
, _compilation(compilation)
, _requires_phi_function(method->max_locals())
{
......
//构建CFG流程图
if (create_graph && monitor_pairing_ok()) _start = build_graph(compilation, osr_bci);
}
hotspot/src/share/vm/c1/c1_IR.cpp
构建CFG图
BlockBegin* IRScope::build_graph(Compilation* compilation, int osr_bci) {
GraphBuilder gm(compilation, this);
return gm.start();
}
hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope)
{
int osr_bci = compilation->osr_bci();
//构建所有块
BlockListBuilder blm(compilation, scope, osr_bci);
//字节码到块的映射
BlockList* bci2block = blm.bci2block();
BlockBegin* start_block = bci2block->at(0);
push_root_scope(scope, bci2block, start_block);
//块合并
_initial_state = state_at_entry();
start_block->merge(_initial_state);
//完成图构建
_vmap = new ValueMap();
switch (scope->method()->intrinsic_id()) {
//......
// Otherwise, fall thru
}
default:
scope_data()->add_to_work_list(start_block);
iterate_all_blocks();
break;
}
//块图入口
_start = setup_start_block(osr_bci, start_block, _osr_entry, _initial_state);
}
hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
BlockListBuilder::BlockListBuilder(Compilation* compilation, IRScope* scope, int osr_bci)
{
//生成起始块
set_entries(osr_bci);
//根据指令数量构建所有块,存储在_bci2block(字节码和块映射)和_blocks(块列表),并为当前块构建前驱和后驱
set_leaders();
//处理块循环
mark_loops();
}
2.LIR阶段
hotspot/src/share/vm/c1/c1_Compilation.cpp
void Compilation::emit_lir() {
LIRGenerator gen(this, method());
hir()->iterate_linear_scan_order(&gen);
{
LinearScan* allocator = new LinearScan(hir(), &gen, frame_map());
set_allocator(allocator);
//线性扫描算法,赋值物理寄存器给LIR操作数
allocator->do_linear_scan();
_max_spills = allocator->max_spills();
}
}
3.发射阶段
hotspot/src/share/vm/c1/c1_Compilation.cpp
C1_MacroAssembler继承自MacroAssembler
int Compilation::emit_code_body() {
// emit code
_masm = new C1_MacroAssembler(code());
LIR_Assembler lir_asm(this);
//发射代码
lir_asm.emit_code(hir()->code());
//CodeStub
emit_code_epilog(&lir_asm);
generate_exception_handler_table();
return frame_map()->framesize();
}
hotspot/src/share/vm/c1/c1_LIRAssembler.cpp
void LIR_Assembler::emit_code(BlockList* hir) {
int n = hir->length();
for (int i = 0; i < n; i++) {
emit_block(hir->at(i));
}
}
hotspot/src/share/vm/c1/c1_LIRAssembler.cpp
void LIR_Assembler::emit_block(BlockBegin* block) {
......
emit_lir_list(block->lir());
......
}
hotspot/src/share/vm/c1/c1_LIRAssembler.cpp
void LIR_Assembler::emit_lir_list(LIR_List* list) {
int n = list->length();
for (int i = 0; i < n; i++) {
LIR_Op* op = list->at(i);
check_codespace();
op->emit_code(this);
}
hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
#include "asm/macroAssembler.hpp"
#include "asm/macroAssembler.inline.hpp"
4.代码安装
hotspot/src/share/vm/c1/c1_Compilation.cpp
void Compilation::install_code(int frame_size) {
_env->register_method(
method(),
osr_bci(),
...)
);
}
hotspot/src/share/vm/ci/ciEnv.cpp
void ciEnv::register_method(ciMethod* target,...) {
nm = nmethod::new_nmethod(method,compile_id(),...);
// Free codeBlobs
code_buffer->free_blob();
task()->set_code(nm);
if (entry_bci == InvocationEntryBci) {
//栈上替换
method->set_code(method, nm);
}
}
hotspot/src/share/vm/oops/method.cpp
替换栈上方法,同时修改entry_point,实时替换可被立即执行
void Method::set_code(methodHandle mh, CompiledMethod *code) {
mh->_code = code;
OrderAccess::storestore();
#ifdef SHARK
mh->_from_interpreted_entry = code->insts_begin();
#else //!SHARK
mh->_from_compiled_entry = code->verified_entry_point();
OrderAccess::storestore();
// Instantly compiled code can execute.
if (!mh->is_method_handle_intrinsic())
mh->_from_interpreted_entry = mh->get_i2c_entry();
#endif //!SHARK
}
四.CFG图分析
修改之前的Hello类,添加add方法,循环一万次触发阈值编译
public class Hello{
public static void main(String[] args){
int index = 0;
for(int i = 0; i < 10000; i++){
index = add(i);
}
System.out.println("hello world !" + index);
}
public static int add(int i) {
i++;
return i;
}
}
执行命令追加 -XX:+PrintCFGToFile 将编译CFG流程输出到本地 .cfg文件,查找Hello的add控制流段取出。
begin_block --> end_block 代表控制流图中的一个节点,节点与节点之间通过sucessors和predecessors来链接。
begin_block
name "B0"
from_bci 0
to_bci -1
predecessors
successors
xhandlers
flags "std"
end_block
add 对应的字节码
0:iinc 1,1
3:iload_1
4:ireturn
HIR后得到的中间表示,HIR通过SSA每个变量分配一个编号
0 0 i2 1 <|@
0 0 i3 i1 + i2 <|@
.4 0 i4 ireturn i3 <|@
begin_intervals -->end_intervals之间表示线性扫描算法得到的寄存器生命周期
begin_intervals
name "Before Register Allocation"
0 fixed "[rsi|I]" 0 -1 [0, 4[ "no definition"
3 fixed "[rax|I]" 3 572 [0, 1[ [34, 36[ "no spill store"
569 int 569 0 [4, 30[ 4 M 30 S "no spill store"
570 long 570 -1 [6, 12[ 6 M 8 M 12 M "no spill store"
571 int 571 -1 [8, 16[ 8 M 10 M 12 M 14 M 16 M "no optimization"
572 int 572 569 [30, 34[ 30 M 32 M 34 S "no spill store"
end_intervals
经过LIR阶段后
begin_LIR
28 label [label:0x00007f93643ae400] <|@
32 add [rsi|I] [int:1|I] [rsi|I] <|@
34 move [rsi|I] [rax|I] <|@
36 return [rax|I] <|@
end_LIR
add方法完整的CFG
begin_compilation
name " Hello::add"
method "static jint Hello.add(jint)"
date 1599640056921
end_compilation
begin_cfg
begin_block
name "B0"
from_bci 0
to_bci -1
predecessors
successors
xhandlers
flags "std"
end_block
end_cfg
begin_cfg
name "After Generation of HIR"
begin_block
name "B1"
from_bci 0
to_bci 0
predecessors
successors "B2"
xhandlers
flags
begin_states
begin_locals
size 1
method "static jint Hello.add(jint)"
0 i1
end_locals
end_states
begin_HIR
.0 0 8 std entry B2 <|@
end_HIR
end_block
begin_block
name "B2"
from_bci 0
to_bci 0
predecessors "B1"
successors "B0"
xhandlers
flags "std"
begin_states
begin_locals
size 1
method "static jint Hello.add(jint)"
0 i1
end_locals
end_states
begin_HIR
.0 0 7 goto B0 <|@
end_HIR
end_block
begin_block
name "B0"
from_bci 0
to_bci 4
predecessors "B2"
successors
xhandlers
flags "std"
begin_states
begin_locals
size 1
method "static jint Hello.add(jint)"
0 i1
end_locals
end_states
begin_HIR
0 0 i2 1 <|@
0 0 i3 i1 + i2 <|@
.4 0 i4 ireturn i3 <|@
end_HIR
end_block
end_cfg
//掐掉了一些优化流程
begin_cfg
name "Before Register Allocation"
begin_block
name "B1"
from_bci 0
to_bci 0
predecessors
successors "B2"
xhandlers
flags
first_lir_id 0
last_lir_id 22
begin_states
begin_locals
size 1
method "static jint Hello.add(jint)"
0 i1 "[R569|I]"
end_locals
end_states
begin_HIR
.0 0 8 std entry B2 <|@
end_HIR
begin_LIR
0 label [label:0x00007f93643af030] <|@
2 std_entry <|@
4 move [rsi|I] [R569|I] <|@
6 move [lng:140270052721192|J] [R570|J] <|@
8 move [Base:[R570|J] Disp: 32|I] [R571|I] <|@
10 add [R571|I] [int:8|I] [R571|I] <|@
12 move [R571|I] [Base:[R570|J] Disp: 32|I] <|@
14 logic_and [R571|I] [int:16376|I] [R571|I] <|@
16 cmp [EQ] [R571|I] [int:0|I] <|@
18 branch [EQ] [CounterOverflowStub: 0x00007f92f403d290] <|@
20 label [label:0x00007f92f403d2b8] <|@
22 branch [AL] [B2] <|@
end_LIR
end_block
begin_block
name "B2"
from_bci 0
to_bci 0
predecessors "B1"
successors "B0"
xhandlers
flags "std"
dominator "B1"
first_lir_id 24
last_lir_id 26
begin_states
begin_locals
size 1
method "static jint Hello.add(jint)"
0 i1 "[R569|I]"
end_locals
end_states
begin_HIR
.0 0 7 goto B0 <|@
end_HIR
begin_LIR
24 label [label:0x00007f93643af2a0] <|@
26 branch [AL] [B0] <|@
end_LIR
end_block
begin_block
name "B0"
from_bci 0
to_bci 4
predecessors "B2"
successors
xhandlers
flags "std"
dominator "B2"
first_lir_id 28
last_lir_id 36
begin_states
begin_locals
size 1
method "static jint Hello.add(jint)"
0 i1 "[R569|I]"
end_locals
end_states
begin_HIR
0 1 i2 1 <|@
.0 2 "[R572|I]" i3 i1 + i2 <|@
.4 0 i4 ireturn i3 <|@
end_HIR
begin_LIR
28 label [label:0x00007f93643ae400] <|@
30 move [R569|I] [R572|I] <|@
32 add [R572|I] [int:1|I] [R572|I] <|@
34 move [R572|I] [rax|I] <|@
36 return [rax|I] <|@
end_LIR
end_block
end_cfg
begin_intervals
name "Before Register Allocation"
0 fixed "[rsi|I]" 0 -1 [0, 4[ "no definition"
3 fixed "[rax|I]" 3 572 [0, 1[ [34, 36[ "no spill store"
569 int 569 0 [4, 30[ 4 M 30 S "no spill store"
570 long 570 -1 [6, 12[ 6 M 8 M 12 M "no spill store"
571 int 571 -1 [8, 16[ 8 M 10 M 12 M 14 M 16 M "no optimization"
572 int 572 569 [30, 34[ 30 M 32 M 34 S "no spill store"
end_intervals
begin_intervals
name "After Register Allocation"
0 fixed "[rsi|I]" 0 -1 [0, 4[ "no definition"
3 fixed "[rax|I]" 3 572 [0, 1[ [34, 36[ "no spill store"
569 int "[rsi|I]" 569 0 [4, 30[ 4 M 30 S "no spill store"
570 long "[raxrax|J]" 570 -1 [6, 12[ 6 M 8 M 12 M "no spill store"
571 int "[rdi|I]" 571 -1 [8, 16[ 8 M 10 M 12 M 14 M 16 M "no optimization"
572 int "[rsi|I]" 572 569 [30, 34[ 30 M 32 M 34 S "no spill store"
end_intervals
begin_cfg
name "Before Code Generation"
begin_block
name "B1"
from_bci 0
to_bci 0
predecessors
successors "B2"
xhandlers
flags
first_lir_id 0
last_lir_id 22
begin_LIR
0 label [label:0x00007f93643af030] <|@
2 std_entry <|@
6 move [lng:140270052721192|J] [raxrax|J] <|@
8 move [Base:[raxrax|J] Disp: 32|I] [rdi|I] <|@
10 add [rdi|I] [int:8|I] [rdi|I] <|@
12 move [rdi|I] [Base:[raxrax|J] Disp: 32|I] <|@
14 logic_and [rdi|I] [int:16376|I] [rdi|I] <|@
16 cmp [EQ] [rdi|I] [int:0|I] <|@
18 branch [EQ] [CounterOverflowStub: 0x00007f92f403d290] <|@
20 label [label:0x00007f92f403d2b8] <|@
end_LIR
end_block
begin_block
name "B2"
from_bci 0
to_bci 0
predecessors "B1"
successors "B0"
xhandlers
flags "std"
dominator "B1"
first_lir_id 24
last_lir_id 26
begin_LIR
24 label [label:0x00007f93643af2a0] <|@
end_LIR
end_block
begin_block
name "B0"
from_bci 0
to_bci 4
predecessors "B2"
successors
xhandlers
flags "std"
dominator "B2"
first_lir_id 28
last_lir_id 36
begin_LIR
28 label [label:0x00007f93643ae400] <|@
32 add [rsi|I] [int:1|I] [rsi|I] <|@
34 move [rsi|I] [rax|I] <|@
36 return [rax|I] <|@
end_LIR
end_block
end_cfg
C1编译器的优化相比C2要弱,所以编译速度较C2快,代码产出质量较C2低一些。JIT通过调用计数和回边计数触发方法编译,被编译的方法将封装到一个编译Task中,然后将这个Task放到任务队列中。C1随虚拟机启动后,运行一个编译线程从任务队列中循环取任务执行编译。编译器将字节码取出经过HIR,LIR两个阶段的编译优化生成优化后的代码。优化后的代码存储到CodeBuffer中。编译完成以后的代码对应着一个nmethod。在最后阶段install_code将进行栈上替换。