ProGuard can cause incorrect calculations

南楼画角 提交于 2019-12-03 12:19:54

Android team member has posted a possible solution in a comment to my issue. If I add android:vmSafeMode="true" to application element of manifest-file, all calculations are performed correctly. This option is not well documented and honestly I do not know how much will it affect the speed, but at least the math will be correct. I will mark it as correct answer until a better one is found.

The original code and the processed code work fine on the Java VM and on most Dalvik VMs, so it must be valid. If the processed code produces spurious results on a few Dalvik VMs, chances are that the problem is caused by the JIT compiler in those VMs. Google's Android team should then look into it.

The most obvious optimization that ProGuard applies here is inlining the method. A few branch instructions and local variables are reordered in the final bytecode, but the execution flow of this small piece of code is fundamentally the same. It's difficult to determine how ProGuard could avoid the problem. You could disable the optimization step entirely.

You could check if inlining the code manually causes the same problems, without ProGuard (the problem doesn't seem to occur on my devices).

(I am the developer of ProGuard)

This all turns out to be a JIT compiler bug which the ProGuard optimizations just happened to trigger.

As the AOSP issue explains:

There was a window in the Jelly Bean release time in which the JIT would mistakenly optimize away uses of floating point double constants which were identical in the low 32 bits (and also had a few other conditions met). The defect was introduced in late November of 2012 in the internal Google tree, and in February of 2013 in aosp. Fixed in April of 2013.

More detailed explanation in this other AOSP issue.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!