热修&插件 - Dalvik加载Dex相关流程

一、Dalvik整体类加载过程

大致流程与Art基本相同。只是具体dex优化流程、解析加载流程区别会比较大。

二、Dex文件优化过程

这里引用SHUWOOM的一张图,梳理了Dex文件的优化过程。

三、Dalvik类加载过程被打上CLASS_ISPREVERIFIED标签流程分析

Dalvik的类加载前面部分与ART没什么差别。

openDexFileNative方法的核心部分是dvmRawDexFileOpen和dvmJarFileOpen。当传递进来的是dex文件类型的时候,调用dvmRawDexFileOpen加载解析,并将解析后的文件信息保存到RawDexFile结构体中;如果不是dex文件类型,例如dex文件包含在压缩包中,则调用dvmJarFileOpen加载解析,并将解析后的文件信息保存到JarFile中。这里是以dvmRawDexFileOpen为例。

dvmOptimizeDexFile方法主要是做Dex文件优化,fork子进程,并调用/system/bin/dexopt来执行优化工作,以OptMain.cpp的main方法作为入口函数,对dex中的class进行验证。

最后通过verifyAndOptimizeClass来做class验证和优化

dalvik/vm/analysis/DexPrepare.cpp

/*
* Verify and/or optimize a specific class.
*/

static void verifyAndOptimizeClass(DexFile* pDexFile, ClassObject* clazz,
   const DexClassDef* pClassDef, bool doVerify, bool doOpt)
{
...
   /*
    * First, try to verify it.
    */
   if (doVerify) {
       if (dvmVerifyClass(clazz)) {
           /*
            * Set the "is preverified" flag in the DexClassDef.  We
            * do it here, rather than in the ClassObject structure,
            * because the DexClassDef is part of the odex file.
            */
           assert((clazz->accessFlags & JAVA_FLAGS_MASK) ==
               pClassDef->accessFlags);
           ((DexClassDef*)pClassDef)->accessFlags |= CLASS_ISPREVERIFIED;
           verified = true;
       } else {
           // TODO: log when in verbose mode
           ALOGV("DexOpt: '%s' failed verification", classDescriptor);
       }
   }
   if (doOpt) {
       bool needVerify = (gDvm.dexOptMode == OPTIMIZE_MODE_VERIFIED ||
                          gDvm.dexOptMode == OPTIMIZE_MODE_FULL);
       if (!verified && needVerify) {
           ALOGV("DexOpt: not optimizing '%s': not verified",
               classDescriptor);
       } else {
           dvmOptimizeClass(clazz, false);
           /* set the flag whether or not we actually changed anything */
           ((DexClassDef*)pClassDef)->accessFlags |= CLASS_ISOPTIMIZED;
       }
   }
}

这里dvmVerifyClass最终会通过verifyMethod验证每个方法:
We do this in three passes:
(1) Walk through all code units, determining instruction locations, widths, and other characteristics.
(2) Walk through all code units, performing static checks on operands.
(3) Iterate through the method, checking type safety and looking for code flow problems.

也就是说其实dexopt执行编译优化过程会触发class pre verify,校验通过的类会被打上CLASS_ISPREVERIFIE标签。

四、Dex文件加载解析过程

dvmDexFileOpenFromFd方法将上一步优化后的dex文件映射到内存中并进行加载和解析。这里引用SHUWOOM的一张图,梳理dex文件解析。

五、Dex加载流程整体数据结构关系与转换

Dex加载转换:

数据结构关系:

这里ClassObject是最终Dex加载完成后具体类在内存中的数据结构实例对象。当Dalvik要运行某一个类方法的时候,是通过运行在内存中的ClassObject对象中的资源去执行,最后调用dvmInterpret方法初始化解释器并执行字节码指令。

参考:
https://shuwoom.com/?p=269

你可能感兴趣的:(热修&插件 - Dalvik加载Dex相关流程)