首页 > 代码库 > dex2oat将dex转换为oat的执行路径概览
dex2oat将dex转换为oat的执行路径概览
dex2oat是一个可执行文件,在源码中通过编译文件art\dex2oat\Dex2oat.cc生成。
dex2oat的执行入口是:
int main(int argc, char** argv) { return art::dex2oat(argc, argv); }
在函数dex2oat中调用了dex2oat->CreateOatFile函数,在CreateOatFile函数中执行了driver->CompileAll(class_loader, dex_files, timings);语句,这条语句将dex文件编译成了oat文件。
void CompilerDriver::CompileAll(jobject class_loader, const std::vector<const DexFile*>& dex_files, base::TimingLogger& timings) { DCHECK(!Runtime::Current()->IsStarted()); UniquePtr<ThreadPool> thread_pool(new ThreadPool(thread_count_ - 1)); PreCompile(class_loader, dex_files, *thread_pool.get(), timings); Compile(class_loader, dex_files, *thread_pool.get(), timings); if (dump_stats_) { stats_->Dump(); } }
Compile函数
void CompilerDriver::Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files, ThreadPool& thread_pool, base::TimingLogger& timings) { for (size_t i = 0; i != dex_files.size(); ++i) { const DexFile* dex_file = dex_files[i]; CHECK(dex_file != NULL); CompileDexFile(class_loader, *dex_file, thread_pool, timings); } }
void CompilerDriver::CompileDexFile(jobject class_loader, const DexFile& dex_file, ThreadPool& thread_pool, base::TimingLogger& timings) { // TODO: strdup memory leak. timings.NewSplit(strdup(("Compile " + dex_file.GetLocation()).c_str())); ParallelCompilationManager context(Runtime::Current()->GetClassLinker(), class_loader, this, &dex_file, thread_pool); context.ForAll(0, dex_file.NumClassDefs(), CompilerDriver::CompileClass, thread_count_); }
context.ForAll(0, dex_file.NumClassDefs(), CompilerDriver::CompileClass, thread_count_);这条语句中重要的是CompilerDriver::CompileClass,CompilerDriver::CompileClass代表一个回调函数,这个回调函数将一个dex中的类进行编译。
在CompileClass函数中调用了CompileMethod函数将一个方法进行编译,其中使用到了类的成员变量jni_compiler_和compiler_,这两个成员变量均在CompilerDriver类的构造函数中被赋值:
CompilerDriver::CompilerDriver(CompilerBackend compiler_backend, InstructionSet instruction_set, bool image, DescriptorSet* image_classes, size_t thread_count, bool dump_stats) ... { ... if (compiler_backend_ == kPortable) { // Initialize compiler_context_ init_compiler_context = reinterpret_cast<void (*)(CompilerDriver&)>(ArtInitCompilerContext); compiler_ = reinterpret_cast<CompilerFn>(ArtCompileMethod); } else { init_compiler_context = reinterpret_cast<void (*)(CompilerDriver&)>(ArtInitQuickCompilerContext); compiler_ = reinterpret_cast<CompilerFn>(ArtQuickCompileMethod); } ... if (compiler_backend_ == kPortable) { jni_compiler_ = reinterpret_cast<JniCompilerFn>(ArtLLVMJniCompileMethod); } else { jni_compiler_ = reinterpret_cast<JniCompilerFn>(ArtQuickJniCompileMethod); } ... }
这其中有这么几个函数值得关注:ArtCompileMethod、ArtQuickCompileMethod、ArtLLVMJniCompileMethod、ArtQuickJniCompileMethod。
查看其中ArtCompileMethod函数的代码:
extern "C" art::CompiledMethod* ArtCompileMethod(art::CompilerDriver& driver, const art::DexFile::CodeItem* code_item, uint32_t access_flags, art::InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx, jobject class_loader, const art::DexFile& dex_file) { UNUSED(class_def_idx); // TODO: this is used with Compiler::RequiresConstructorBarrier. art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker(); art::DexCompilationUnit dex_compilation_unit( NULL, class_loader, class_linker, dex_file, code_item, class_def_idx, method_idx, access_flags); art::llvm::CompilerLLVM* compiler_llvm = ContextOf(driver); art::CompiledMethod* result = compiler_llvm->CompileDexMethod(&dex_compilation_unit, invoke_type); return result; }
通过上面ArtCompileMethod函数的代码发现,使用类art::llvm::CompilerLLVM中的CompileDexMethod函数对dex中的方法进行了编译。
art::llvm::CompilerLLVM属于LLVM的范畴。以上就是dex2oat工具将dex转换为oat的执行路径概览,未涉及到具体细节。
dex2oat将dex转换为oat的执行路径概览
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。