最近有很多关于JägerMonkey (JM) 文章的帖子,其中一些帖子对 Mozilla JM 工作中使用的技术部分有一些细微的错误。 所以这里有一个关于我们正在使用的技术、各个部分的功能以及它们来源的快速概述。
1. SpiderMonkey. 这是 Mozilla 的核心 JavaScript 解释器。 该引擎将原始 JavaScript 代码转换为中间字节码。 然后解释该字节码。 SpiderMonkey 负责 Firefox 3 及更早版本的所有 JavaScript 处理。 我们继续改进该引擎,因为它仍然是我们许多在 Firefox 3.5、3.6 及更高版本中所做工作的基础。
2. 跟踪. 跟踪是在 Firefox 3.5 之前添加的,它负责我们在性能方面取得的大幅提升。(尽管其中一部分是因为我们也改进了底层的 SpiderMonkey 引擎。)
这是我们跟踪的方式
- 在执行期间监控解释的 JavaScript 代码,查找使用次数超过一次的代码路径。
- 当我们找到使用次数超过一次的代码片段时,优化该代码。
- 将该优化后的表示形式组装成机器代码并执行它。
自从 Firefox 3.5 以来,我们发现当我们处于完全跟踪模式时,速度非常快。 当我们必须“回退”到 SpiderMonkey 并解释 + 记录时,速度很慢。
跟踪的难点之一是生成快速运行的代码。 这由一段称为 Nanojit 的代码完成。 Nanojit 是最初是 Tamarin 项目的一部分的代码。 Mozilla 不使用大部分 Tamarin 有两个原因:1. 我们没有发布 ECMAScript 4,2. Tamarin 的解释部分比 SpiderMonkey 慢得多。 对于 Firefox 3.5,我们采用了最好的部分——Nanojit——并将其与 SpiderMonkey 连接起来。
Nanojit 做两件事:它接受 JavaScript 的高级表示形式并进行优化。 它还包含一个汇编程序,用于将优化后的表示形式转换为用于机器级执行的本机代码。
Mozilla 和 Adobe 继续在 Nanojit 上进行合作。 Adobe 使用 Nanojit 作为其 ActionScript VM 的一部分。
3. Nitro 汇编程序. 这是一段我们从 Apple 的 webkit 版本中获取的代码,用于生成用于执行的本机代码。 Nitro 汇编程序与 Nanojit 非常不同。 虽然 Nanojit 接受高级表示形式、进行优化然后生成代码,但 Nitro 汇编程序只生成代码。 所以它很复杂,是底层代码,但它没有执行 Nanojit 所做的事情。
我们正在使用 Nitro 汇编程序(以及许多其他新代码)来构建每个人都拥有的东西——编译后的 JavaScript——然后我们将做与 Firefox 3.5 相同的事情——将跟踪与之连接起来。 所以我们希望拥有所有最好的东西:SpiderMonkey 生成用于执行的本机代码,就像其他 VM 一样,并且能够继续跟踪以获得更紧密的内循环以获得更高的性能。
我希望这有助于解释我们正在使用哪些技术片段以及它们如何融入 Firefox 的 JS 性能的整体图景。
33 条评论