为什么基于堆栈的VM?为什么不基于队列的VM?

时间:2016-05-19 08:17:21

标签: jvm dalvik vm-implementation

正如我调查的那样,有两种主要的方法来实现流程VM:

  • 基于堆栈,例如JVM,CLR等。
  • 或基于注册的,例如Lua,Dalvik等。

基于寄存器的方法模仿物理处理器的架构。 但对于基于堆栈的方法,还有许多其他数据结构。

我认为选择哪种方法主要取决于我们想要存储/获取操作数的方式。为什么选择堆栈?基于队列的VM怎么样?或其他选项,如链表?

1 个答案:

答案 0 :(得分:2)

StackOverflow实际上不适用于基于意见的调查;它可能会被关闭。

但是,了解特定于处理器的体系结构通常使用寄存器是关键,因为这与处理器的工作方式相对应。每个指令集都有一组固定的寄存器,不同的架构将有不同的数量。此外,一些寄存器具有基于平台或ABI的特定含义。

通用程序集文件很难在平台之间移植;或者如果可以的话,最终可能达到最小值,因此错过可能适用于更广泛说明的优化。 64位处理器的优点之一不是额外的宽度,而是ISA中可用寄存器数量的增加。

解决这个问题有两种方法;假定无限寄存器集,然后在为特定体系结构转换时提供寄存器映射(例如,LLVM在其ISA中使用无限寄存器集,然后映射到真实ISA上的特定寄存器)或使用堆栈。使用堆栈的一个优点是,当您用完时,您不需要处理溢出寄存器的特定情况(例如,您有一个函数,您希望有10个寄存器,但仅限ISA)有5)。堆栈非常擅长表示无限条目(当然,以可用内存量为模)。

也就是说,(实际)堆栈速度较慢 - 当您使用它时,有效地忽略了真实的寄存器。所以通常寄存器用于速度,而堆栈用于不适合寄存器的东西。

无论如何 - VM代码使用堆栈,因为像pushpop这样的指令只处理单个值,而基于寄存器的指令通常在操作码编码中使用位标志来指示N个寄存器中的哪个到使用。因此,定义基于堆栈的ISA可以为您提供完全灵活的无限数据点集,然后解释器/ JIT可以根据需要将这些数据点转换为特定的寄存器 - 实际上,执行LLVM在编译时执行的运行时优化。这允许在64位系统上运行的Java程序能够自动获取更大的寄存器集,而无需重新编译32位运行 - 并且您可以自动获得更宽的寄存器。

'堆栈'这是一个逻辑概念而不是特定的数据结构。使用非连续的非增长数据结构是没有意义的。并且堆栈是专门使用的,因为通常调用新的子例程/函数/方法会生成一个新的堆栈' space,所以你总是在从封闭方法返回之前从该子程序返回,所以你只能弹出/推送一端(例如队列在这里并不相关)。除此之外,这就是为什么你得到StackOverflow异常以及为什么这个站点被称为StackOverflow而不是QueueOverflow。