V8的点火系统到底是做什么的?

6
https://v8.dev/docs/ignition上,我们可以看到:

Ignition是一个快速的、基于寄存器的低级别解释器,使用TurboFan的后端编写。

https://docs.google.com/document/d/11T2CRex9hXxoJwbYqVQ32yIPMh0uouUZLdyrtmMoL44/edit?ts=56f27d9d#上:

Ignition项目的目标是为V8构建一个解释器,该解释器执行低级别的字节码,从而使只运行一次或非热代码以字节码形式更紧凑地存储。

解释器本身由一组字节码处理程序代码片段组成,每个处理程序处理特定的字节码并分派到下一个字节码的处理程序。这些字节码处理程序

要将函数编译为字节码,必须解析JavaScript代码以生成其AST(抽象语法树)。BytecodeGenerator遍历此AST,并根据需要为每个AST节点生成字节码。

一旦产生字节码处理程序的图表,它就通过Turbofan简化版本的流水线,并分配给解释器表中相应的条目。

因此,看起来Ignition的工作是将由BytecodeGenerator生成的字节码转换为字节码处理程序,并通过Turbofan执行它。
但在这里:enter image description here和这里enter image description here,您可以看到是Ignition产生了字节码。
此外,在这个视频中https://youtu.be/p-iiEDtpy6I?t=722中,Ignition被称为基线编译器。
那么它是什么? 基线编译器? 字节码解释器? AST到字节码转换器?
这张图片似乎最合适:enter image description here,其中Ignition只是一个解释器,而之前的一切都是一个没有名字的字节码生成器/优化器。

enter image description here


1
遗憾的是,其中一些文档已经过时了,包括上面第一个图形的文档。 Full-codegen和Crankshaft已经不再使用,现在仅使用Ignition+TurboFan。 - T.J. Crowder
1
@T.J.Crowder 我已经将图像更改为更现代的内容。 - marzelin
好东西。你在哪里找到的? - T.J. Crowder
1
从这里开始:@T.J.Crowder(来自https://docs.google.com/presentation/d/1OqjVqRhtwlKeKfvMdX6HaCIu9wpZsrzqpIVIwQSuiXQ/)。实际上,这些幻灯片相当古老,因为它们是为2016年的这次演讲https://www.youtube.com/watch?v=r5OWCtuKiAk准备的,但其中一些仍然相关。 - marzelin
谢谢。是的,官方文档链接到过时的信息是不幸的,但是嘿,他们有很多事情要做(我很感激他们的付出)。我会想帮助文档的,但这是一个比我目前能承担的更大的项目。 :-) - T.J. Crowder
3个回答

11

我是一名V8开发者。

https://v8.dev/docs/ignition上我们可以看到:

Ignition是一个快速的低级寄存器解释器,使用TurboFan的后端编写

没错,这就是它的概括。再补充一些细节:

  • "Ignition" 这个名字既指字节码生成器(Bytecode Generator),也指字节码解释器(Bytecode Interpreter)。通常情况下,整个东西也被视为一个大黑盒子,并随意称之为“解释器”,这有时可能会导致术语上的混淆。
  • 字节码生成器接受由解析器为给定的JavaScript函数产生的AST,并从中生成字节码。
  • 字节码解释器接受字节码生成器生成的字节码,并通过将其发送到一组字节码处理程序来解释执行它。
  • 组成字节码解释器的字节码处理程序是使用Turbofan管道的部分生成的。这是在V8编译时发生的,而不是运行时。换句话说,您需要Turbofan来构建(部分)Ignition,但不需要Turbofan来运行Ignition。
  • 解析器(以及它产生的AST / 抽象语法树)不是Ignition的一部分。

一旦字节码处理程序的图形被生成,它就会通过Turbofan的简化版本管道,并分配给解释器表中的相应条目。

因此,看起来Ignition的工作是将由BytecodeGenerator生成的字节码转换为字节码处理程序,并通过Turbofan执行它。

本设计文档的这一部分讨论生成字节码处理程序,这是在“预编译”时使用Turbofan的部分完成的(即当V8被编译时)。在运行时,字节码不会被“转换”为处理程序,而是由现有的固定处理程序集“处理”(=运行,执行,解释),并且Turbofan不参与其中。
此外,在这个视频中https://youtu.be/p-iiEDtpy6I?t=722,Ignition被称为一个基线编译器。在那个时候,谈话涉及到所有现代JavaScript引擎都有一个“基线编译器”的一般概念(在非常一般的概念上——我同意幻灯片可能应该更清晰地表达)。请注意,幻灯片没有提到Ignition。下一张幻灯片说Ignition在V8中填补了这个角色。因此,更准确的说法是“Ignition取代了一个基线编译器”,或者“Ignition是一个基线执行引擎”。或者您可以稍微重新定义术语,说“Ignition是一个生成字节码然后解释它的编译器”。
那张幻灯片显示“解释器”框作为“Ignition Bytecode Pipeline”的一部分。字节码生成器/优化器也是Ignition的一部分。

