【问题标题】:'Method exceeds compiler instruction limit' message on well under 64K method远低于 64K 方法的“方法超出编译器指令限制”消息
【发布时间】:2019-07-24 09:59:52
【问题描述】:

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

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。

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

【问题讨论】:

  • 也许 64k 是字节?

标签: android methods limit


【解决方案1】:

这是因为Compiler::IsPathologicalCase:

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

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

来源: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;
}

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

【讨论】:

  • 看起来我的更新和绘制方法“病态”很大,哈哈。不错的来源。
  • @Androidcoder 可能不是你的,而是完全编译的。剥离未使用的方法也可能有所帮助;只是不知道这是在检查发生之前还是之后发生的。最佳解决方案是低于 16k 指令数。
  • 剥离未使用的方法无关紧要,因为在调用方法时会触发此错误。第一次调用方法时编译失败,所以下一次调用也是“第一次”又失败了,下一次,再下一次……编译一个大的方法需要CPU时间和电池电量,所以在循环中这样做是相当的问题。 (在我的例子中,它涉及使用javacc 和一个中等复杂的语法进行解析。你好,搜索引擎。)
【解决方案2】:

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

【讨论】:

  • 问题涉及单个方法中的指令数; android的限制低于JVM的限制。 Multidex 处理应用程序中方法的数量。
猜你喜欢
  • 2013-03-04
  • 2014-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-31
  • 1970-01-01
  • 1970-01-01
  • 2014-09-22
相关资源
最近更新 更多