Ruby MRI 是什么样的解释器?

What kind of interpreter is the Ruby MRI?

是语言翻译器吗?还是字节码解释器/JIT 编译器?我在哪里可以了解有关实现的更多信息(除了浏览源代码)?

这是一个名为 YARV 的字节码解释器,由 Sasada Koichi 编写。

这是一个外观示例:

puts RubyVM::InstructionSequence.compile("1+1").disasm
== disasm: #<ISeq:<compiled>@<compiled>>================================
0000 trace            1                                               (   1)
0002 putobject_OP_INT2FIX_O_1_C_
0003 putobject_OP_INT2FIX_O_1_C_
0004 opt_plus         <callinfo!mid:+, argc:1, ARGS_SIMPLE>, <callcache>
0007 leave

进一步阅读:

虽然 MRI 还没有 JIT,但有 Ruby+OMR 项目,它试图添加一个基于 Eclipse OMR:

的 JIT 编译器

注意:"MRI" 一词令人困惑。意思是"Matz's Ruby/Reference Implementation/Interpreter"。但是,MRI 已经退役,不再开发或维护。

MRI 是一个纯粹的 AST-walking 解释器,不涉及任何编译。

令人困惑的是:Matz 编写了一个新的实现,但它叫做 MRuby,而不是 MRI。 现在 称为 MRI 的实现不是 Matz 编写的。所以,实际上,最好根本不要使用该术语,并具体说明您正在谈论的实现方式。

现在人们称之为 MRI 的实现的名称实际上是 YARV(Yet Another Ruby VM),它是由 Koichi Sasada 编写的。它由一个将 Ruby 源代码编译为 YARV 字节码的 Ahead-Of-Time 编译器和一个解释所述字节码的解释器组成。因此,它是一个完全典型的字节码 VM,完全像 CPython for Python,Zend Engine for PHP,Lua VM,旧版本的 Rubinius,旧版本用于 ECMAScript 的 SpiderMonkey,等等。

有人在谈论为 YARV 3 添加一个从 YARV 字节码到本机机器码的 JIT 编译器,这将使 VM 成为混合模式执行引擎。

Matz 的当前实现,MRuby,也是一个字节编码的 VM。

为了完整起见,这里有几个其他 Ruby 实现,首先是当前可用于生产的实现,然后是一些历史上有趣的实现:

  • Rubinius:提前将 Ruby 源代码编译为 Rubinius 字节码,然后将该字节码交给由字节码解释器和基于 LLVM 的 JIT 编译器组成的混合模式执行引擎;他们最近为 JIT 编译器引入了或正在引入一个单独的中间表示(IR),因此解释器使用 Rubinius 字节码,但 JIT 编译器使用 Compiler IR。 Rubinius 也属于 "historically interesting" 类别,因为它是第一个成功的 Ruby 实现,其中很大一部分是在 Ruby 中实现的;之前还有其他项目,但 Rubinius 是第一个准备好投入生产的项目。
  • JRuby:主模式是一个混合模式的执行引擎,由一个 AST-walking 解释器和一个 JIT 编译器组成,JIT 编译器首先将 AST 翻译成 IR,然后进一步编译成 JVM 字节码.另一种模式是 AOT 编译器,它提前将 Ruby 源代码编译为 JVM 字节码。
  • Opal:将 Ruby 源代码编译为 ECMAScript 源代码的 Ahead-Of-Time 编译器。
  • MagLev:基于 GemStone/S Smalltalk VM 的实现。不幸的是,我对此知之甚少,我相信它将 Ruby 源代码编译为 GemStone/S 字节码,然后 GemStone/S VM 是一个标准的混合模式 VM,带有一个字节码解释器和一个JIT 编译器。

一些不再维护但历史上有趣的实现:

  • Topaz:使用 RPython/PyPy VM 框架的实现; PyPy 框架很有趣,因为它包含一个跟踪 JIT 编译器,与其他 JIT 编译器不同,该编译器不工作 除了 解释器和编译用户程序,而是编译 解释器 在解释用户程序时。这基本上意味着 PyPy 开发人员只需编写一次 JIT,并且每个使用 PyPy 框架的语言实现者只需编写一个简单的字节码解释器即可免费获得优化的本机 JIT 编译器。
  • XRuby:Ruby 的第一个静态 AOT 编译器,为 JVM 实现。
  • IronRuby:它最开始是一个没有解释器的纯JIT编译器,但是后来添加了解释器,因为事实证明这实际上提高了性能(这与解释器速度慢的流行神话相反)。
  • unholy:概念验证 AOT 编译器,可将 YARV 字节码编译为 CPython 字节码;当 Google App Engine 首次出现并且只支持 Python 时,这被 _why the lucky stiff 破解了,当时的想法是您可以使用 YARV 将 Ruby 源代码编译为 YARV 字节码,使用unholy将YARV字节码编译成CPython字节码,使用decompyle将CPython字节码编译成Python源码,然后将Python源码上传到GAE到[=111] =] 你闪亮的新 Ruby 应用程序。
  • 荣誉提名转到:tinyrb、metaruby、Ruby.NET、Red Sun、HotRuby、BlueRuby、SmallRuby

几个有趣的当前研究项目是:

  • JRuby+Truffle:该项目正在使用来自 Oracle 实验室的 Truffle AST 解释器框架重新实现 JRuby 的内部结构;这个版本,当 运行 在启用 Graal 的 JVM(另一个 Oracle 实验室研究项目)上能够获得类似于 Java 的性能,有时甚至达到(并超过)C.
  • Ruby+OMR:IBM 已将其 J9 JVM 分解为可独立重用、独立于语言的构建块,供 VM 实施者使用,并在 Eclipse 保护伞下的开源许可下作为 Eclipse Open 发布托管运行时。这不是一个学术项目:Java 8 版本的 IBM J9 实际上是使用 OMR 实现的。 Ruby+OMR 项目是 OMR 开发人员的概念验证,用 OMR 替换 YARV 的垃圾收集器,并将 OMR 的 JIT 编译器、分析器和调试器添加到 YARV。令人印象深刻的是 如何 所有的东西都是独立于语言的,整个补丁不到 10000 行,这不仅仅是胶水代码,它实际上 还包括 所有必需的 OMR 组件。 (还有一个等效的 Python+OMR 项目,但仍然是非 public。)

最后但同样重要的是,您有时可能会听说 "Rite"。十多年来,Rite 一直被用作完全重写 MRI 的代号。 Matz 说,当他写 MRI 时,他实际上对语言实现一无所知,所以他想 "right"(明白吗?)再写一遍。与此同时,也有很多关于 Ruby 2.0 的讨论,希望修复语言中一些长期存在的设计缺陷。两者混为一谈,因此 Rite 被称为 Ruby 2.0 的新实现。然而,YARV 的出现非常好,以至于 Matz 决定他根本不需要编写自己的 VM,他基本上决定 "YARV is Rite".

但现在,尽管如此,他确实编写了自己的 VM,这就是为什么您有时会听到 MRuby(或其 VM 组件)被称为 "Rite"。

Ruby 现在有一个 VM-generated JIT 编译器!

由于合并了 2.6.0-preview1 分支,Ruby 现在有一个基本的 JIT 编译器,称为 "MJIT" (YARV MRI Jit)。它的灵感来自 Vladimir Makarov 的作品,他提出了一种基于 RTL(寄存器传输语言)的指令集,而不是基于堆栈的指令集。加速还不明显,因为并非所有指令路径都由 MJIT 处理,但分支包含未来工作的基础。