为什么COMPUTE_FRAMES会生成许多冗余指令?

4
我正在编写一个编译器,输出JVM字节码,使用ASM 9.4作为后端。这很好用,但有一个特别奇怪的问题。
我正在指定 COMPUTE_FRAMES 自动计算堆栈帧。据说这样做的权衡是(可以理解)使代码生成需要更多时间,但速度似乎足够快。
在任何地方都没有记录的是,指定 COMPUTE_FRAMES 导致大量冗余指令被生成。具体来说,每个方法的结尾处会出现一个 athrow,在某些情况下,整个方法中会散布一堆长时间运行的 nop
这似乎并不会造成任何损害;我的初始测试用例通过了,我想JIT编译器实际上不会为冗余指令生成任何机器代码。但这有点令人不安。为什么会这样?我做错了什么吗?
1个回答

8

这是一个表明您的生成字节码中存在无法访问的代码的迹象。对于具有堆栈图的情况,每个未被其前一个指令访问到的指令必须具有堆栈帧,即使不是分支目标。这是为了在单个线性遍历中验证代码。

但对于无法访问的代码,没有已知的初始状态,并且为任意指令序列发明一个有效的初始状态将非常具有挑战性。ASM 的解决方案是使用nop指令替换整个无法访问的代码,然后跟随单个athrow语句。对于此序列,可以指定一个有效的初始堆栈帧;它是具有单个可抛对象的桢。此序列对后续可能可访问的代码也没有影响。

由于代码是无法访问的,因此此替换不会影响执行,正如您在测试中已经注意到的那样。而且,您是正确的,JIT编译器不会为其生成任何本机代码。

但是要摆脱这些令人不安的代码,您需要修订编译器代码,以找出它生成无法访问的代码的部分。


啊哈!是的,那很有道理。我知道我的编译器会生成很多无法到达的代码;计划是优化器会清理它,但优化器仍在待办事项列表中。那就好了,谢谢! - rwallace
我知道一个点赞已经足够了,但是这真是一篇好的解释,我想明确地感谢你,Holger。我相信在将来的某个时候,这将会有用并且需要再次查阅。 - kriegaex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接