ART世界探險(16) - 快速編譯器下的方法編譯

ART世界探險(16) - 快速編譯器下的方法編譯

我們對三大組件有了了解之后,下面終于可以開始正餐,開始分析兩種Compiler下的Compile函數。

我們先看一張圖,對于整個流程有個整體的印象,然后我們再去看代碼:

quick_compile

QuickCompiler的Compile

CompiledMethod* QuickCompiler::Compile(const DexFile::CodeItem* code_item,
                                       uint32_t access_flags,
                                       InvokeType invoke_type,
                                       uint16_t class_def_idx,
                                       uint32_t method_idx,
                                       jobject class_loader,
                                       const DexFile& dex_file) const {
...
CompilerDriver* driver = GetCompilerDriver();

上來就是老朋友,先獲取CompilerDriver對象。前面我們介紹過,它是調用編譯器的驅動接口,大雜燴類。
然后下面判斷是不是病態情況,值不值得編譯。是不是經過校驗。是不是打開了編譯開關。

...
  if (Compiler::IsPathologicalCase(*code_item, method_idx, dex_file)) {
    return nullptr;
  }

  if (driver->GetVerifiedMethod(&dex_file, method_idx)->HasRuntimeThrow()) {
    return nullptr;
  }

  DCHECK(driver->GetCompilerOptions().IsCompilationEnabled());

下面是Runtime和ClassLinker出場,三大組件齊了。
然后是大管家CompliationUnit開始工作。

  Runtime* const runtime = Runtime::Current();
  ClassLinker* const class_linker = runtime->GetClassLinker();
  InstructionSet instruction_set = driver->GetInstructionSet();
  if (instruction_set == kArm) {
    instruction_set = kThumb2;
  }
  CompilationUnit cu(runtime->GetArenaPool(), instruction_set, driver, class_linker);
  cu.dex_file = &dex_file;
  cu.class_def_idx = class_def_idx;
  cu.method_idx = method_idx;
  cu.access_flags = access_flags;
  cu.invoke_type = invoke_type;
  cu.shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx));

  CHECK((cu.instruction_set == kThumb2) ||
        (cu.instruction_set == kArm64) ||
        (cu.instruction_set == kX86) ||
        (cu.instruction_set == kX86_64) ||
        (cu.instruction_set == kMips) ||
        (cu.instruction_set == kMips64));

...
  InitCompilationUnit(cu);

上面都是在做CompilationUnit的初始化工作,例如這個InitCompilationUnit:

void QuickCompiler::InitCompilationUnit(CompilationUnit& cu) const {
  // Disable optimizations according to instruction set.
  cu.disable_opt |= kDisabledOptimizationsPerISA[cu.instruction_set];
  if (Runtime::Current()->UseJit()) {
    // Disable these optimizations for JIT until quickened byte codes are done being implemented.
    // TODO: Find a cleaner way to do this.
    cu.disable_opt |= 1u << kLocalValueNumbering;
  }
}

然后開始構建MIRGraph.

  cu.mir_graph.reset(new MIRGraph(&cu, &cu.arena));

  /*
   * After creation of the MIR graph, also create the code generator.
   * The reason we do this is that optimizations on the MIR graph may need to get information
   * that is only available if a CG exists.
   */
  cu.cg.reset(GetCodeGenerator(&cu, nullptr));

  /* Build the raw MIR graph */
  cu.mir_graph->InlineMethod(code_item, access_flags, invoke_type, class_def_idx, method_idx,
                             class_loader, dex_file);
...

下面創建Pass驅動,然后調用它來做優化。

  /* Create the pass driver and launch it */
  PassDriverMEOpts pass_driver(GetPreOptPassManager(), GetPostOptPassManager(), &cu);
  pass_driver.Launch();
...

寄存器重新映射

  /* Reassociate sreg names with original Dalvik vreg names. */
  cu.mir_graph->RemapRegLocations();

清理內存,以便下次復用

  /* Free Arenas from the cu.arena_stack for reuse by the cu.arena in the codegen. */
...
  cu.arena_stack.Reset();

  CompiledMethod* result = nullptr;
...

生成機器指令

  cu.cg->Materialize();
...

消除重復數據,并重復結果

  result = cu.cg->GetCompiledMethod();
...
  return result;
}

我們為下一章節做個小小的預告,下面我們將深入到MIRGraph,CodeGenerator,優化的Pass還有Mir2Lir的激動人心的過程中。
先上一個預告圖,順便復習一下之前所學的流程:

Paste_Image.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,814評論 25 708
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,837評論 18 139
  • ART世界探險(14) - 快速編譯器和優化編譯器 ART的編譯器為兩種,一種是QuickCompiler,快速編...
    Jtag特工閱讀 880評論 0 0
  • 從一位媽媽的朋友圈看到了我自己,很難得的一份看見!刷著這位媽媽的朋友圈,看到她對兒子的愛,看到她對我們蓓蕾幼兒園的...
    潘存英閱讀 311評論 0 0
  • 果然,悲催之心,或者恐懼,亦,罪惡感,,正義才能拯救。就像是水與火的關系,以前一直不懂,為什么要救火,,被摧殘,怎...
    f9105556d285閱讀 273評論 0 0