在文件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 的 interpret-only模式源码及调用流程 & QuickCompiler后端调用流程】三.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)