② Ignition 模块: 一个解释器,可以将 AST 转换成 ByteCode(字节码)。字节码(Byte-code):是一种包含执行程序,由一序列 op 代码/数据对组成的二进制文件,是一种中间码。将 JS 代码转成 AST 是便于引擎对其进行操作,前面说到 JS 代码最终是转成机器码给 CPU 执行的,为什么还要先转换成字节码呢?因为 JS 运行所处的环境是不一定的,可能是 Windows 或 Linux 或 iOS,不同的操作系统其 CPU 所能识别的机器指令也是不一样的。字节码是一种中间码,本身就有跨平台的特性,然后 V8 引擎再根据当前所处的环境将字节码编译成对应的机器指令给当前环境的 CPU 执行。参考官方文档:https://v8.dev/blog/ignition-interpreter
③ TurboFan 模块: 一个编译器,可以将字节码编译为 CPU 认识的机器码。在了解 TurboFan 模块之前可以先考虑一个问题,如果每执行一次代码,就要先将 AST 转成字节码然后再解析成机器指令,是不是有点损耗性能呢?强大的 V8 早就考虑到了,所以出现了 TurboFan 这么一个库;TurboFan 可以获取到 Ignition 收集的一些信息,如果一个函数在代码中被多次调用,那么就会被标记为热点函数,然后经过 TurboFan 转换成优化的机器码,再次执行该函数的时候就直接执行该机器码,提高代码的执行性能;图中还存在一个 Deoptimization 过程,其实就是机器码被还原成 ByteCode,比如,在后续执行代码的过程中传入热点函数的参数类型发生了变化(如果给 sum 函数传入 number 类型的参数,那么就是做加法;如果给 sum 函数传入 String 类型的参数,那么就是做字符串拼接),可能之前优化的机器码就不能满足需求了,就会逆向转成字节码,字节码再编译成正确的机器码进行执行;从这里就可以发现,如果在编写代码时给函数传递固定类型的参数,是可以从一定程度上优化我们代码执行效率的,所以 TypeScript 编译出来的 JavaScript 代码的性能是比较好的;参考官方文档:https://v8.dev/blog/turbofan-jit