ART世界探险(16) - 快速编译器下的方法编译
来源:互联网 发布:奇葩说肖骁 知乎 编辑:程序博客网 时间:2024/04/30 01:00
ART世界探险(16) - 快速编译器下的方法编译
我们对三大组件有了了解之后,下面终于可以开始正餐,开始分析两种Compiler下的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的激动人心的过程中。
先上一个预告图,顺便复习一下之前所学的流程:
0 0
- ART世界探险(16) - 快速编译器下的方法编译
- ART世界探险(19) - 优化编译器的编译流程
- ART世界探险(14) - 快速编译器和优化编译器
- ART世界探险(20) - Android N上的编译流程
- ART探险(1) - oatdump看到的世界
- ART世界探险(7) - 数组
- ART世界探险(18) InlineMethod
- ART世界探险(5) - 计算指令
- ART世界探险(6) - 流程控制指令
- ART世界探险(8) - 面向对象编程
- ART世界探险(9) - 同步锁
- ART世界探险(10) - 异常处理
- ART世界探险(11) - OAT文件格式分析
- ART世界探险(13) - 初入dex2oat
- ART世界探险(3) - ARM 64位CPU的架构快餐教程
- ART世界探险-arm64-v8a 64位CPU的架构快餐教程
- ART世界探险(2) - 从java byte code说起
- ART世界探险(15) - CompilerDriver,ClassLinker,Runtime三大组件
- 轮播图的简单制作(前端开发)
- 51nod 1094
- Linux产生序列数字
- Java线程总结(一):创建线程的两种方式Thread和Runnable
- SWT编写Moco的启动控制面板
- ART世界探险(16) - 快速编译器下的方法编译
- 几种简单的设计模式
- linux环境下设置shadowsocks+polipo全局代理
- fzu 2231 根据坐标面上的点找平行四边形个数
- 392.leetcode Is Subsequence (medium)[判断一个字符串是否是另一个字符串的子串]
- C语言中的声明以及static关键字
- xshell4配置堡垒机访问server
- ural 1014
- 第2周项目3--体验复杂度