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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值