v8
Lars Bak是这个项目的组长,目前该JavaScript引擎已用于其它项目的开发。第一个版本随着第一个版本的Google Chrome于2008年9月2日发布。
基本介绍
V8使用C++开发,并在谷歌浏览器中使用。在运行ECMAScript之前,相比其它的JavaScript的引擎转换成字节码或解释执行,V8将其编译成原生机器码(IA-32, x86-64, ARM, or MIPS CPUs),并且使用了如内联缓存(inline caching)等方法来提高性能。有了这些功能,JavaScript程序在V8引擎下的运行速度媲美二进制程序。V8中实现的ECMAScript中指定ECMA-262,第3版运行在Windows XP和Windows Vista, MacOS X的10.5(雪豹)和Linux使用IA-32或ARM处理器。V8可以独立运行,也可以嵌入到任何C++应用程序。项目托管在谷歌 Code上,基于BSD协议,任何组织或个人可以将其源码用于自己的项目中。
历史
Google为其Google Chrome创建了V8,两者均于2008年首次发布。V8的首席开发人员是Lars Bak ,它因强大的汽车引擎而得名。多年来,Chrome 执行ECMAScript 的速度比其他浏览器更快。
V8汇编器基于Strongtalk汇编器。 2010 年 12 月 7 日,发布了名为 Crankshaft 的新编译基础架构,速度有所提高。在 2015 年的 Chrome 41 版本中,添加了 TurboFan 项目,以便为以前具有挑战性的工作负载(例如asm.js )提供更多性能改进。V8 的大部分开发都受到Sun Microsystems开发的Java HotSpot 虚拟机的强烈启发,较新的执行管道与 HotSpot 的执行管道相似。
对新WebAssembly语言的支持于 2015 年开始。
2016年,V8中添加了Ignition解释器,设计目标是与TurboFan和Crankshaft相比,减少小内存Android手机的内存使用量。 Ignition 是一个基于寄存器的机器,与 HotSpot 使用的模板解释器具有相似(尽管不完全相同)的设计。
2017年,V8发布了全新的编译器管道,由Ignition(解释器)和TurboFan(优化编译器)组成。从 V8 版本 5.9 开始,V8 中不再使用 Full-codegen(早期基线编译器)和 Crankshaft 来执行 ECMAScript,因为团队认为他们不再能够跟上新的 JavaScript 语言功能以及这些功能所需的优化。
2021 年,随着 SparkPlug 编译器的发布,引入了新的分层编译管道,它补充了 V8 中现有的 TurboFan 编译器,与 HotSpot 使用的分析 C1 编译器直接并行。
2023 年,添加了基于 Maglev SSA的编译器,它比 Sparkplug 慢 10 倍,但比 TurboFan 快 10 倍,弥补了 Sparkplug 和 TurboFan 之间的差距,适用于频率较低的运行循环,这些循环的“热”程度不足以通过TurboFan,就像大多数 Web 应用程序的情况一样,它们与浏览器交互的时间多于 ECMAScript 执行的时间。
设计
V8引擎的设计受到了Sun Microsystems开发的Java HotSpot虚拟机的启发,特别是在新的执行管道方面,它与HotSpot的设计非常相似。2010年,V8引入了Crankshaft编译基础设施,以提高执行速度。2015年,为了进一步提升性能,尤其是对于如asm.js这样的复杂工作负载,V8添加了TurboFan项目。2016年,为了在内存受限的Android手机上减少内存使用,V8引入了Ignition解释器。2017年,V8发布了包括Ignition(解释器)和TurboFan(优化编译器)的全新编译器管道,取代了Full-codegen和Crankshaft。2021年,V8引入了SparkPlug编译器,进一步优化了编译管道。
V8的执行过程首先是使用自己的解析器生成抽象语法树,然后Ignition解释器从这个语法树生成字节码,最后TurboFan将字节码编译成机器码。V8的即时编译技术允许它在执行前将ECMAScript编译成本地机器码,并根据代码的执行情况动态进行优化和重新优化。V8的垃圾收集器是一种分代增量收集器,旨在优化内存管理。
V8不仅可以在浏览器中使用,还可以集成到独立项目中,例如Couchbase数据库服务器、Deno运行环境、Electron桌面应用程序框架、MarkLogic数据库服务器、NativeScript移动应用程序框架、Node.js运行环境和Qt Quick运行环境。此外,V8还被移植到了PowerPC和IBM 欧洲航天局/390架构上。Firefox浏览器也将V8的部分功能移植到了其正则表达式解析器中。
运作方式
V8在执行之前将ECMAScript编译成了机器代码,而非字节码或是解释执行它,以此提升性能。更进一步,使用了如内联缓存(inline caching)等方法来提高性能。有了这些功能,JavaScript程序与V8引擎的速度媲美二进制编译。
传统的Javascript是动态语言,又可称之为Prototype-based Language,JavaScript继承方法是使用prototype,透过指定prototype属性,便可以指定要继承的目标。属性可以在运行时添加到或从对象中删除,引擎会为执行中的对象建立一个属性字典,新的属性都要透过字典查找属性在内存中的位置。V8为object新增属性的时候,就以上次的hidden class为父类别,创建新属性的hidden class的子类别,如此一来属性访问不再需要动态字典查找了。
为了缩短由垃圾回收造成的停顿,V8使用stop-the-world, generational, accurate的垃圾回收器。在执行回收之时会暂时中断程序的执行,而且只处理对象堆栈。还会收集内存内所有对象的指针,可以避免内存溢出的情况。V8汇编器是基于Strongtalk汇编器。