【问题标题】:Matching a virtual machine design with its primary programming language将虚拟机设计与其主要编程语言相匹配
【发布时间】:2012-06-09 05:52:10
【问题描述】:

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

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


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

这是另一个示例:对于 Haskell,要查看的论文是 Implementing lazy functional languages on stock hardware: the Spineless Tagless G-machine。这与我所知道的任何其他类型的 VM 都非常不同。事实上,GHC(Haskell 的首要实现)不会实时运行,而是用作编译的中间步骤。 Peyton-Jones 列出了至少 8 个其他无法运行的虚拟机。我想了解为什么有些虚拟机成功而其他虚拟机失败。

【问题讨论】:

  • 这个话题有点太宽泛了。你能给出你最感兴趣的设计的一些特定方面吗?或任何其他示例。无论如何都要向我 +1,因为这可能会产生一些有趣的答案。
  • Dalvik JVM 使用基于寄存器的架构 - en.wikipedia.org/wiki/Dalvik_(software)
  • 您应该查看 Parrot parrot.org 的文档,该文档最初是为 Perl 设计的,但后来被用于其他几种语言。该文档讨论了动态类型语言与 Java 等更多静态语言的 VM 功能。
  • SpacedMonkey - Dakvik 不是 JVM,JVM .class 文件不会在其上运行。 JVM 的字节码在放到 Android 设备上之前会被翻译成 Dalvik 字节码。
  • 这不是更适合程序员吗?

标签: jvm language-design vm-implementation


【解决方案1】:

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

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

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

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

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

希望对您有所帮助。

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 这不是你可以在评论中提到的答案
      • 你能给我总结一下它在这个话题上所说的话吗?
      • 有一整章是关于实现技术的,比较基于堆栈的机器和寄存器机器。
      • 当您提出一个没有具体答案的广泛问题时,您对答案投了反对票,这很有趣。你做了什么来帮助自己?你的研究有什么具体问题?如果您想比较 VM 设计以及它们在不同情况下的使用方式,请阅读一本书。
      • 抱歉,Jim 不是为了读书,而是为了更实际的答案,而不仅仅是推荐一本书。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-20
      • 1970-01-01
      • 1970-01-01
      • 2019-05-29
      • 1970-01-01
      • 2014-08-17
      • 1970-01-01
      相关资源
      最近更新 更多