jvm-为什么java字节码指令iload_<n>只有0-3?

​没错,事情是这样的。在阅读周志明大大的《深入理解jvm 第三版》的字节码指令一节的时候,讲到iload_<n style="margin: 0px; padding: 0px; font-size: inherit; color: inherit; line-height: inherit;">指令中,n只能取0~3。有点不解,遂du了一下。</n>

然后!然后!然后!果然没让我失望,那个对jvm有着深厚造诣的蓝人--R大!!在b乎回答了这个问题。膜拜R大,这个蓝人tql。

直接上链接好了。

java字节码指令iload_<n style="margin: 0px; padding: 0px; font-size: inherit; color: inherit; line-height: inherit;">为什么只有0到3?- RednaxelaFX的回答 - 知乎https://www.zhihu.com/question/54390587/answer/139423116</n>

总结一下:

这是Java字节码上针对字节码大小的一个早期优化。Java字节码指令集里,大部分操作局部变量的指令(例如iload、istore)都有完整版:

iload n

例如iload 5,以及针对前4个局部变量/参数的缩写版

iload_<n>

例如iload_0,这样两个版本。其中缩写版只有0~3的范围。

二者的区别是,完整版有显式的“操作数”(operand),缩写版把操作数融合到了操作码(opcode)中。分别用两种指令举个例子:

iload的指令格式是:

iload index
image

index是一个unsigned byte,用来指定局部变量的下标。另外看Notes里标注,还有wide版,如果在iload前面带有wide前缀的话,则格式为:

wide iload index1 index2

其中wide、iload、index1、index2各自为一个字节,(index1<<8)| index2 构成指令局部变量下标的操作数。

iload_<n>的指令格式是:

iload_<n>
image

其中iload_<n>自身就是opcode,它可能的取值为:
iload_0 = 26 (0x1a)
iload_1 = 27 (0x1b)
iload_2 = 28 (0x1c)
iload_3 = 29 (0x1d)
这样的话,针对前4个局部变量,iload_<n>就可以只用一个字节的opcode来表达整条指令,比使用完整版的iload要少一个字节。使用缩写版指令不但可以让字节码的大小减少,还可以让解释器的性能提升。原因如下图所示:摘自R大的知乎回答。

image

当使用缩写版指令时,decode_operands()就不需要做任何额外的内存读,因为operand已经隐藏在opcode里了,于是就会比完整版指令要快一些。

至于选择03的范围来做的原因,R大猜测大概只是正好发现,如果用03的话基本可以把opcode范围用满(因为字节码是1字节,最多256个),而如果用04的话就把编码空间超了,02的话则用不满,仅此而已。

《!-- 毁灭吧,赶紧的,累了 --》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叹了口丶气

觉得有收获就支持一下吧~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值