'Method exceeds compiler instruction limit' 64K方法下井井有条留言

'Method exceeds compiler instruction limit' message on well under 64K method

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

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)

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

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

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

搜索 'Method exceeds compiler instruction limit' 刚刚让我找到了可怕的 'Dalvik compiler limit on 64K methods' 错误的链接。我必须一直忽略这个吗?

这是因为 Compiler::IsPathologicalCase:

Skip compilation for pathologically large methods - either by instruction count or num vregs.

Dalvik uses 16-bit uints for instruction and register counts. We'll limit to a quarter of that, which also guarantees we cannot overflow our 16-bit internal Quick SSA name space.

来源:compiler.cc.

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

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

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

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

  • 42 时,这将允许双倍的金额。

  • 如果不是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;
}

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

要跳过此错误,您可以为您的发布或调试版本使用 proGaurd minify Enabled 选项。如果这没有帮助,请使用 MultiDex 应用程序。有关详细信息,请参阅此文档。MultiDex