为啥jvm在推入堆栈之前将字节和短扩展为int?

Posted

技术标签:

【中文标题】为啥jvm在推入堆栈之前将字节和短扩展为int?【英文标题】:Why jvm expands byte & short to int before pushing on stack?为什么jvm在推入堆栈之前将字节和短扩展为int? 【发布时间】:2013-08-27 15:11:59 【问题描述】:

java代码:,

byte a_b = 12;
short c_d = 14

替换字节码
bipush  12 // expands byte1 (a byte type) to an int and pushes it onto the stack
sipush   14 // expands byte1, byte2 (a short type) to an int and pushes it onto the stack

为什么 jvm 会进行这种扩展,而不是使用 byte & short ?

当我打开文件的字节码时

EDIT : short var = 14 被 bipush 14 而不是 sipush 14 取代

是我的理解不清楚还是有bug?

我正在使用以下版本

java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) Client VM (build 20.1-b02, mixed mode, sharing)

【问题讨论】:

见***.com/a/17094810/724361。 主要是因为这是他们定义它的方式,并且没有迫切需要以不同方式定义它。 (堆栈在概念上仅以 4 字节为增量递增/递减,尽管在 8 字节 JVM 中显然必须出现一点踢踏舞。) bipush 是 2 个字节长,而 sipush 是 3 个字节长。为什么要使用较长的指令,而较短的指令也同样有效? @HotLicks 查看从以下链接添加的快照 docs.oracle.com/javase/specs/jvms/se7/html/… 您的意思是“在任何时间点,操作数堆栈都有关联的深度,其中 long 或 double 类型的值对深度贡献两个单位,任何其他类型的值贡献一个单位。 “? 【参考方案1】:

因为(概念上)JVM 堆栈上的最小数据单位是 32 位。所以没有办法只用 8 位来增加栈的大小。

http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.6.2

在任何时间点,操作数堆栈都有一个关联的深度,其中 long 或 double 类型的值对深度贡献两个单位,并且 任何其他类型的值贡献一个单位。

【讨论】:

我认为你的意思是减少 ;-) 你也只能将 8 位数据写入 32 位堆栈帧。我只会浪费空间。我认为真正的原因可以在@TheTerribleSwiftTomato 在 cmets 中链接的答案中找到。 @stonedsquirrel - 他们确实将 8 位数据写入 32 位堆栈帧。然后他们将符号扩展到框架的其余部分。 @HotLicks 当然可以。您不仅可以做到,而且必须使用固定的堆栈帧大小,这让我不以为然;-) 谢谢!

以上是关于为啥jvm在推入堆栈之前将字节和短扩展为int?的主要内容,如果未能解决你的问题,请参考以下文章

将 Nibbles 推入 C 中的整数堆栈

Java中的字节和短点(我已经阅读了其他问题)

将XMM寄存器推入堆栈

为啥我不能从字符堆栈中弹出元素?

Java - 为啥 char 不应该被隐式转换为字节(和短)原语?

为啥我不能将整数向量推入 C++ 中的二维整数向量?