美文网首页
aot模式能脱离虚拟机吗?

aot模式能脱离虚拟机吗?

作者: hqdoremi22 | 来源:发表于2019-11-04 16:19 被阅读0次

    art中可以采用解释模式或者AOT机器码模式执行。
    解释模式,就是取出Dex Code,逐条解释执行就行了。如果方法的调用者是以解释模式运行的,在调用这个方法时,就会取得这个方法的entry_point_from_interpreter_,然后跳转过去执行。
    而如果是AOT的方式,就会先预编译好Dex Code对应的机器码,然后运行期直接执行机器码就行了,不需要一条条地解释执行Dex Code。如果方法的调用者是以AOT机器码方式执行的,在调用这个方法时,就是跳转到entry_point_from_quick_compiled_code_执行。

    那我们是不是只需要替换这几个entry_point_*入口地址就能够实现方法替换了呢?

    并没有这么简单。因为不论是解释模式或是AOT机器码模式,在运行期间还会需要用到ArtMethod里面的其他成员字段

    就以AOT机器码模式为例,虽然Dex Code被编译成了机器码。但是机器码并不是可以脱离虚拟机而单独运行的,以这段简单的代码为例:

    public class MainActivity extends Activity {
     
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    ... ...
    

    编译为AOT机器码后,是这样的:

     7: void com.patch.demo.MainActivity.onCreate(android.os.Bundle) (dex_method_idx=20639)
       DEX CODE:
         0x0000: 6f20 4600 1000            | invoke-super {v0, v1}, void android.app.Activity.onCreate(android.os.Bundle) // method@70
         0x0003: 0e00                      | return-void
    
       CODE: (code_offset=0x006fdbac size_offset=0x006fdba8 size=96)
         ... ...
         0x006fdbe0: f94003e0  ldr x0, [sp]        ;x0 = MainActivity.onCreate对应的ArtMethod指针
         0x006fdbe4: b9400400  ldr w0, [x0, #4]    ;w0 = [x0 + 4] = dex_cache_resolved_methods_字段
         0x006fdbe8: f9412000  ldr x0, [x0, #576]  ;x0 = [x0 + 576] = dex_cache_resolved_methods_数组的第72(=576/8)个元素,即对应Activity.onCreate的ArtMethod指针
         0x006fdbec: f940181e  ldr lr, [x0, #48]   ;lr = [x0 + 48] = Activity.onCreate的ArtMethod成员的entry_point_from_quick_compiled_code_执行入口点
         0x006fdbf0: d63f03c0  blr lr              ;调用Activity.onCreate
         ... ...
    

    这里面我去掉了一些校验之类的无关代码,可以很清楚看到,在调用一个方法时,取得了ArtMethod中的dex_cache_resolved_methods_,这是一个存放ArtMethod的指针数组,通过它就可以访问到这个Method所在Dex中所有的Method所对应的ArtMethod

    Activity.onCreate的方法索引是70,由于是64位系统,因此每个指针的大小为8字节,又由于ArtMethod*元素是从这个数组的第0x2个位置开始存放的,因此偏移(70 + 2) * 8 = 576的位置正是Activity.onCreate的ArtMethod指针。

    这是一个比较简单的例子,而在实际代码中,有许多更为复杂的调用情况。很多情况下还需要用到dex_code_item_offset_等字段。由此可以看出,AOT机器码的执行过程,还是会有对于虚拟机以及ArtMethod其他成员字段的依赖。

    因此,当把一个旧方法的所有成员字段换成都新方法后,执行时所有数据就可以保持和新方法的一致。这样在所有执行到旧方法的地方,会取得新方法的执行入口、所属class、方法索引号以及所属dex信息,然后像调用旧方法一样顺滑地执行到新方法的逻辑。

    转自:https://yq.aliyun.com/articles/74598?t=t1#

    相关文章

      网友评论

          本文标题:aot模式能脱离虚拟机吗?

          本文链接:https://www.haomeiwen.com/subject/jwydbctx.html