SpiderMonkey 技术专题简介-冯金伟博客园

简介

SpiderMonkey开发者Mozilla基金会/Mozilla公司当前版本45 (2016年3月8日;稳定版本)52.7.2 (2018年3月15日;不稳定版) 源代码库hg.mozilla.org/mozilla-central/ 编程语言C/C++操作系统跨平台系统平台IA-32、x86-64、ARM、MIPS、SPARC类型JavaScript引擎许可协议MPL网站spidermonkey.devSpiderMonkey是世界上第一款JavaScript引擎,由前网景公司的布兰登·艾克设计,后期由Mozilla基金会维护,以开放源代码发布。目前为Mozilla Firefox网页浏览器所使用的JavaScript引擎,并也被嵌入到其他许多环境,例如GNOME 3桌面。

历史

1995年,艾克被招聘到Netscape,目的是让他在浏览器中实现Scheme编程语言,于是他于10天内开发出JavaScript (当工程管理决定这个编程语言必须长得像Java时,使用Scheme的想法被放弃)。之后艾克必须为这个重大的技术负债付出代价,在1996年秋天,艾克留在家里两个礼拜,并且重写了Mocha程序库,也是后来大家所知道的SpiderMonkey。SpiderMonkey这个名字源自于电影瘪四与大头蛋横贯美国,电影里的角色Tom Anderson提到,主要演员就像一对蜘蛛猴(Spider Monkey)夫妻在自慰。2011年,艾克将SpiderMonkey代码的管理交给戴夫·曼达林(Dave Mandelin)。

TraceMonkey

TraceMonkey是第一个为JavaScript语言编写的JIT编译器,于2008年8月23日发布并最先作为Firefox 3.5的SpiderMonkey中的编译引擎。相比Firefox 3.0的编译器,它提供了高达20到40倍的性能改善

比起编译全部函数,TraceMonkey采用追踪即时编译(trace Just-in-time Compilation)将JavaScript编译成二进制码(Binary code)以提高执行性能,它的运作方式是在执行期间借由追踪和记录控制流程及数据类型,将其用于建构追踪树(Trace Trees)(页面存档备份,存于互联网档案馆),以生成高度优化路径的原生码,追踪树技术由欧文加利福尼亚大学研究团队贡献,安德里亚斯·加尔是该团队的负责人。

JägerMonkey的增进,使得TraceMonkey被遗弃,特别是在SpiderMonkey中类型推论引擎的开发,TraceMonkey自Firefox 11开始已经被停止使用。

JägerMonkey

JägerMonkey由Mozilla自2010年年初开发,在内部被称为MethodJIT,它被用来改善性能,特别是当某些情况下TraceMonkey无法生成稳定的原生码。JägerMonkey于Mozilla Firefox 4开始被使用,采用组合编译(Method JIT)和汇编器(Assembler),它的汇编器移植自WebKit的Nitro引擎(SFX,SquirrelFish Extreme)。后期Method JIT与TraceMonkey的Tracing JIT集成,使SpiderMonkey的速度更快。

JägerMonkey的运作很不同于其他编译器,传统的编译器是借由创建控制流图并将其优化,JägerMonkey则是透过重复线性前进循环SpiderMonkey字节码,也就是内部函数表示法。虽然这种方式阻碍重新排序指令的优化,但这对JavaScript这个经常改变变量类型而需要重新编译的语言来说,JägerMonkey有快速编译的优势。

Mozilla在JägerMonkey中实做了一个临界值的优化,重要的还有多形态内嵌缓存( Polymorphic inline caching)及类型推论,Kraken和V8测试分数显示,类型推论可以分别带来44%与30%的分数提升。

TraceMonkey及JägerMonkey的JIT技术的异同在一篇hacks.mozilla.org的文章(页面存档备份,存于互联网档案馆)中有做解释,深入的技术细节可在一篇由SpiderMonkey的开发者Chris Leary的文章中获取,更多技术信息还可在其他开发者的博客中找到:dvander(页面存档备份,存于互联网档案馆)、dmandelin。

标准

SpiderMonkey实现了ECMA-262第5.1版(ECMAScript)和其他许多特色,而ECMA-357(ECMAScript for XML (E4X))已在2013年取消支持。

即便SpiderMonkey在Firefox中被使用,它并不提供一些主要环境,像是文档对象模型(DOM)。

内部

SpiderMonkey是以C和C++语言编写,并包含解释器、IonMonkey即时编译和垃圾回收器。

IonMonkey

IonMonkey是Mozilla的第三个JIT编译器,它激活了许多新的优化技术,但是这些特色无法在之前的JägerMonkey架构运行。

IonMonkey更像传统的编译器,它使用中间表示层(IR,Intermediate representation)的静态单赋值形式将SpiderMonkey的字节码转换为控制流图(Control Flow Graph),这个结构令其他语言使用的优化技术可被使用在JavaScript,其中包含形态的特殊化(type specialization)、内联函数(Inline function)、线性扫描的寄存器配置(linear scan register allocator)、死码删除(Dead code elimination)以及尽可能将程序移出循环外(Loop-Invariant Code Motion)。

该编译器可以在ARM、X86及X86-64上快速的将JavaScript函数转换成原生码。

2013年初发行的Firefox 18中开始采用IonMonkey并将其作为默认引擎,这改进了TraceMonkey与JaegerMonkey不会对代码进行解析、自动运行优化的缺点。。

OdinMonkey

OdinMonkey被用于优化JavaScript的子集asm.js,OdinMonkey并非一个JIT编译器,它依然采用IonMonkey作为编译器,这于2013年6月25日正式发布的Firefox 22起采用。

实现

SpiderMonkey可被嵌入于应用程序中,并为应用程序提供执行JavaScript的能力。不完整名单如下:

Mozilla Firefox、Thunderbird、SeaMonkey

Adobe Acrobat、Adobe Reader、Adobe Flash Professional、Adobe Dreamweaver

GNOME桌面环境,第3版和更高版本

Yahoo! Widgets

UOX 3,网络创世纪私人服务器

FreeSWITCH,开放源代码通信软件

0 A.D.,即时战略游戏

ELinks(英语:ELinks),纯文字网页浏览器

Synchronet(英语:Synchronet),BBS、电子邮件和服务器软件

SpiderMonkey亦提供了JavaScript Shell,它是一个交互式开发环境,可让开发者使用命令行来执行JavaScript程序。许多大型组织使用SpiderMonkey来管理他们前端应用程序的JavaScript。