Hotspot 方法编译之CompileBroker 源码解析

    目录

一、CompileBroker 定义

二、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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值