为什么在 ASM 中使用 F_SAME?

Why use F_SAME in ASM?

F_SAME 在 ASM 中的真正用途是什么? 我在 Java Virtual Machine Instruction Set 中查找了这个助记词,但没有找到任何相关内容。

我了解堆栈映射框架并且它们可以节省 space。
但是,为什么在跳转目标、异常处理程序或 遵循无条件跳转指令?
仍然无法“预测”堆栈内容的类型?
使用这个是强制性的吗?

我对此进行了很多搜索,但几乎在任何地方都找不到与之相关的任何内容。

谢谢!

这不是真正的操作码。源代码中的注释对其进行了解释:ASM specific stack map frame types, used in {@link ClassVisitor#visitFrame}。切记注释有误,visitFrame方法在MethodVisitor中

我想你可能想知道为什么帧会出现在跳转目标等处。 StackMapTableAttribute 用于加快字节码验证。验证者进行流分析,确保操作数栈和局部变量在所有基本块入口点处一致。在基本块中,操作数堆栈和局部变量随着每条指令的访问而递增更新。这些增量更新很便宜,因此没有理由冗余地记录这些信息。

在 Java1.6 之前,验证器没有使用 StackMapTableAttribute,但这迫使它对代码执行更多遍,以确保访问所有执行路径。

更准确地回答你的问题,为什么 F_SAME 存在?因为正如你所说,它比编码一个完整的帧要小。

如果您使用 ASM 生成代码,那么您应该使用 COMPUTE_MAXS 和 COMPUTE_FRAMES 选项,这样您就不必担心这种混乱。如果您想使用更简单的东西,请使用我编写的 Cojen/Maker 库。