作者:lylmwt | 来源:互联网 | 2023-09-09 19:07
我目前正在构建一个简单的虚拟机作为辅助项目,最终目标是从头开始实现我自己的编程语言。无论如何,我试图松散地复制在JVM中看到的许多技术。我注意到当在JVM中调用一个函
我目前正在构建一个简单的虚拟机作为辅助项目,最终目标是从头开始实现我自己的编程语言。无论如何,我试图松散地复制在 JVM 中看到的许多技术。
我注意到当在 JVM 中调用一个函数时,一个堆栈帧被推送到包含三个部分的调用堆栈上……局部变量数组、操作数堆栈和帧数据。我的问题是 JVM 如何知道要为操作数堆栈部分分配多少空间。是否有一个简单的规则来确定给定函数调用的操作数堆栈应该有多大?
最后,如果操作数堆栈填满会发生什么?堆栈框架是否应该扩展自身以进行补偿?还是应该抛出错误?
回答
JVM 如何知道要为操作数堆栈部分分配多少空间
“帧的操作数堆栈的最大深度在编译时确定,并与与帧关联的方法的代码一起提供。” JVMS §2.6.2 , §4.7.3。
如果操作数堆栈填满会发生什么?
如上所述,每个单独帧的操作数堆栈的大小是预先知道的。对于特定方法,计算不能使用比类文件中指定的更多的操作数堆栈,否则类验证将失败。
“在执行过程中,操作数堆栈的任何时候都不能增长到比 max_stack 项所暗示的深度更大的深度。” JVMS §4.9.2。
§2.5.2 is talking about the call stack (a.k.a. the Java Virtual Machine stack), not the operand stack. The only way that the operand stack could overflow would be if the maximum depth of the operand stack is incorrect, which would mean the bytecode is illegal and will be rejected during the verification stage.
@c.abate in case of Java bytecode, you must even track the types that are expected to be on the operand stack, to provide stack map frames for branch merge points. This implies that the same type of items must be at the beginning of the loop as in the next iteration, otherwise, they are unusable. But usually, when you have modelled the elements of your programming language and converted the source code to a tree, this knowledge comes for free.
@c.abate Keep track of the stack depth while generating code for a method: Every time you emit an instruction that grows the stack, you increase the stack depth. Every time you emit an instruction that shrinks the stack, you decrease the stack depth. Every time the current depth of stack exceeds the maximum, you set the maximum to the current depth.
@c.abate Exactly. When writing a verifier, you'll need to make sure that such a thing can't happen (i.e. that all incoming edges of a basic block come from blocks with the same outgoing stack depth), but when counting the depth in the code generator, you simply know that (barring bugs) this can't happen because you won't generate code that does that.