在Java中,在方法的末尾,当它返回时,操作数堆栈只包含返回值(或者对void方法为空)。或者,在返回值下是否还有其他需要在堆栈中丢弃的值?
我正在标准C堆栈上创建每个方法框架。如图所示:

如您所见,调用方中的操作数堆栈成为被调用方帧中的args。在被调用的框架中,在还原保存的寄存器之前,操作数堆栈上是否会有“垃圾”(返回值除外)需要清理?
发布于 2016-06-27 17:49:59
请参阅return的文档
操作数堆栈 .→空着 描述 …如果不抛出异常,则丢弃当前帧的操作数堆栈上的任何值(§2.6)。
或ireturn,分别:
操作数堆栈 ,值→为空 描述 …如果没有异常抛出,则从当前帧的操作数堆栈(§2.6)中弹出值,并将其推送到调用方帧的操作数堆栈中。当前方法的操作数堆栈上的任何其他值都将被丢弃。
我认为,这给出了足够的提示,即操作数堆栈上可能存在必须“丢弃”的值,尽管在典型的实现中,不需要采取任何行动,因为丢弃堆栈帧作为一个整体意味着丢弃操作数堆栈。
我不知道为什么这对你是个障碍。如果您真的想通过使用当前操作数堆栈位置来获得堆栈帧的开头,那么无论如何您都需要有关堆栈帧的元信息,即您必须知道该帧中局部变量的数量。检索此信息并计算堆栈帧开始,不能比首先检索帧的开始更便宜。
发布于 2016-06-27 16:40:08
发布于 2016-06-27 16:28:56
这个问题很难最终回答,因为你没有明确说明你要问的是什么。
规范是公开可用的https://docs.oracle.com/javase/specs/jvms/se8/jvms8.pdf (见第2.6.2章)
这表示堆栈可能处于任意状态,至少在发生未察觉的异常时是这样。我没有看到返回值的明确提及,但是由于指定返回字节码从堆栈值返回值,所以返回字节码必须在堆栈上(第3.5章)。
规范只是对逻辑上发生的事情的描述。真正的VM不需要将规范1:1转换为内存布局--它只需要确保得到的逻辑是相同的(想想JIT的代码)。
https://stackoverflow.com/questions/38058539
复制相似问题