aot模式能脱离虚拟机吗?

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模式能脱离虚拟机吗?)