美文网首页
jvm-为什么java字节码指令iload_只有0-3?

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

作者: 小北觅 | 来源:发表于2021-01-07 17:09 被阅读0次

    ​没错,事情是这样的。在阅读周志明大大的《深入理解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的话则用不满,仅此而已。

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

    相关文章

      网友评论

          本文标题:jvm-为什么java字节码指令iload_只有0-3?

          本文链接:https://www.haomeiwen.com/subject/fwgzoktx.html