众所周知, 现代的Web应用程序运行更多的JavaScript代码 比几年前 尽管编译器已迅速追随潮流 并提高了JavaScript的效率, 对于Mozilla,必须实施解决方案以更好地处理此工作负载。
为此, Mozilla开发并添加了新的字节码解释器 的JavaScript 内置到Firefox 70中的JavaScript渲染引擎。 随着Firefox 70将于明年XNUMX月面世,Mozilla宣布将使用添加到其JavaScript引擎中的新代码解释器来更好地进行JavaScript代码管理。
为了实现这一目标, Mozilla解释说 在现代JavaScript引擎中,每个函数最初都是在代码解释器中执行的。
被大量调用的函数被编译为本地机器代码。 这被称为JIT编译或即时编译。 至于 Firefox还包括一个用C ++编写的JavaScript代码解释器以及各种级别的JIT编译。
首先,我们有一个基本的JIT编译器,它使用内联缓存将每个字节码语句直接编译为一小段机器代码,从而为称为IonMonkey或Ion的JIT编译器提供性能和信息收集。
反过来,IonMonkey编译器使用高级优化来为关键选项生成快速代码。
应该注意的是,当使用一种新的参数类型调用已经被编译的函数时,该函数中的代码可以被“去优化”并丢弃。 在这种情况下,执行将在基础代码中继续进行,直到下一个离子构建为止。
尽管到目前为止,解释JavaScript代码的过程运行良好,但是 Firefox解释说,第一个浏览器遇到了一些问题 部分 由C ++解释器和基本的JIT编译器组成。
事实上, 一些现代的Web应用程序 例如Google文件或Gmail 运行太多的JavaScript以至于编译器 基本甚至是JIT编译器 他们可能会花很长时间尝试编译成千上万个函数。
而且,C ++解释器的运行速度非常慢,并且不收集类型信息,从而延迟了基本编译。 一种解决方案是将其从线程中拉出来,但这会带来性能风险。
为了解决这些问题,Mozilla的人员评论说:
基本解释器在C ++解释器和基本JIT编译器之间,并且包含两个级别的元素。
使用固定的解释器循环(如C ++解释器)执行所有字节码语句,并使用内联缓存技术提高性能并收集类型信息(如基本JIT那样)。
生成解释器并不是一个新主意。 但是Firefox团队在这里指出,他们通过重用大多数基本的JIT编译器代码找到了一种新的方法。 基本的JIT编译器是JIT模型,这意味着将每个中间代码指令编译成基本上固定的机器指令序列,然后在解释循环中建议这些序列。
另外,由于 Firefox开发人员希望基本解释器使用完全相同的在线缓存 和与JIT相同的信息,添加了一个称为JitScript的新数据结构。
JitScript包含基本解释器和JIT编译器使用的所有类型信息和内联缓存数据结构。
通过这些新的实现,功能的基本编译器数据现在仅在机器代码中。 从那里,所有缓存的信息和概要分析数据都已移至JitScript。
另一方面,由于基本解释器和JIT编译器相同,因此许多生成的代码也可以共享。
为此,创建了一个名为BaselineCodeGen的基类以及其他2个派生类。 基本编译器使用第一类BalineCompiler将脚本的字节码编译为机器代码。
第二个BaselineInterpreterGenerator类用于为基本解释器生成代码。 借助BaselineInterpreterGenerator类,Firefox团队成功构建了基本解释器。
数据来源: https://hacks.mozilla.org/