Meituan-Dianping / Robust

Robust is an Android HotFix solution with high compatibility and high stability. Robust can fix bugs immediately without a reboot.
Apache License 2.0
4.42k stars 807 forks source link

优化robust插桩,减少约20% 因robust而增大的包大小,并连带修复一个bug #237

Closed limengyun2008 closed 6 years ago

limengyun2008 commented 6 years ago

原来的插桩逻辑为这样:

if (PatchProxy.isSupport()) {
     return PatchProxy.accessDispatch();
}

封装一下变成下面这种代码

PatchProxyResult patchProxyResult = PatchProxy.proxy();
if (patchProxyResult.isSupported) {
     return patchProxyResult.result;
}
 

这样做的好处有两个:

  1. 减少包大小。 不是开玩笑,虽然后者代码看起来变得复杂,但实质产生的指令更少。 之前两个函数调用,每次都需要load 7个参数到栈上,这7个参数还不是简单的基本类型,这意味着比后者多出若干条指令。 数据显示在5W个方法的插桩下,后者能比前者节省200KB

  2. fix一个bug。robust其实支持采用将ChangeQuickRedirect置为null的方法实时下线一个patch,那原来的插桩逻辑就存在线程安全的问题。 根源在于原来的逻辑中ChangeQuickRedirect是每次都直接去取的static变量值 如果在执行isSupport的时候ChangeQuickRedirect有值,但执行到accessDispatch时ChangeQuickRedirect被置为空,那就意味着被patch的方法该次将不执行任何代码 这样会带来一系列的不可知问题。 封装之后能保证这两个方法读取到的ChangeQuickRedirect是同一份。

Change-Id: I67c594ca06758abac666cfeacaed38388ee4e8dd

hedex commented 6 years ago

@limengyun2008 这个思路挺赞,确实能减少load各个参数的指令