dex2oat将dex转换为oat的执行路径概览

转自:http://blog.csdn.net/zylc369/article/details/39452053

dex2oat是一个可执行文件,在源码中通过编译文件art\dex2oat\Dex2oat.cc生成。


dex2oat的执行入口是:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. int main(int argc, char** argv) {  
  2.   return art::dex2oat(argc, argv);  
  3. }  

在函数dex2oat中调用了dex2oat->CreateOatFile函数,在CreateOatFile函数中执行了driver->CompileAll(class_loader, dex_files, timings);语句,这条语句将dex文件编译成了oat文件。

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. void CompilerDriver::CompileAll(jobject class_loader,  
  2.                                 const std::vector<const DexFile*>& dex_files,  
  3.                                 base::TimingLogger& timings) {  
  4.   DCHECK(!Runtime::Current()->IsStarted());  
  5.   UniquePtr<ThreadPool> thread_pool(new ThreadPool(thread_count_ - 1));  
  6.   PreCompile(class_loader, dex_files, *thread_pool.get(), timings);  
  7.   Compile(class_loader, dex_files, *thread_pool.get(), timings);  
  8.   if (dump_stats_) {  
  9.     stats_->Dump();  
  10.   }  
  11. }  


Compile函数

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. void CompilerDriver::Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files,  
  2.                        ThreadPool& thread_pool, base::TimingLogger& timings) {  
  3.   for (size_t i = 0; i != dex_files.size(); ++i) {  
  4.     const DexFile* dex_file = dex_files[i];  
  5.     CHECK(dex_file != NULL);  
  6.     CompileDexFile(class_loader, *dex_file, thread_pool, timings);  
  7.   }  
  8. }  


CompileDexFile函数

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. void CompilerDriver::CompileDexFile(jobject class_loader, const DexFile& dex_file,  
  2.                                     ThreadPool& thread_pool, base::TimingLogger& timings) {  
  3.   // TODO: strdup memory leak.  
  4.   timings.NewSplit(strdup(("Compile " + dex_file.GetLocation()).c_str()));  
  5.   ParallelCompilationManager context(Runtime::Current()->GetClassLinker(), class_loader, this,  
  6.                                      &dex_file, thread_pool);  
  7.   context.ForAll(0, dex_file.NumClassDefs(), CompilerDriver::CompileClass, thread_count_);  
  8. }  

context.ForAll(0, dex_file.NumClassDefs(), CompilerDriver::CompileClass, thread_count_);这条语句中重要的是CompilerDriver::CompileClass,CompilerDriver::CompileClass代表一个回调函数,这个回调函数将一个dex中的类进行编译。


在CompileClass函数中调用了CompileMethod函数将一个方法进行编译,其中使用到了类的成员变量jni_compiler_和compiler_,这两个成员变量均在CompilerDriver类的构造函数中被赋值:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. CompilerDriver::CompilerDriver(CompilerBackend compiler_backend, InstructionSet instruction_set,  
  2.                                bool image, DescriptorSet* image_classes, size_t thread_count,  
  3.                                bool dump_stats) ... {  
  4. ...  
  5.   if (compiler_backend_ == kPortable) {  
  6.     // Initialize compiler_context_  
  7.     init_compiler_context = reinterpret_cast<void (*)(CompilerDriver&)>(ArtInitCompilerContext);  
  8.     compiler_ = reinterpret_cast<CompilerFn>(ArtCompileMethod);  
  9.   } else {  
  10.     init_compiler_context = reinterpret_cast<void (*)(CompilerDriver&)>(ArtInitQuickCompilerContext);  
  11.     compiler_ = reinterpret_cast<CompilerFn>(ArtQuickCompileMethod);  
  12.   }  
  13. ...  
  14.   if (compiler_backend_ == kPortable) {  
  15.     jni_compiler_ = reinterpret_cast<JniCompilerFn>(ArtLLVMJniCompileMethod);  
  16.   } else {  
  17.     jni_compiler_ = reinterpret_cast<JniCompilerFn>(ArtQuickJniCompileMethod);  
  18.   }  
  19. ...  
  20. }  

这其中有这么几个函数值得关注:ArtCompileMethod、ArtQuickCompileMethod、ArtLLVMJniCompileMethod、ArtQuickJniCompileMethod。


查看其中ArtCompileMethod函数的代码:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. extern "C" art::CompiledMethod* ArtCompileMethod(art::CompilerDriver& driver,  
  2.                                                  const art::DexFile::CodeItem* code_item,  
  3.                                                  uint32_t access_flags,  
  4.                                                  art::InvokeType invoke_type,  
  5.                                                  uint16_t class_def_idx,  
  6.                                                  uint32_t method_idx,  
  7.                                                  jobject class_loader,  
  8.                                                  const art::DexFile& dex_file) {  
  9.   UNUSED(class_def_idx);  // TODO: this is used with Compiler::RequiresConstructorBarrier.  
  10.   art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();  
  11.   
  12.   art::DexCompilationUnit dex_compilation_unit(  
  13.     NULL, class_loader, class_linker, dex_file, code_item,  
  14.     class_def_idx, method_idx, access_flags);  
  15.   art::llvm::CompilerLLVM* compiler_llvm = ContextOf(driver);  
  16.   art::CompiledMethod* result = compiler_llvm->CompileDexMethod(&dex_compilation_unit, invoke_type);  
  17.   return result;  
  18. }  

通过上面ArtCompileMethod函数的代码发现,使用类art::llvm::CompilerLLVM中的CompileDexMethod函数对dex中的方法进行了编译。


art::llvm::CompilerLLVM属于LLVM的范畴。以上就是dex2oat工具将dex转换为oat的执行路径概览,未涉及到具体细节。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值