1.V8的演变历史2008年,V8的第一个版本发布。当时V8架构比较激进。它直接将js代码编译成机器码执行,所以执行速度非常快,但是Codegen只有一个编译器,所以对代码的优化非常有限。2010年,V8发布了Crankshaft编译器。js代码将首先由Full-Codegen编译器编译。如果后续修改的代码块会被执行多次,会用Crankshaft编译器重新编译生成更优化的代码,然后使用优化后的代码执行,从而提高性能。Crankshaft编译器对代码的优化有限,所以2015年V8加入了TurboFan编译器,此时V8还是直接将源代码编译成机器码执行。这个架构有一个核心问题,就是内存消耗特别大(一般是几KB的文件,转换成机器码可能是几十MB,会造成巨大的内存空间)。2016年,V8加入了Ignition编译器,重新引入了字节码,旨在减少内存占用。2017年,V8正式发布了新的编译流水线,使用Ignition和TurboFan的组合来编译和执行代码。从此(V85.9版本)开始,不再使用早期的Full-Codegen和Crankshaft编译器来执行js。在最新的架构中,共有三个核心模块:解析器(Parser)、解释器(Ignition)、优化编译器(TurboFan)。V8在执行js源码时,首先解析器会将源码解析成抽象语法树(AbstractSyntaxTree),然后解释器将AST翻译成字节码,边解释边执行。在这个过程中,解释器会记录特定代码段的运行次数。如果运行次数超过某个阈值,则将代码标记为热代码(hotcode),并将运行信息反馈给优化编译器(TureboFan)。优化编译器根据反馈信息,对字节码进行优化编译,最终生成优化后的机器码。这样,再次执行代码时,解释器将直接使用优化后的机器码执行,无需重新解释,从而大大提高了代码运行效率。这种在运行时编译代码的技术称为即时编译(JIT)。2、V8解析器将js源码解析成AST。这个过程会经过词法分析和句法分析,通过预解析提高执行效率。词法分析:将js源码解析成最小单位的token。在V8中,Scanner负责接收Unicode字符流并将其解析为token以供解析器使用。语法分析:根据语法规则,将标记组成具有前景层次的抽象语法树。在此过程中,如果源代码不符合语法规范,解析过程将终止并抛出语法错误。对于一段js源码,如果必须解析所有源码再执行,必然会面临三个问题:1.一次性解析所有代码,代码执行时间会变长。2.内存消耗会增加,因为解析出的AST和根据AST编译的字节码都会存放在内存中。3.占用磁盘空间,编译后的代码会缓存在磁盘上。因此,现在主流浏览器都进行延迟解析。在解析过程中,只对没有立即执行的函数进行预解析(PreParser),只有在调用函数时才进行全解析。预解析时,只验证函数的语法是否有效,解析函数声明,判断函数作用域,不生成AST。实现预解析的是Pre-Parser解析器。3、将V8解释器的Js源码转换成CPU可识别的机器码,消耗大量内存。V8引入字节码来解决内存使用问题。字节码是机器码的抽象。语法有点类似于汇编。可以看作是一一说明。解析器Ignition基于AST生成字节码并执行它。在这个过程中,会收集反馈信息,交给TurboFan进行优化编译。TurboFan根据Ignition收集的反馈信息将字节码编译成优化后的机器码,然后Ignition执行优化后的机器码而不是字节码。4.V8的优化编译器Ignition解释器在执行字节码的时候还是需要将字节码转换成机器码,因为CPU只能识别机器码,虽然多了一层字节码转换,看起来效率低,但是相比机器码,性能基于字节码的优化更方便。最重要的优化是使用TurboFan编译器编译热代码。在解释执行的过程中,Ignitio解释器会对重复执行的热代码进行标记。这些被标记的代码将被TurboFan编译器编译生成更高效的机器代码。TurboFan在工作时主要使用两种算法,一种是inline,一种是escapeanalysis。内联就是对嵌套的函数进行内联分析。对于下图左侧的代码,如果不进行优化直接编译代码,会生成两个函数的机器码。不过,为了进一步提升性能,TurboFan会优化这两个函数,先内联再编译。中间代码如下。再者,由于函数内部变量的值都确定了,所以可以进一步优化函数,如下图右侧代码所示。最终生成的机器码比优化前少很多,执行效率自然更高。通过内联,您可以降低复杂性、消除冗余代码、合并常量,而内联技术通常是逃逸分析的基础。逃逸分析就是分析对象的生命周期是否局限于当前函数。如果对象是在函数内部定义的,对象只在函数内部起作用,例如对象不返回,也不传递或调用给其他函数。这时,这个对象就被认为是“没有逃脱”。在编译优化时,使用标量替换未转义的对象,减少对象定义,从而减少从内存中访问对象属性,提高执行效率,减少内存占用。文章来自视频:https://www.zhihu.com/zvideo/...
