ART 的 interpret-only模式源码及调用流程 & QuickCompiler后端调用流程

在文件compiler/dex/quick/quick_compiler.cc中取消 kCompilerDebugFlags 的注释,重新在根目录下编译,替换启动盘中相应的动态库。
用eclipse写一个Helloworld程序安装到android系统中,或者在 /data/dalvik-cache/ 目录下删除一个应用程序的oat文件(classes.dex文件),重启系统。根据Logcat日志查看dex2oat调用路径。


 一.ART 的 interpret-only 模式执行路径:



int main(...) --> art::dex2oat(...) --> CompileApp(dex2oat) --> dex2oat.Compile()  --> driver_->CompileAll(...) -->  Compile(...) --> CompileDexFile(...) --> context.ForAll(...) --> 
CompilerDriver::CompileClass(...) --> driver->CompileMethod(...) --> (*dex_to_dex_compiler)(...) -->  ArtCompileDEX(...)  -->  dex_compiler.Compile()
在dex_compiler.Compile()函数中有四类操作码的替换:
CompileReturnVoid(...): 在需要 barrier 的地方将 RETURN-VOID 替换为 RETURN-VOID-BARRIER。
CompileCheckCast(...): 将 CHECK-CAST 替换为 2 个 NOP 指令。
CompileInstanceFieldAccess(...): 将获取字段的方式由通过索引获取替换为通过偏移地址获取,从而不需要在运行阶段进行解析。
CompileInvokeVirtual(...): 将虚方法调用时的虚方法的index替换为Vtable中的 index,从而不需要在运行阶段进行解析。


二. interpret-only模式相关源码


在文件build/core/main.mk中,设置dex2oat模式: 
 
   ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.dex2oat-filter=interpret-only


编译android源码后这个编译属性会记录在system/build.prop文件中。


在文件frameworks/native/cmds/installd/commands.c中,函数dexopt(...)调用run_dex2oat(...),使用property_get()从文件build.prop中获取这个属性:
 
  bool have_dex2oat_compiler_filter_flag = property_get("dalvik.vm.dex2oat-filter",
                                                          dex2oat_compiler_filter_flag, NULL) > 0;
...
   else if (have_dex2oat_compiler_filter_flag) {
       sprintf(dex2oat_compiler_filter_arg, "--compiler-filter=%s", dex2oat_compiler_filter_flag);
   }
...
    if (have_dex2oat_compiler_filter_flag) {
        argv[i++] = dex2oat_compiler_filter_arg;
    }
...


然后调用execv(DEX2OAT_BIN,(char* const*)argv) , 执行 system/bin/dex2oat,幷将这个属性作为参数传递给dex2oat . 


在文件 art/dex2oat/dex2oat.cc 中函数 ParseArgs(...) 内,在解析参数argv时将变量 compiler_filter_string 设置为interpret-only ,继而变量compiler_filter(初值为kDefaultCompilerFilter,即Speed)被设置为 kInterpretOnly,从而编译器被设置为 interpret-only 模式。
instruction_set_被设置为Mips。当instruction_set_ 为 kMips32r6 和 kMips64 时只有interpret-only 模式可以工作。


Android属性之build.prop,及property_get/property_set && Android平台LOG输出规范: http://blog.csdn.net/zhandoushi1982/article/details/7378264 
剖析 Android ART Runtime (2) – dex2oat: https://mssun.me/blog/android-art-runtime-2-dex2oat.html
如何反编译 android 中 /data/dalvik-cache/arm 下的文件: http://zhidao.baidu.com/link?url=nd7Q-JuZTR3gLiIWdMOX2OLJLnO89SYuTOkK5SHxtTllpzP6MsgsyKvcB6gCPWdpN01FHonv_-76M5tOOGhP_jO3Yupu0axOGb-Ehkqh_J_


三.ART的后端使用Quick Compiler 还是 Optimizing Compiler 的执行路径:



在函数 dex2oat(...) 函数中,创建对象 Dex2Oat dex2oat(&timings) 时在其构造函数中给 compiler_kind_ 赋初值:
CompileApp(dex2oat)  -->  dex2oat.Compile()  -->  driver_.reset(new CompilerDriver(...,compiler_kind_,...)  -->  CompilerDriver::CompilerDriver(...,Compiler::Kind compiler_kind,...) :...,compiler_(Compiler::Create(this, compiler_kind)),... (构造函数初始化) -->  CreateQuickCompiler(driver)

你可能感兴趣的:(Android)