16

作为一个附带项目的背景,我一直在阅读不同的虚拟机设计,当然 JVM 受到的关注最多。我还研究了 BEAM (Erlang)、GHC 的 RTS(一种但不完全是 VM)和一些 JavaScript 实现。Python 也有一个字节码解释器,我知道它存在,但没有读过太多。

我还没有找到一个很好的解释,为什么要为特定语言做出特定的虚拟机设计选择。我对适合并发和/或非常动态(Ruby、JavaScript、Lisp)语言的设计选择特别感兴趣。


编辑:为了回应要求具体的评论,这里是一个例子。JVM 使用堆栈机而不是寄存器机,这在 Java 刚被引入时引起了很大争议。事实证明,设计 JVM 的工程师这样做是为了平台可移植性,将堆栈机器转换回寄存器机器比克服虚拟寄存器过多或过少的阻抗不匹配更容易和更有效。

这是另一个例子:对于 Haskell,要查看的论文是在股票硬件上实现惰性函数式语言:Spineless Tagless G-machine。这与我所知道的任何其他类型的 VM 都非常不同。事实上,GHC(Haskell 的首要实现)不会实时运行,而是用作编译的中间步骤。Peyton-Jones 列出了至少 8 个其他无法运行的虚拟机。我想了解为什么有些虚拟机成功而其他虚拟机失败。

4

3 回答 3

2

我将以不同的方式回答您的问题:什么是虚拟机?虚拟机只是比源语言低级语言的“解释器”规范。这里我使用“interpreter”这个词的黑盒含义。我不在乎 VM 是如何实现的(作为字节码 intepereter、JIT 编译器等等)。当这样表述时,从设计的角度来看,VM 并不是有趣的东西,它是低级语言。

理想的 VM 语言将做两件事。一,它将使将源语言编译到其中变得容易。第二,它还将使在目标平台上的解释变得容易(解释器可以非常天真地实现,或者可以是一些非常复杂的 JIT,如 Hotspot 或 V8)。

显然,这两个理想属性之间存在张力,但它们或多或少地形成了一条穿过所有可能 VM 的设计空间的线上的两个端点。(或者,也许是比线更复杂的形状,因为这不是一个平坦的欧几里得空间,但你明白了)。如果您在该行之外构建您的 VM 语言,那么它不会很有用。这就是限制 VM 设计的原因:把它放在理想的位置上。

这也是为什么高级虚拟机往往非常特定于语言,而低级虚拟机则与语言无关,但不提供很多服务。高级虚拟机本质上接近源语言,这使得它远离其他不同的源语言。低级 VM 本质上接近目标平台,因此接近许多语言理想线的平台端,但低级 VM 也远离理想线的“易于编译”端大多数源语言。

现在,更广泛地说,从概念上讲,任何编译器都可以看作是从源语言到中间形式的一系列转换,中间形式本身可以被视为 VM 的语言。中间语言的虚拟机可能永远不会被构建,但它们可能会被构建。编译器最终会发出最终形式。最终形式本身将成为 VM 的一种语言。我们可以称该虚拟机为“JVM”、“V8”……或者我们可以称该虚拟机为“x86”、“ARM”等。

希望有帮助。

于 2012-07-09T23:41:32.130 回答
1

派生 VM 的技术之一是顺着编译链往下走,将源语言转换为越来越多的低级中间语言。一旦您发现了适合平面表示的足够低级别的语言(即可以序列化为一系列“指令”的语言),这几乎就是您的虚拟机。您的 VM 解释器或 JIT 编译器只会从您选择进行序列化的点继续您的转换链。

一些序列化技术非常常见 - 例如,使用表达式树的伪堆栈表示(如在 .NET CLR 中,它根本不是“真正的”堆栈机器)。否则,您可能希望使用 SSA 形式进行序列化,如 LLVM 中,或者只是一个具有无限数量寄存器的 3 地址 VM(如 Dalvik 中)。您采用哪种方式并不重要,因为它只是一个序列化,稍后会反序列化以继续您的正常编译方式。

如果您打算立即解释您的 VM 代码而不是编译它,那就有点不同了。目前对于哪种 VM 更适合解释尚未达成共识。基于堆栈(或者我敢说是 Forth)的 VM 和基于寄存器的 VM 都被证明是有效的。

于 2012-07-01T09:02:35.067 回答
0

我发现这本书很有帮助。它讨论了您所询问的许多问题。(请注意,我与亚马逊没有任何关联,也不是在推广亚马逊;只是最容易链接的地方)。

http://www.amazon.com/dp/1852339691/

于 2012-06-29T18:43:23.760 回答