Jvm 为什么是基于堆栈的虚拟机?为什么不使用基于队列的虚拟机?

Jvm 为什么是基于堆栈的虚拟机?为什么不使用基于队列的虚拟机?,jvm,dalvik,vm-implementation,Jvm,Dalvik,Vm Implementation,正如我所调查的,有两种主要的方法来实现流程VM: 基于堆栈,如JVM、CLR等 或基于寄存器,如Lua、Dalvik等 基于寄存器的方法模仿了物理处理器的体系结构。 但对于基于堆栈的方法,还有许多其他数据结构 我认为选择哪种方法主要取决于我们希望如何存储/获取操作数。那么为什么选择堆栈呢?基于队列的虚拟机怎么样?或其他选项,如链表 StackOverflow确实不适合基于意见的调查;很可能要关门了 然而,关键是要认识到处理器特定的体系结构通常使用寄存器,因为寄存器对应于处理器的工作方式。每个

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

  • 基于堆栈,如JVM、CLR等
  • 或基于寄存器,如Lua、Dalvik等
基于寄存器的方法模仿了物理处理器的体系结构。 但对于基于堆栈的方法,还有许多其他数据结构


我认为选择哪种方法主要取决于我们希望如何存储/获取操作数。那么为什么选择堆栈呢?基于队列的虚拟机怎么样?或其他选项,如链表

StackOverflow确实不适合基于意见的调查;很可能要关门了

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

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

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

也就是说,(实)堆栈速度较慢——实际上,当您使用它时,您忽略了实寄存器。所以通常寄存器用于速度,堆栈用于寄存器中不适合的内容

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


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

调用子例程的第一次调用最后一次返回性质自然适合于stack这样的逻辑FILO结构。基于队列的VM听起来很有趣。我想问题是,;这到底是怎么回事?我认为如果你坐下来思考实现细节,你会很快发现为什么其他结构不起作用,尽管我可能错了,在这种情况下,你可能已经发明了一种新的处理方式。