低于 64K 的方法出现“方法超出编译器指令限制”消息

And*_*der 2 methods android limit

我经常在日志中看到类似这样的重复消息:

Method exceeds compiler instruction limit: 29278 in void com.xxxxxxapp.xxxxxx.MyGLRenderer.onDrawFrame(javax.microedition.khronos.opengles.GL10)
Method exceeds compiler instruction limit: 29278 in void com.xxxxxxapp.xxxxxx.MyGLRenderer.onDrawFrame(javax.microedition.khronos.opengles.GL10)
Method exceeds compiler instruction limit: 29278 in void com.xxxxxxapp.xxxxxx.MyGLRenderer.onDrawFrame(javax.microedition.khronos.opengles.GL10)
Run Code Online (Sandbox Code Playgroud)

分解代码通常会给出相同的消息,但数字较小:

Method exceeds compiler instruction limit: 22400 in void com.xxxxxxapp.xxxxxx.MyGLRenderer.onDrawFrame(javax.microedition.khronos.opengles.GL10)
Run Code Online (Sandbox Code Playgroud)

我认为 64000 是保留在此处的神奇数字。尽管有这样的烦人消息,我的游戏代码似乎总是运行良好,而且不仅仅是在 opengl onDrawFrame 方法中。尽管更新代码比绘制代码更容易分解,但我在低于 64K 的更新方法中收到了类似的消息。

搜索“方法超出编译器指令限制”刚刚让我链接到可怕的“Dalvik 编译器对 64K 方法的限制”错误。我必须继续忽略这一点吗?

Mar*_*ler 5

发生这种情况的原因是Compiler::IsPathologicalCase

跳过对病态大方法的编译 - 通过指令计数或 num vreg。

Dalvik 使用 16 位 uint 进行指令和寄存器计数。我们将限制为四分之一,这也保证了我们不会溢出 16 位内部 Quick SSA 名称空间。

来源:compiler.cc

16 位uint可以表示 的最大值65535,除以4,等于16383.75

将目标级别从 提高DalvikART可能会绕过它;因为由于指令计数,Dalvikjavax.microedition.khronos.opengles.GL10似乎不兼容。

之后将检查寄存器计数,因此这似乎不是问题。

修补compiler.cc也是一种选择,尽管不是一个好的选择。

  • 什么4时候2,这将允许双倍的金额。

  • 如果不是,return true它也应该继续编译。

这是有问题的检查:

if (accessor.InsnsSizeInCodeUnits() >= UINT16_MAX / 4) {
  LOG(INFO) << "Method exceeds compiler instruction limit: "
            << accessor.InsnsSizeInCodeUnits()
            << " in " << dex_file.PrettyMethod(method_idx);
  return true;
}
Run Code Online (Sandbox Code Playgroud)

免责声明:不保证“无副作用”。