Java类文件规范指出:


代码数组提供实现该方法的Java虚拟机代码的实际字节。

当将代码数组读入可字节寻址的计算机的内存中时,如果数组的第一个字节在4字节边界上对齐,则tableswitch和lookupswitch的32位偏移量将为4字节对齐。 (有关代码数组对齐结果的更多信息,请参阅这些指令的描述。)
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.3


我将如何解释这一说法?

这2条指令的维基百科页面上提到了这一点:(https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings

Tableswitch的其他字节:


4 +:[0–3个字节填充],defaultbyte1,defaultbyte2,defaultbyte3,defaultbyte4,lowbyte1,lowbyte2,lowbyte3,lowbyte4,highbyte1,highbyte2,highbyte3,highbyte4,跳转偏移量...


Lookupswitch其他字节:


4 +:,defaultbyte1,defaultbyte2,defaultbyte3,defaultbyte4,npairs1,npairs2,npairs3,npairs4,匹配偏移对...


我认为与类文件规范语句有关,我只是不知道它的精确程度。

最佳答案

tableswitch和lookupswitch指令定义为具有0到3个填充字节,具体取决于它们在方法字节码中的偏移量。填充的实际定义可以在第6.5节中找到,其中列出了每条指令的格式。


在lookupswitch操作码之后,立即在零和三之间
字节必须充当填充,以便defaultbyte1从一个地址开始
从当前方法开始算起,这是四个字节的倍数
(第一条指令的操作码)。


您突出显示的语句解释了此设计选择的动机,否则可能看起来很奇怪或毫无意义。

这样可以更有效地实现Java解释器,因为如果代码以4字节对齐地址加载,则可以通过对齐访问方式读取切换表中的偏移量和键。

当然,由于我们拥有一些不错的JIT,所以如今它并不是那么重要,但是在Java的早期,JVM可能被实现为幼稚的解释器,这将在性能上产生很大的不同。

07-26 09:27