HotSpot C1编译器与栈上替换

上一篇主要分析了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

编译流程分三步:

  1. HIR阶段:构建CFG流程图,根据流程图进行数据流优化
  2. LIR阶段:为指令操作数分配虚拟寄存器,根据变量存活周期采用线性扫描算法分配物理寄存器
  3. 发射阶段: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将进行栈上替换。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值