谢谢你的回答。我最困惑的是有些幻灯片显示字节码来自点火解释器,而其他幻灯片则显示字节码是点火的输入。 "Ignition Bytecode Pipeline" 是点火的内部部分还是外部辅助部分? - marzelin
“Pipeline” 在这里的意思是“按顺序描述事情发生的方式”。解析器生成AST,字节码生成器从AST生成字节码,然后字节码首先由字节码解释器执行几次,再作为Turbofan生成优化代码的输入。术语“Ignition”同时指代字节码生成器和字节码解释器。(也就是说,“Ignition”最终只是一个项目名称,对于理解如何工作,覆盖在该伞下的V8代码的哪些部分并不重要。) - jmrk
啊,我现在明白了:Ignition 最初是一个内部项目名称,后来成为营销目的的“引人注目的总称”,以产生一些炒作。从技术角度来看,它不过是在 2016 年左右发布的 V8 的一组大修改而已。没有“Ignition 解释器”,只有解释器、生成器、编译器等。谢谢。 - marzelin
这是一种看待它的方式。我会说有一个Ignition字节码生成器和一个Ignition字节码解释器,所以"Ignition"就是它们两个的结合体。但是,重要的是代码及其功能,而不是你用来指代各个部分的名称。 - jmrk
嗯,你团队中的一些人似乎没有注意到生成器的存在,而将所有功劳归功于解释器。例如,在你们的团队博客上可以看到“由V8的Ignition解释器产生的字节码”这样的内容:https://v8.dev/blog/v8-release-56 - marzelin
显示剩余5条评论

6
如我在评论中提到的那样,遗憾的是一些文档已经过时,包括你上面第一张图的文档。Full-codegen和Crankshaft已经完全不再使用,现在只有解析和Ignition+TurboFan。 (你已经从某些V8文档中删除了过时文档中的图片)

Ignition是一个高速字节码解释器。

V8的解析器生成Ignition字节码。该字节码由Ignition执行(解释)。只运行一次的代码(启动代码等)或很少运行的代码保持在字节码级别,并继续由Ignition执行。

"热"代码进入第二阶段,TurboFan接管:TurboFan的输入与Ignition解释的相同字节码(而不是像Crankshaft一样的源代码),然后将其积极编译为高度优化的机器码直接运行(而不是被解释)。

这篇文章探讨了放弃Full-codegen和Crankshaft的动机(前者节省内存,后者实现和优化语言特性的难度)。TurboFan的设计还帮助V8作者最小化他们必须编写的平台特定代码量(通过具有中间表示形式,其中包括它们也可以用来编写Ignition的字节码处理程序)。

您好,Crowder先生,非常感谢您提供如此出色的答案,我想请教一些问题。Crowder先生,解析器生成AST,然后生成字节码。然后,Ignition执行生成的字节码,并在运行时监视和寻找需要进行优化的部分,如果Profiler发现热点函数,则TurboFan对其进行优化。因此,TurboFan可以即时优化代码。Crowder先生,我想问的问题是为什么在V8中引入了Ignition,我认为多亏了Ignition,我们可以从字节码生成更紧凑和高效的机器代码。这正确吗? - Dickens
另外,Crowder先生,解析器是否真的生成字节码而不是Ignition?在大多数文章中都写着字节码是由Ignition本身生成的,但是您上面写道解析器生成字节码。 - Dickens
@Dickens - "我认为得益于Ignition,我们从字节码生成了更紧凑、高效的机器码。" 我不这么认为。Ignition 的最初动机是为了减少移动设备上的内存消耗,有关详情请参见链接的文章。*"解析器是否真的生成字节码而不是Ignition?"* 解析器是Ignition的一部分 - T.J. Crowder
1
点火是否执行字节码并将其解释为机器代码,以便浏览器能够理解?当我们的应用程序由点火执行时,分析器会分析并寻找热函数,如果找到,则将热函数传递给编译器进行优化。然后,在编译器完成优化后,编译器将使用优化代码更改代码的某些部分。这正确吗?先生。 - Dickens
1
@Dickens - 基本上是的。 - T.J. Crowder

0
请纠正我对转换过程的理解中的错误:
  • 将JS代码解析为AST
  • 将AST发送到Ignition以转换为字节码
  • 生成机器码
  • 如果字节码是最优的,则将其发送到CPU进行处理
  • 如果字节码需要优化,则将其发送到Turbofan进行优化
  • 如果Turbofan收到字节码,则进一步优化并发送到计算机进行处理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接