您的位置:首页 > 移动开发 > Android开发

Android ART虚拟机执行引擎-JIT(九)

2018-02-25 21:15 274 查看
Just-in-time compilation是一种动态编译,是在程序运行过程中才执行编译工作。相对于ART的核心技术ahead-of-time,JIT有几个有点:比AOT更节省存储空间;不需要在每次安装,或者系统升级、应用升级后都做AOT优化。
因为不需要在程序安装时执行AOT预编译,所以不会出现漫长的安装等待,不会影响程序的启动速度。
JIT的编译过程是在独立的线程中完成的,并且只编译有必要的函数。
AOT的编译有两个主要的执行时机:一是ROM系统编译时,一是第三方应用程序安装时。
1),JIT的执行时机需要一套追踪机制来决定哪一部分代码需要被执行JIT-也就是热区域的确定,这个追踪技术在Android中被成为Profile Guided Compilation。
Profile Guided Compilation的工作原理:
step1,应用程序第一次启动时,只会通过解释器执行,同时JIT会介入并针对hot methods执行优化工作。
step2,第一步的执行过程中会同步输出一种被称为profile information的信息保存到文件中。
step3,上述步骤会重复执行,以使profile information不断完善,profile information中记录了需要离线优化的函数hot methods,影响程序启动速度的Classes,以进一步优化程序的启动速度,等等。

step4,当设备处于idle状态并且在充电,就会进入profile guided compilation服务,这个编译过程以profile information文件为输入,输出是二进制机器码,这里的二级制机器码被用于替代原始应用程序的相应部分。
step5,经过前面的步骤,应用程序在后续启动时,就可以根据实际情况在AOT/JIT/Interpreter中选择最合适的执行方式了。

JIT对应的源码实现在art/runtime/jit/,是在runtime的start过程中启动的。
art/runtime/Runtime.ccbool Runtime::Start() {
// Create the JIT either if we have to use JIT compilation or save profiling info.
// TODO(calin): We use the JIT class as a proxy for JIT compilation and for
// recoding profiles. Maybe we should consider changing the name to be more clear it's
// not only about compiling. b/28295073.
if (jit_options_->UseJitCompilation() || jit_options_->GetSaveProfilingInfo()) {
std::string error_msg;
if (!IsZygote()) {
// If we are the zygote then we need to wait until after forking to create the code cache
// due to SELinux restrictions on r/w/x memory regions.
CreateJit();
} else if (jit_options_->UseJitCompilation()) {
if (!jit::Jit::LoadCompilerLibrary(&error_msg)) {
// Try to load compiler pre zygote to reduce PSS. b/27744947
LOG(WARNING) << "Failed to load JIT compiler with error " << error_msg;
}
}
}
}其中是否使用JIT,由jit_options_->UseJitCompilation()来判断。
然后调用CreateJit生成JIT实例,具体代码是调用Jit::Create,实现在art/runtime/jit/jit.cc,void Runtime::CreateJit() {
jit_.reset(jit::Jit::Create(jit_options_.get(), &error_msg));
if (jit_.get() == nullptr) {
LOG(WARNING) << "Failed to create JIT " << error_msg;
}
}JIT模块完成的主要任务:
监测程序运行,获取需要翻译的函数信息;
通过profileSaver将获取的信息存入文件中;
有jit_compile_method(art/rumtime/jit/jit_compiler.cc)实时翻译运行过程中的热点函数,保存到jitCodeCache中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: