Art下DexClassLoader将dex转化为oat文件格式的过程

经过看源码DexClassLoader最终会调用DexFile类中的native函数openDexFileNative。


下面来看看openDexFileNative函数做了什么。

openDexFileNative函数在art\runtime\native\dalvik_system_DexFile.cc文件中下面的代码导出了openDexFileNative符号。

static JNINativeMethod gMethods[] = {
  NATIVE_METHOD(DexFile, closeDexFile, "(I)V"),
  NATIVE_METHOD(DexFile, defineClassNative, "(Ljava/lang/String;Ljava/lang/ClassLoader;I)Ljava/lang/Class;"),
  NATIVE_METHOD(DexFile, getClassNameList, "(I)[Ljava/lang/String;"),
  NATIVE_METHOD(DexFile, isDexOptNeeded, "(Ljava/lang/String;)Z"),
  NATIVE_METHOD(DexFile, openDexFileNative, "(Ljava/lang/String;Ljava/lang/String;I)I"),
};

通过观察上面的全局变量可以发现,openDexFileNative所代表的函数是DexFile_openDexFileNative。


在DexFile_openDexFileNative函数中,首先调用DexFile::GetChecksum函数获得了zip文件或dex文件的校验和,如果获得校验和成功将校验和保存在局部变量dex_location_checksum中。

DexFile::GetChecksum(dex_location, &dex_location_checksum)



如果outputName不为NULL,则将执行下面的代码进行dex到oat的转换。

std::string oat_location(outputName.c_str());
dex_file = linker->FindOrCreateOatFileForDexLocation(dex_location, dex_location_checksum, oat_location);


-------------------------------------------------------------------


FindOrCreateOatFileForDexLocation函数是ClassLinker类的成员函数,下面来看看FindOrCreateOatFileForDexLocation函数做了什么。


ClassLinker::FindOrCreateOatFileForDexLocation函数调用了ClassLinker::FindOrCreateOatFileForDexLocationLocked函数。

return FindOrCreateOatFileForDexLocationLocked(dex_location, dex_location_checksum, oat_location);


-------------------------------------------------------------------
ClassLinker:: FindOrCreateOatFileForDexLocationLocked函数中。


通过调用ClassLinker::FindDexFileInOatLocation函数判断dex文件是否已经优化为oat文件。

// Check if we already have an up-to-date output file
const DexFile* dex_file = FindDexFileInOatLocation(dex_location,
                                                     dex_location_checksum,
                                                     oat_location);

如果dex未被优化为oat文件,则调用ClassLinker::GenerateOatFile函数将dex转换为oat。

GenerateOatFile(dex_location, scoped_flock.GetFile().Fd(), oat_location)

ClassLinker:: GenerateOatFile函数中fork了一个子进程,在子进程中调用了dex2oat进行dex到oat的转换,并且父进程等待子进程运行的结束。

// fork and exec dex2oat
pid_t pid = fork();

    execl(dex2oat, dex2oat,
          "--runtime-arg", "-Xms64m",
          "--runtime-arg", "-Xmx64m",
          "--runtime-arg", "-classpath",
          "--runtime-arg", class_path,
          "--runtime-arg", oat_compiler_filter_option,
#if !defined(ART_TARGET)
          "--host",
#endif
          boot_image_option,
          dex_file_option,
          oat_fd_option,
          oat_location_option,
          NULL);

ClassLinker:: GenerateOatFile函数执行完成后,又调用了oat_dex_file->OpenDexFile()函数打开在内存中的dex文件。

const DexFile* result = oat_dex_file->OpenDexFile();


至此,完成了dex到oat的转换。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值