Java类文件规范声明:
代码数组给出了实现该方法的Java虚拟机代码的实际字节。
当代码数组被读入字节可寻址机器的内存时,如果数组的第一个字节在4字节边界上对齐,则tableswitch和lookupswitch 32位偏移将是4字节对齐的。 (有关代码阵列对齐结果的更多信息,请参阅这些说明的说明。) (https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.3)
我如何理解这句话?
这两条说明的维基百科页面提到了这一点:(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,jump offsets ...
Lookupswitch其他字节:
4+:< 0-3字节填充>,defaultbyte1,defaultbyte2,defaultbyte3,defaultbyte4,npairs1,npairs2,npairs3,npairs4,匹配偏移对...
我认为< 0-3字节填充>与类文件规范声明相关,我只是不知道具体如何。
答案 0 :(得分:1)
tableswitch和lookupswitch指令被定义为具有0到3个字节的填充,具体取决于它们在方法的字节码中的偏移量。填充的实际定义可以在6.5节中找到,其中列出了每条指令的格式。
在lookupswitch操作码之后,立即在0到3之间 bytes必须充当填充,以便defaultbyte1从地址开始 这是从当前方法开始的四个字节的倍数 (第一条指令的操作码)。
你强调的陈述解释了这种设计选择的动机,否则它可能看起来很奇怪或毫无意义。
这样可以更有效地实现Java解释器,因为如果代码以4字节对齐的地址加载,则可以使用对齐访问来读取切换表中的偏移量和键。
当然,现在它并不重要,因为我们有精美的JIT,但早在Java的早期,JVM可能被实现为一个天真的解释器,这将在性能上产生重大影响。