[资料] [链接帖] 各JavaScript引擎的简介,及相关资料/博客收集帖
RednaxelaFX
2013-04-20
之前一直有同学在问,于是开个帖来收集JavaScript引擎的资料链接。每个JavaScript引擎先简单写点我对它的了解,然后是资料和博客的链接。
链接顺序按其描述的功能在产品中出现的时间从新到旧排。 最终能做成个まとめ就好了,hmm。 慢慢更新。把以前收集的链接都转到这帖来。先从我写的发在自己博客和HLLVM群组这边的开始。欢迎回帖补充资料或提问讨论。 读的时候请考虑到发文时间——所有资料都只能代表当时的状况。 以前写过篇杂谈,虽然没直接写JavaScript引擎的具体实现,不过或许会对入门有帮助:虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩 (抱歉,这系列后面烂尾了没发出来…) 在另一帖里我简单写过几种实现解释器的方式的对比,字节码的作用之类:CPython能否用V8的方式优化性能 有一点想补充的是:关于基于栈与基于寄存器的字节码的对比,如果在字节码的后面是一个非常简易的初级JIT编译器,那基于寄存器的字节码未必比基于栈的字节码有多少优势: 基于栈的字节码的操作数栈(或者叫表达式栈)暗含着表达式中某些临时值的生命周期,而基于寄存器的字节码则要显式分析所有值的生命周期。这会影响到简易寄存器分配的效率。 不过如果前面生成字节码的编译器有做一定优化,那基于寄存器的字节码还是可以重夺优势:假设有条件离线对基于寄存器的字节码做优化,那可以尝试调整其虚拟寄存器的分配,让估计更“热”的值放在更靠近编号为0的虚拟寄存器里,然后在简易JIT编译器里的寄存器分配就可以固定的把虚拟寄存器映射到真实寄存器上,这就比较好。 ========================================================================== Ecma-262 ECMAScript 5.1 Annotated ECMAScript 5.1 ECMAScript 6 draft Ecma-402 ECMAScript Internationalization API Ecma-404 The JSON Data Interchange Format 还有一个没怎么见人提起的 Ecma-327 ECMAScript Compact Profile (ES-CP) 看看Mozilla的JavaScript介绍页面上都提到了哪些JavaScript引擎: https://developer.mozilla.org/en-US/docs/JavaScript/About_JavaScript ========================================================================== JavaScript与“无处不在的计算”或者说“普适计算” ubiquitous computing 在学习JavaScript,最好的办法就是多写代码多做实验。现在几乎走到哪儿都能找到设备运行JavaScript,比当年的BASIC还要通用。 在桌面上,主流浏览器(Chrome、Firefox、IE等)都自带开发者控制台,里面就可以直接试用JavaScript。 不在桌面上?在网页上试用JavaScript的好地方: http://jsconsole.com/ 实际上就是在网页中以控制台的形式暴露出浏览器内嵌的JavaScript引擎的功能。在平板电脑之类的不便于打开浏览器自身的控制台的地方特别好用。 iOS上可以试试Jsany - JavaScript Anywhere 与他人在线交流代码的好地方: http://codechat.net/ ========================================================================== 现代JavaScript引擎都有哪些特征呢?跟以前的JavaScript引擎有怎样的差别,为什么变快了那么多?这里简单写下我的理解吧。 有很多同学可能会想从JavaScript引擎的源码着手一探究竟。这里也顺便介绍一下JavaScript引擎大致的组成部分与工作流程。了解这其中涉及的各种术语都是什么意思的话,读源码就能事半功倍,很多时候光看文件名就足以定位到自己关心的那部分实现。 <- TODO 早期JavaScript引擎的实现普遍跟同时代的其它脚本语言一样,比较“偷懒”。反正是“脚本语言”,当时的JavaScript脚本通常只包含很简单的逻辑,只运行很短时间就完事。没啥性能压力,得不到足够的重视与开发资源,性能自然是好不到哪里去,却也足以满足当时的需求。 非常早期的“Mocha”引擎实现得确实非常偷懒。字节码解释器、引用计数方式的自动内存管理、fat discriminated union形式的值表现形式。现在随便找本教写玩具语言实现的书上或许就会这么教…但只能用来写玩具 犀牛书第4版写了点JavaScript与引用计数的历史。 到1996年,Brendan Eich新写的SpiderMonkey已经改为使用mark-and-sweep GC、tagged value。 于是其实早期的两个主要的JavaScript引擎实现,Mozilla SpiderMonkey和Microsoft JScript其实都一直在用mark-and-sweep GC。也没啥别的主流JavaScript引擎用过引用计数方式来实现自动内存管理的。这点别被忽悠了。在叫得出名字的JavaScript引擎里只有quad-wheel(没听说过么?不奇怪,非主流嘛)是用引用计数方式实现自动内存管理的。 (老版本IE里JScript虽说是有因为循环引用而导致内存泄漏的问题,但那不是因为JScript自身用引用计数。问题出在JScript与DOM交互的边界上:IE的DOM节点(及其它host对象)是COM对象,而COM对象自身是引用计数的。在JS一侧GC时DOM节点被看作根节点,所以被DOM节点引用的JS对象不会死;反过来,被JS对象引用的DOM节点的引用计数不为0所以也不会死。这导致JScript与DOM交互时有可能被连累引发循环引用->内存泄漏的问题。 IE9/Chakra里已经通过把DOM对象变成由JavaScript一侧的GC来管理解决了这个问题。) 几种较老的JavaScript引擎的特征:
(几个术语: 树遍历解释器:tree-walking interpreter。遍历抽象语法树来解释执行的解释器。 对象布局: object representation 或者 object layout。指在堆上分配的JavaScript对象的在内存中的布局。 值表现形式: value representation。注意跟“对象布局”说的不是一件事。这个指的是原始类型数据、指向堆上分配的对象的指针之类的值的表现形式。对某些JavaScript引擎来说这是指“JSValue”背后在内存中的表现形式。 TODO 加上对parser的描述
早期JavaScript引擎得到的投入实在不足,而当时的Java虚拟机(JVM)却得到了大量资源实现各种优化,包括JIT编译器之类。这使得用Java写的Rhino一度能比用C写的SpiderMonkey跑得还快,因为Rhino得益于JVM里优秀的JIT编译器和GC,而SpiderMonkey还在用简易的解释器和GC。 这个阶段中,JavaScript对象的布局或者说表现方式通常可以叫做“property bag”,本质上就跟hashmap一样。 在Google推出V8之后,业界受到巨大冲击。V8的性能远高于当时所有其它JavaScript引擎,可以有效支撑起当时兴起的大量使用JavaScript的Web应用。 各大JavaScript引擎的实现者都坐不住了,像打了鸡血似的使劲优化优化再优化。先是把已在其它HLLVM上得到充分验证的优化技术引入到JavaScript引擎中,然后再针对JavaScript语言的特点做专项优化。 现在(2013-04)几种主流的JavaScript引擎的特征:
(几个缩写: copying GC: 也叫scavenger。 MIC: monomorphic inline-cache PIC: polymorphic inline-cache pun-boxing: Packed NaN unboxing) SpiderMonkey和LuaJIT似乎都在用pun boxing 所以说这年头是个JavaScript引擎都得有JIT编译器了…没有都不好意思出来混。受到平台限制(例如iOS、Windows Phone)而无法实现JIT编译器的“第三方JavaScript引擎“只好哭了。 TODO -------------------------------------------------------------------------- 当代JavaScript引擎之间有许多共通的实现技巧。多数优化会对JavaScript程序的行为做一定猜测(speculate),并基于猜测做激进优化(speculative optimization)。 下面挑几个简单介绍一下。 从源语言到中间表示的编译器(source-to-IR compiler) 也叫做编译器的“前端”。 递归下降式语法分析器(recursive-descent parser) 运算符优先级式语法分析器(operator precedence parser) deferred parser / diet parser(延迟语法分析) 从中间表示到目标代码的编译器(IR-to-target-code compiler) 也叫做编译器的“后端”。但因为这部分编译器经常被叫做“JIT”编译器,所以单独拿出来写 JIT style compiler: “just-in-time编译”狭义的定义是“即时编译”,也就是在某段代码即将第一次被执行时才对其编译。太早或太迟都不符合这个狭义版定义。所谓“JIT风格的编译器”通常意味着“编译是同步进行的”。这就自然的引出几个特征:1、编译速度必须很快;2、编译只能做有限的优化,只能选效费比高的来做。 optimizing compiler 多层编译(tiered compilation) 后台编译(background compilation) 类型反馈(type feedback) 类型特化(type specialization) SSA-form IR 自动内存管理 分代式GC(generational GC) 增量式GC(incremental GC) 并发式GC(concurrent GC) 准确式GC(exact / accurate / type exact / type accurate / precise GC) 对象布局 紧凑对象布局 + 隐藏类 值表现形式 tagger-pointer 或 tagged-value NaN-boxing 运行时系统 inline-cache on-stack replacement deoptimization 用native stack实现VM stack cons-string 或者叫 rope 来优化字符串拼接 dependent string/sliced string 来优化字符串的子串操作 sparse array B-tree TODO -------------------------------------------------------------------------- 上面介绍的JavaScript引擎实现技巧也影响了“如何写出更高效的JavaScript代码”:尽量让代码的行为符合JavaScript引擎的猜测,效率就会高。 写类型稳定的代码 在构造器函数里声明和初始化所有属性 尽量不要delete属性;不要通过delete属性来把某个属性重置,赋值为undefined都好 不要把数组当一般对象用;不要把一般对象当数组用 TODO Kevin Gadd JavaScript Performance For Madmen -------------------------------------------------------------------------- JavaScript引擎在安全性方面面临的挑战 JIT hardening Matasano Security - Attacking Clientside JIT Compilers http://www.accuvant.com/sites/default/files/images/webbrowserresearch_v1_0.pdf Alexander Sotirov Heap Feng Shui in JavaScript 2013-02-19: Corelan Team (corelanc0d3r) DEPS – Precise Heap Spray on Firefox and IE10 有尝试从语言级别修正部分安全问题的,例如从capability based security方向入手的Caja ========================================================================== 接下来介绍各JavaScript的具体情况。请允许我抱有私心的先从Oracle自家的JavaScript实现,Nashorn开始;然后介绍一个较简单干净的新JavaScript实现,lv5;接下来再介绍其它引擎,哈哈 这些JavaScript引擎就微软和Opera的不开源,其它都是开源的。 其实现在实现高性能JavaScript引擎的技术都不是秘密了,死守源码实在是…诶。 结果Opera Carakan挂了,现在就剩微软系JavaScript引擎不开源。 1楼: Oracle Nashorn 2楼: lv5 3楼: Google V8 4楼: Mozilla SpiderMonkey系 (包括SpiderMonkey / Tamarin / TraceMonkey / JaegerMonkey / IonMonkey / Baseline) 5楼: Microsoft Chakra 6楼: Apple JavaScriptCore系 (包括JavaScriptCore / SquirrleFish / SquirrelFish Extreme (SFX) / Nitro) 7楼: Opera Carakan 8楼: KDE KJS 9楼: IronJS 10楼: Jurassic 11楼: dynjs 12楼: Microsoft SPUR 13楼: Mozilla Rhino 14楼: Digital Mars DMDScript 15楼: Microsoft JScript (特指Chakra之前的微软的JScript) 16楼: Microsoft Managed JScript 17楼: Mozilla Narcissus 18楼: Continuum 19楼: 杂项未整理资料 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RednaxelaFX
2013-04-21
Nashorn
官方网站: http://openjdk.java.net/projects/nashorn/ 官方博客: http://blogs.oracle.com/nashorn/ 官网Wiki: https://wiki.openjdk.java.net/display/Nashorn/Main 邮件列表: http://mail.openjdk.java.net/mailman/listinfo/nashorn-dev 兼容标准: ECMAScript 5.1 实现语言: Java 代码: http://hg.openjdk.java.net/nashorn/jdk8/nashorn 代码版本控制工具: Mercurial 开源许可证: GPLv2 -------------------------------------------------------------------------- 我的评论: Nashorn(读作Naz-horn)是Oracle全新开发的JavaScript实现。高度兼容ECMAScript 5标准,并尽可能兼容Rhino。它使用Java语言实现,运行在JVM上,借助JDK7开始包含的JSR 292(invokedynamic)新功能达到较高的性能,同时保持代码的相对整洁,适合对JavaScript内部实现感兴趣的同学阅读。 在2012年底Nashorn就已经达到可以完全通过test262测试套件的兼容性,就这点说它甚至比SpiderMonkey、V8更佳兼容于标准。 Nashorn起初是Oracle内部一个实验项目,用于验证JSR 292功能的完整性、可用性、易用性。后来得到了内部的关注,决定将其产品化,作为默认的JavaScript实现替换掉从JDK6开始包含在JDK之中的Rhino。 John Rose对Rhino做的现代化改造可以算是Nashorn的一种先驱: http://cr.openjdk.java.net/~jrose/pres/201009-ThunderingRhinos.pdf Nashorn显然从中获取了不少经验,但并未以Rhino的代码为基础来开发,而是完全重新写了。原因是Rhino本身的代码已经非常老旧,架构很难适应在现代JVM上高效实现JavaScript的需求,没啥值得复用的代码。 只从JVM以上的层面看,Nashorn是一种单层的纯编译型JavaScript实现。所有JavaScript代码在首次实际执行前都会被编译为Java字节码交由JVM执行。 (当然JVM自身可能是混合执行模式的,例如HotSpot VM与J9 VM。所以Nashorn在实际运行中可能需要一定预热才会达到最高速度) Nashorn不但可以执行JavaScript,还可以当作库为其它工具提供一些基础服务。例如说它现在为NetBeans IDE中的JavaScript编辑器提供语法高亮支持和调试支持。 从Oracle JDK 8 build 82开始,Nashorn已经作为JDK8的一部分包含在安装包中。安装后可以在JDK安装目录的jre/lib/ext/nashorn.jar找到Nashorn的实现。正式版的JDK8里jrunscript等工具都会由Nashorn提供执行JavaScript语言的支持;通过JSR 223 API获取默认的JavaScript引擎也会是Nashorn。 直接使用Java类的实例来容纳JavaScript对象的字段,在对象内嵌入字段而不放在spill array里的好处是: 1、对象更加紧凑,数据离得更近,局部性更好 2、数组访问有边界检查,而对象字段访问则没有,后者效率更高 PropertyMap JDK-8006220: Faster creation of properties Nashorn的hidden class transition记录在PropertyMap的“history”字段里,是个LinkedHashMap<Property, PropertyMap>。 所有同系列的PropertyMap都共享一个history。 Function.prototype.toString()由jdk.nashorn.internal.runtime.ScriptFunction.toSource()实现;具体来说由ScriptFunctionData的子类实现。其中由对应源码的(例如RecompilableScriptFunctionData)里会引用着FunctionNode,里面记录着起始和结束位置,通过这个信息到FunctionNode引用的Source里去找char[]的内容。 关于在现有VM平台上实现JavaScript或其它动态语言的讨论 Peng Wu Reusing JITs are from Mars, Dynamic Scripting Languages are from Venus -------------------------------------------------------------------------- 2014-03-14: Jim Laskey Latest news from the Nashorn team 2013-07: Marcus Lagergren Nashorn Was Stories (from a battle scarred veteran of invokedynamic), JVMLS 2013 video 2013-07: Attila Szegedi Fitting Nashorn on the JVM video 2013-07-09: Jim Laskey Nashorn Multithreading and MT-safety 2013-06-24: Dalibor Topic PodFodder: Project Nashorn Everywhere 2013-05-29: Jim Laskey reposting Gerrit Grunwald Repost: Taming the Nashorn (first impressions)..., Nashorn Blog 2013-05-15: Marcus Lagergren Nashorn: Implementing Dynamic Languages on the JVM, geecon 2013 https://oraclein.activeevents.com/connect/sessionDetail.ww?SESSION_ID=1143 https://oraclein.activeevents.com/connect/fileDownload/session/AB2BAC9C20881CFB16F17F359CAA0E4E/CON1143_Arora-akhil-nashorn-node.pdf 2013-05-08: Hannes Wallnoefer CON1200 - Project Nashorn in Java 8 - Javascript As a First Class Language on The JVM, JavaOne 2013 India Slides 2013-04-24: Claudia Fröhling and Marcus Lagergren JavaScript for the JVM - say hello to Nashorn!, JAX 2013 presentation video 2013-04-13: Attila Szegedi Project Nashorn in Java 8 - Javascript as a first class language on the JVM, Devoxx UK 2013 Slides http://www.meetup.com/Londonjavacommunity/events/109436382/ 2013-01-17: Abhay Bakshi Nashorn Voted In as a Successor to Rhino in the OpenJDK Project, InfoQ 2013-03-28: Jim Laskey Nashorn, JavaScript for the JVM (Commonwealth Complex), EclipseCon 2013 Slides (pptx) Video 2013-01-30: Yolande Poirier, Marcus Lagergren Nashorn, the JavaScript Implementation in Java 8 2013-01-16: Marcus Lagergren Implementing Dynamic Languages on the JVM 2012-12-21: Jim Laskey Open For Business 2012-11-14: Marcus Lagergren Nashorn: Optimizing JavaScript and Dynamic Language Execution on the JVM, Devoxx 2012 Slides 2012-10-01: Staffan Friberg and Marcus Lagergren Optimizing JavaScript and Dynamic Languages on the JVM, JavaOne 2012 2012-10-10: Jim Laskey Welcome To The Nashorn Blog 这帖里有很多介绍Nashorn的技术演讲的链接,主要是JavaOne 2012的session。值得一看。 2012-07-12: Dalibor Topic, Jim Laskey PodFodder: Jim Laskey on Nashorn JavaScript Engine 2011-07-19: Jim Laskey Nashorn: Adventures in JSR-292 or How To Be A Duck Without Really Trying, JVM Language Summit 2011 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RednaxelaFX
2013-04-21
lv5
代码: https://github.com/Constellation/iv 代码版本控制工具: Git 主要人物: 鈴木勇介 (@Constellation) -------------------------------------------------------------------------- 我的评论: 立志成为“最符合ECMAScript标准的JavaScript引擎实现”。其早期版本几乎是直接把规范里的条款翻译为可执行的代码,不管运行效率如何。后来渐渐加入优化提升性能。 它的研发历程是本活生生的教科书,从非常简单的AST解释器一直进化到带有一定优化的JIT编译器,对test262的兼容性也一直维持在很高的水平,值得对自己实现JavaScript引擎感兴趣的同学阅读学习。 在Mac OS X上构建lv5非常方便。基本上有正常的C++构造环境、Python、SCons和Boehm GC就好了。在代码树的根目录执行scons,构建好之后在obj/lv5就能找到名为lv5的可执行文件,也就是lv5的shell。 Boehm GC用MacPorts装的话名字是boehmgc。 这个JavaScript引擎里到处都是炮姐里的角色名。看不懂neta的话可能会晕掉。 eleporter -> 白井黒子/空間移動(テレポート) -> 老的AST解释器 railgun -> 御坂美琴/超電磁砲(レールガン) -> Stack VM -> Register VM aero (Aero Hand Project) -> 婚后光子/空力使い(エアロハンド) -> 正则表达式引擎 breaker (Imagine Breaker Project) -> 上条当麻/幻想殺し(イマジンブレイカー) -> Context-threading JIT编译器 radio (Radio Noise Project) -> 妹達(シスターズ)/欠陥電気(レディオノイズ) -> 准确式GC phonic -> ? -> ruby binding for iv AST API accelerator -> 一方通行(アクセラレータ) -> ? melt (Meltdowner) -> 麦野沈利/原子崩し(メルトダウナー) -> ECMAScript扩展 Lv6 Shift Project -> 絶対能力者進化(レベル6シフト) -> 性能提升的大项目 Level Upper Project -> 幻想御手(レベルアッパー) -> ES6 version 动态编译器用了Xbyak库。作者把这个叫做online assembler,也对。 偷懒不想自己写GC的话就可以像lv5一样用Boehm GC。不过许多开始用Boehm GC的项目最终都转为自己写了——例如说Mono。 使用Boehm GC使得lv5的设计受到了限制,例如说它在选择tag数据的实现时就只能选择tagged value而不能用tagged pointer,否则如果指针被tag了的话Boehm GC就认不出那是有用的指针了。 另外他还有一个叫做Shibuya(涩谷)的ES.next实现,用ES5.1来实现:https://github.com/Constellation/shibuya 所以这也是个元循环虚拟机,与Narcissus的方案有相似之处。 -------------------------------------------------------------------------- 2012-12-22: 鈴木勇介 Polymorphic Inline Cache implementation of iv / lv5 http://qiita.com/advent-calendar/2012/vm 2012-08-04: 鈴木勇介 lv5: The most precise ECMAScript engine 2012-01-28: 鈴木勇介 Announcing Lv5 new RegisterVM lv5 version 0.0.2: RegisterVM 2011-12-18: 鈴木勇介 lv5.current 2011/12/18 2011-10-19: 鈴木勇介 iv / lv5, ECMA262 5.1th full support 2011-09-26: 鈴木勇介 固定長配列 所以ES5.1里只要把数组的length设成{ writable: false }就变成定长数组了orz 2011-07-27: 鈴木勇介 iv / lv5 VM engine |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RednaxelaFX
2013-04-21
V8
官方网站: http://code.google.com/p/v8 官方博客: http://blog.chromium.org/search/label/v8 (Chromium的官方博客包含V8的内容) 邮件列表: http://groups.google.com/group/v8-users 文档: https://developers.google.com/v8/intro 代码: https://code.google.com/p/v8/wiki/Source?tm=4 兼容标准: ECMAScript 5 实现语言: C++ 开源许可证: New BSD License 代码版本控制工具: Subversion/Git Shell: d8 相关工具: C1Visualizer: https://java.net/projects/c1visualizer/ IRHydra: https://code.google.com/p/irhydra/ 主要人物: Lars Bak: 参与过Self、Strongtalk、HotSpot、CLDC HotSpot Implementation、OOVM、V8、Dart的研发 Kasper Lund: 参与过CLDC HotSpot Implementation、OOVM、V8、Dart的研发 Søren Gjesse Daniel Clifford Vyacheslav Egorov Erik Corry -------------------------------------------------------------------------- 我的评论: 最初的V8就是现代化版的Self VM,套上了JavaScript语言的皮。 V8的tagged pointer形式也与Self/Strongtalk采用了同样的取舍:小整数(Smi)的tag为0,方便小整数的直接加减/位运算;而对象指针按4字节对齐后带有非0的tag:0x01。这与许多其它采用tagged value的VM正好相反,其它VM让对象对齐分配后指针不带特殊tag,这样便于对象指针直接使用;而V8则更注重小整数的运算性能,稍微牺牲指针的性能。 V8的选择的合理之处在于:像x86这样有复杂寻址模式的指令集里,指针加1可以用base+offset的形式来直接嵌在地址里,这样的话指针加1并不需要为地址运算而付出额外指令的代价。而由于小整数tag为0,小整数的加减等运算不需要位移也不需要mask就可以直接做,整体上看开销比较小。也正是这个原因,Self一直下来的血统一直使用这种tag方式。 不过这种编码方式也有弊端,例如说如果想用ARM/Thumb-16来实现这种tagging scheme,就无法把指针加1直接放进地址运算里,因为它的寻址无法只加1。 参见Self的tag: https://github.com/russellallen/self/blob/master/vm/src/any/objects/tag.hh Strongtalk的tag: http://code.google.com/p/strongtalk/wiki/VMTypesForSmalltalkObjects Heap里有个Object* roots_[kRootListLength]存着所有从VM里能直接访问到的非Handle的root。这跟HotSpot VM的Universe里的一大堆成员变量当作root的意义一样,但处理起来更方便一些:GC的扫描代码不需要一个个root按名字去遍历,只要遍历这个roots_数组即可。 PreParser用于加速后续parse过程。 实际上可以看成V8的基础parsing就用了2-pass方式,先收集一些上下文信息但并不生成AST,然后再做真的parse的时候靠这些上下文信息来减少麻烦,增加“预测”的准确性。 // Preparsing checks a JavaScript program and emits preparse-data that helps // a later parsing to be faster. // See preparse-data-format.h for the data format. // The PreParser checks that the syntax follows the grammar for JavaScript, // and collects some information about the program along the way. // The grammar check is only performed in order to understand the program // sufficiently to deduce some information about it, that can be used // to speed up later parsing. Finding errors is not the goal of pre-parsing, // rather it is to speed up properly written and correct programs. // That means that contextual checks (like a label being declared where // it is used) are generally omitted. http://ariya.ofilabs.com/2012/07/lazy-parsing-in-javascript-engines.html 类似的技巧在Dart中也有应用: https://www.dartlang.org/slides/2012/10/gotoaarhus/translating-dart-to-efficient-javascript-kasper-lund.pdf 为什么V8不用字节码,直接把JavaScript编译到机器码呢? Florian Loitsch和Bob Nystrom所写的Why Not a Bytecode VM?虽然主要说的是Dart VM的设计考量,但对V8也适用。 concurrent recompilation(之前叫parallel recompilation) 演示V8的常量折叠 function foo() { return 1 + 2 } --- Raw source --- () { return 1 + 2 } --- Optimized code --- kind = OPTIMIZED_FUNCTION name = foo stack_slots = 0 Instructions (size = 54) 0x34af9a343880 0 55 push rbp 0x34af9a343881 1 4889e5 REX.W movq rbp,rsp 0x34af9a343884 4 56 push rsi 0x34af9a343885 5 57 push rdi ;;; <@0,#0> -------------------- B0 -------------------- ;;; <@4,#4> context 0x34af9a343886 6 488bc6 REX.W movq rax,rsi ;;; <@8,#7> -------------------- B1 -------------------- ;;; <@10,#9> stack-check 0x34af9a343889 9 493b6548 REX.W cmpq rsp,[r13+0x48] 0x34af9a34388d 13 7305 jnc 20 (0x34af9a343894) 0x34af9a34388f 15 e86c7ffcff call 0x34af9a30b800 ;; code: STUB, StackCheckStub, minor: 0 ;;; <@12,#14> constant-t 0x34af9a343894 20 4b8d0464 REX.W leaq rax,[r12+r12*2] ;;; <@14,#12> return 0x34af9a343898 24 488be5 REX.W movq rsp,rbp 0x34af9a34389b 27 5d pop rbp 0x34af9a34389c 28 c20800 ret 0x8 0x34af9a34389f 31 6690 nop 0x34af9a3438a1 33 0f1f00 nop ;;; Safepoint table. Deoptimization Input Data (deopt points = 1) index ast id argc pc 0 3 0 20 Safepoints (size = 18) 0x34af9a343894 20 11111111 (sp -> fp) 0 (测试在V8 3.18.6,x64上运行) r12在V8/x64上是Smi常量寄存器,初始化为Smi的单位元(数值为1),具体实现是Smi::FromInt(kSmiConstantRegisterValue)也就是说底层表现是0x2。要获取一个数值为3的Smi的代码是: leaq rax,[r12+r12*2] 意思是rax = r12 * 3。可见源码里的1+2被折叠为常量3了。 Deferred parsing 跟HotSpot Client Compiler非常相似的新编译器 编译器内部使用的类型系统:types.h Inobject slack tracking: objects.h 不知道Google Chrome for Android (Chrome Mobile)里的V8跟桌面的V8有多大差异呢? 另外一提的是iOS版Chrome里没有使用V8,而是用UIWebView里自带的没有JIT的JavaScriptCore。Apple自己的Safari则可以用带有JIT版的JavaScriptCore。 关于浮点数转换的Grisu3算法: やっぱりdoubleでは「76287755398823936」は表現できない Printing floating-point numbers quickly and accurately with integers, Florian Loitsch, 2010 -------------------------------------------------------------------------- https://codereview.chromium.org/25254002/ V8也要有flow-sensitive analysis了啊厉害⋯ http://cs.au.dk/~jmi/VM/GC.pdf https://docs.google.com/a/chromium.org/presentation/d/1OFG81taxgjOGU43sv9WHvPZkt5--KnM6gSijWN8NMcU/edit?disco=AAAAAECHbXY#slide=id.p V8 Binding Explained 这是Webkit时代的了。Blink时代的binding机制有改变。 https://code.google.com/p/chromium/issues/detail?id=112386 TurboFan - Land the Fan (disabled), Chromium Code Reviews Daniel Clifford, Hannes Payer, Michael Starzinger, Ben L. Titzer Allocation Folding Based on Dominance, Google V8 Team Crankshaft介绍文(日文) http://nothingcosmos.github.io/V8Crankshaft/src/blog.html 写到了Crankshaft与HotSpot C1的关系 。没错,就是同根生。 Create Wiki - V8 Cookbook 2015-04-12: Vyacheslav Egorov jsunderhood digest (in Russian) http://mrale.ph/talks/techtalksnsu2014/images/slides/slide-2-014.png 2014-10-09: Mounir Lamouri Chrome 39 Beta: JS Generators, Animation Playback Control, and the WebApp Manifest, The Chromium Blog 2014-09-13: Vyacheslav Egorov Vyacheslav Egorov: invokedynamic.js, JSConf.EU 2014-08-28: Andreas Rossberg Chrome 38 Beta: New primitives for the next-generation web, The Chromium Blog Map, Set, Iterator, Symbol 2014-05-30: Ben Titzer New Optimizations of Google Chrome's V8, InfoQ, mloc.js 2014 2014-05-22: Shane Stephens, Doug Stockwell Chrome 36 Beta: element.animate(), HTML Imports, and Object.observe(), The Chromium Blog 引用 // Let's say we have a model with data var model = {}; // Which we then observe Object.observe(model, function(changes) { // This asynchronous callback runs and aggregates changes changes.forEach(function(change) { // Letting us know what changed console.log(change.type, change.name, change.oldValue); }); }); 2014-04-10: Rick Byers Chrome 35 Beta: More developer control over touch input, new JavaScript features, and unprefixed Shadow DOM, The Chromium Blog 2014-02-13, Yang Guo Compiling in the background for a smoother user experience, TheChromium Blog 2013-09-23: Jay Conrod A tour of V8: Garbage Collection 2013-08: Marja Hölttä (Google) Crankshafting from the ground up 2013-08-14: Vyacheslav Egorov Hidden classes vs jsPerf 最重要的takeaway是这段: Vyacheslav Egorov 写道 Important thing to understand from this is that the code below will produce objects with different hidden classes because their constructors are different closures.
function make() { function maker() { } return new maker(); } var a = make(), b = make(); // a and b have different hidden classes because a new maker is created // every time you execute make. 2013-06-06: Working with arrays in V8 (performance issue), StackOverflow 引用 @Esailija Actually what you write is not entirely correct. ArrayPush built-in tries to keep elements in fast mode if they were in fast mode. See the logic in https://code.google.com/p/v8/source/browse/trunk/src/builtins.cc#547 – Vyacheslav Egorov
@yttrium the difference happens due to how heuristics for going back into fast mode from dictionary mode work. if your array is in dictionary mode then every time when it needs to grow V8 checks whether it is dense enough and whether it can win space by using a continuous (C-like) array instead of dictionary. With 180000 as starting point heuristics hit fast and with 181000 heuristic hits very late. Hence the difference. Heuristic is here: https://code.google.com/p/v8/source/browse/trunk/src/objects.cc?r=14954#12483 – Vyacheslav Egorov 2013-05-16: Lars Bak, Kasper Lund Web Languages and VMs: Fast Code is Always in Fashion, Google I/O 2013 Video Slides 2013-05-16: John McCutchan Accelerating Oz with V8: Follow the Yellow Brick Road to JavaScript Performance, Google I/O 2013 Slides 2013-05-08: Andy Wingo generators in v8 2013-04-29: Vyacheslav Egorov Performance tuning as the art of weather forecast 2013-04-18: Andy Wingo inside full-codegen, v8's baseline compiler 2013-04-11: Ariya Hidayat JavaScript: Need for Speed, SF Web Performance Group 2013-02-17: Vyacheslav Egorov Release the IRHydra! 2012-11-05: Addy Osmani Writing Fast, Memory-Efficient JavaScript 2012-10-16: Charles Torre, Lars Bak and Steve Lucco Lars Bak and Steve Lucco: Chakra, V8, JavaScript, Open Source, Channel 9 2012-10-11: Chris Wilson, Daniel Clifford Performance Tips for JavaScript in V8 2012-09-23: Vyacheslav Egorov Grokking V8 closures for fun (and profit?) <- 关注一下https://code.google.com/p/v8/issues/detail?id=2206,它在V8里还没实现,现在的owner是Ben Titzer 2012-07-03: Ariya Hidayat Lazy Parsing in JavaScript Engines 2012-06-27: Daniel Clifford Breaking the JavaScript Speed Limit with V8, Google I/O 2012 土豆源 Slides 2012-06-03: Vyacheslav Egorov Explaining JavaScript VMs in JavaScript - Inline Caches 2012-05-24: Vyacheslav Egorov V8 Inside Out, Web Rebels 2012 2012-05-02: Jakob Kummerow Chromium Blog: Better code optimization decisions for V8 2012-04-19: Florian Schneider Compiling Dart to Efficient Machine Code 这篇虽然主题是如何将Dart语言编译为高效的机器码,但里面也穿插着一些有用的V8相关的介绍。 2012-04-02: Vyacheslav Egorov Can V8 do that?!, JSConf US 2012 2012-03-15: Florian Loitsch Optimizing for V8 series 作者通过实验来分析V8新的(Crankshaft里的)优化编译器的实现。 2012-02-28: In V8: pointer tagging 2012-02-02: Nikita Popov Pointer magic for efficient dynamic value representations 2011-12-18: Vyacheslav Egorov I-want-to-optimize-my-JS-application-on-V8 checklist 2011-11-21: Vyacheslav Egorov and Erik Corry A game changer for interactive performance. 介绍V8的新GC:对年老代的增量式mark-and-sweep收集。 2011-10-11: Kasper Lund Crankshaft: Turbocharging the next generation of web applications., GOTO Conference 2011 Aarhus V8的核心开发Kasper Lund介绍新的Crankshaft编译架构。 此时的Crankshaft还在使用每毫秒取一次sample的方式来profile程序获取热点。后来的Crankshaft已改为较传统的基于计数器的方式。 2011-09-05: Andy Wingo from ssa to native code: v8's lithium language 2011-08-02: Andy Wingo a closer look at crankshaft, v8's optimizing compiler 2011-07-24: Jay Conrod Polymorphic Inline Caches explained 介绍V8的PIC的好文 2011-07-05: Andy Wingo v8: a tale of two compilers 2011-06-20: Andy Wingo on-stack replacement in v8 2011-06-11: Vyacheslav Egorov Understanding V8 2011-06-10: Andy Wingo V8 is faster than GCC 表喷…作者知道他说的是什么意思 2011-06-08: Andy Wingo what does v8 do with that loop? 提到了V8 Crankshaft的sampling-based profiler触发Crankshaft编译的设计 2011-05-18: Andy Wingo value representation in javascript implementations 2011-05-03: 莫枢 关于一些JavaScript引擎最近的动态, HLLVM群组 https://codereview.chromium.org/7189066 simple non-incremental compaction https://groups.google.com/forum/#!msg/v8-dev/9Ke8H6Kv5cM/FRnlw91N9m8J Prototype of mark-and-compact support for Harmony weak maps. http://www.mail-archive.com/v8-dev@googlegroups.com/msg27971.html 从老的card marking改为store buffer的讨论帖 2010-12-08: David Mandelin Crankshaft 2010-12-08: Kevin Millikin and Florian Schneider Chromium Blog: A New Crankshaft for V8 2010-09-29: Hannes Wallnöfer Update on my Node.js Memory and GC Benchmark 2010-02-19: 莫枢 Cpython能否用V8的方式优化性能, HLLVM群组 可以关注这帖里我的几个回复。 http://comments.gmane.org/gmane.comp.lang.javascript.v8.general/1897 关于external string。外部字符串如果是ASCII或者UTF-16编码的话可以直接暴露给V8当作一个JavaScript String。对UTF-8编码或者其它编码的则不行。进一步参考讨论帖:https://code.google.com/p/v8/issues/detail?id=27 2009-08-21: 莫枢 [草稿帖][2009-08-21][JavaScript][V8][Nitro] 响应号召,放一个V8/Nitro相关的草稿出来, HLLVM群组 2009-05-27: Mads Ager, Lars Bak, Anders Sandholm V8: Building a High Performance JavaScript Engine, Google I/O 2009 优酷源 Slides 2009-04-29: Erik Meijer, Lars Bak Inside V8: A JavaScript Virtual Machine, Channel 9 2009-02-04: Erik Corry, Christian Plesner Hansen and Lasse Reichstein Holst Nielsen Irregexp, Google Chrome's New Regexp Implementation 2009-01-13: Hajime Morita Why Is the New Google V8 Engine So Fast? 一个5 part的系列文。相当详细的介绍了初期V8的各种特点。不愧是日本同行,分析加上成文的速度和深度都相当赞。我当时也靠读这篇才开始真正深钻进V8的实现里。 2008-10-08: 莫枢 在WinXP上构建V8 这篇提了下在Windows XP上用VC2008来构建V8的步骤,以及V8与 要注意现在(2013-04-20)V8的构建方式以及跟2008年的时候很不一样了,用了新的工具。 2008-09-07: Hajime Morrita V8 祭り 2008-09-03: 莫枢 简记V8与SquirrleFish/Tamarin的对比点 2008-09-03: Brendan Eich TraceMonkey Update 2008-09-02: Lars Bak Google Chrome's Need for Speed, Chromium Blog |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RednaxelaFX
2013-04-21
SpiderMonkey系
(包括SpiderMonkey/Tamarin/Tamarin Tracing (TT) /TraceMonkey/JaegerMonkey/IonMonkey/Baseline) 官方网站: https://developer.mozilla.org/en-US/docs/SpiderMonkey 官方博客: https://blog.mozilla.org/javascript/ https://air.mozilla.org/?tag=javascript 代码: http://hg.mozilla.org/mozilla-central/file/tip/js/src (repo地址是 http://hg.mozilla.org/mozilla-central/,包括完整的Gecko、Firefox源码) 代码版本控制工具: Mercurial / Git 开源许可证: MPL2 内部实现的描述: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals 字节码格式文档: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Bytecodes IonMonkey文档: https://wiki.mozilla.org/Platform/Features/IonMonkey 老版本(还在用C而未迁移到C++时的)SpiderMonkey的文档: http://www-archive.mozilla.org/js/spidermonkey/ 在V8出现前,SpiderMonkey是native application嵌入JavaScript的最流行选择。如果大家没留意过的话,UltraEdit就内嵌了SpiderMonkey来让用户使用JavaScript写宏与插件[/url];Adobe Acrobat也类似。 准确说Tamarin不是SpiderMonkey系的VM,而是Adobe捐赠给Mozilla的开源版AVM2 (ActionScript Virtual Machine 2)。但它与同时期的TraceMonkey有一定关系,而且既然是属于Mozilla的VM了也就一并放在这边吧。 Mozilla对这个VM并不满意,认为Tamarin的解释器比SpiderMonkey的慢,而JIT也没有特别值得用的部分,最后只把Tamarin的JIT编译器里的汇编器nanojit拿出来塞进了TraceMonkey里。 然后TraceMonkey也被抛弃,SpiderMonkey里现在应该一点Tamarin的影子都没有了。 到底SpiderMonkey指的是啥,后来Mozilla推出的各*Monkey跟SpiderMonkey有啥关系,Chris Leary写的这篇博客说得很清楚:Mapping the monkeysphere。 Chris Leary 写道
JaegerMonkey与Nitro的关系可以参加David Mandelin画的示意图: JaegerMonkey chunked compilation SpiderMonkey里隐藏类叫做Shape。 Property cache与PIC。 现在只有解释器还在用原本的简易property cache,新的IonMonkey转用更多依赖type inference和另外实现的PIC。 SpiderMonkey一个相对奇葩的地方是,它的Function.prototype.toString是通过反编译字节码得到,而不是把真实的源码记录着返回出来。 看2011年底的SpiderMonkey 1.8.5的行为: js> function foo () { /* ... */ return 42 } js> foo function foo() {return 42;} js> 可以看到foo被反编译出来得到的字符串里注释、空白之类的都跟真正的源码不一样。 在2012年中的761723之后,SpiderMonkey也改为跟其它大多数JavaScript引擎一样直接返回实际源码了。Brendan Eich有篇介绍ECMAScript Harmony的blog也提到了这个改动。 ECMAScript 6 support in Mozilla -------------------------------------------------------------------------- http://rfrn.org/~shu/ Shu-yu Guo https://bugzilla.mozilla.org/show_bug.cgi?id=634503 Investigate V8's GC 谁能说这不是一个可爱的bug… 2014-01-14: Luke Wagner asm.js AOT compilation and startup performance 2013-07-18: Steve Fink Clawing Our Way Back To Precision Mozilla JavaScript Blog 讲SpiderMonkey从保守式GC变回准确式GC 2013-06-24: Steve Fink Sfink/Draft - GC Pointer Handling, Mozilla Wiki 2013-04-05: Kannan Vijayan The Baseline Compiler Has Landed, Mozilla JavaScript Blog 中文翻译 by 编译路漫漫 2013-02-03: Jon Coppeard Spider Monkey Garbage Collection, Air Mozilla 2013-01-03: Jim Blandy Support for debugging SpiderMonkey with GDB now landed, Mozilla JavaScript Blog 2012-12-05: 编译路漫漫 如何得到SpiderMonkey引擎的字节码(bytecode) 2012-12-04: 编译路漫漫 SpiderMonkey内部的字符串表示 2012-11-16: 编译路漫漫 IonMonkey 中可能的研究点 2012-10-15: Kannan Vijayan The Ins and Outs of Invalidation, Mozilla JavaScript Blog Type inference of IonMonkey, invalidation vs. guarding, etc 2012-10-08: Luke Wagner Optimizing JavaScript variable access 2012-10-04: Mihai Bazon UglifyJS — why not switching to SpiderMonkey AST 这里所说的SpiderMonkey AST的文档请参考 https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API 2012-09-16: 编译路漫漫 IonMonkey分析:目录结构 2012-09-12: David Anderson IonMonkey in Firefox 18, Mozilla JavaScript Blog 中文翻译 by 编译路漫漫 2012-08-28: Bill McCloskey Incremental GC in Firefox 16!, Mozilla JavaScript Blog 2012-07-20: David Mandelin Incremental GC now in Firefox Aurora 2012-05-09: David Mandelin SpiderMonkey API Futures 2012-02-01: David Mandelin Mozilla JS Development Newsletter 1/25/2012-2/29/2012 2012-01-25: Jeff Walden SpiderMonkey no longer supports sharp variables 回复里Jeff还很批了一通E4X。这功能真悲催啊… 2012-01-24: Luke Wagner JSRuntime is now officially single-threaded 2012-01-24: David Mandelin Mozilla JS Development Newsletter 12/07-1/24 2012-01-06: Chris Leary String representation in SpiderMonkey 2011-11-01: Nicholas Nethercote SpiderMonkey is on a diet 2011-09-01: Jesse Ruderman Lessons from JS engine bugs 2011-08-26: Kailas Patil JaegerMonkey Architecture 2011-08-12: Luke Wagner Old Dijkstra Essays Considered 2011-07-15: Steve Webster Firefox doesn’t hoist function declarations in blocks 2011-06-16: David Mandelin Know Your Engines at O’Reilly Velocity 2011 2011-06-08: Chris Leary Mapping the monkeysphere 2011-06-06: Jeff Walden I feel the need…the need for JSON parsing correctness and speed! 2011-06-05: Gregor Wagnery, Andreas Gal, Christian Wimmer, Brendan Eich and Michael Franzy Compartmental Memory Management in a Modern Web Browser, ISMM'11 2011-05-18: Andy Wingo value representation in javascript implementations 2011-05-03: 莫枢 关于一些JavaScript引擎最近的动态, HLLVM群组 2011-04-22: David Mandelin Mozilla JavaScript 2011 2011-03-16: Jeff Walden JavaScript change for Firefox 5 (not 4): class, enum, export, extends, import, and super are once again reserved words per ECMAScript 5 2011-03-06: Jeff Walden JavaScript change in Firefox 5 (not 4), and in other browsers: regular expressions can’t be called like functions 2010-12-08: SpiderMonkey 1.8.5 for Windows, Kahu Security 方便懒得自己编译的人(逃 源码版本是2010-11-24从http://hg.mozilla.org/mozilla-central/下载的当时最新版。 2010-10-13: Andreas Gal Compartments 2010-09-27: Chris Leary PICing on JavaScript for fun and profit 2010-09-08: David Anderson Land Ho, Fast JavaScript! JaegerMonkey对外发布测试版本 2010-09-08: David Mandelin Jägermonkey: it’s in ur browser!!! 2010-08-25: Dave Herman An API for parsing JavaScript 2010-08-02: Rob Sayre Mozilla’s New JavaScript Value Representation 2010-07-19: David Mandelin JägerMonkey Update: Getting Faster 2010-07-13: David Anderson JägerMonkey has Crossed the Streams 2010-05-10: David Mandelin JägerMonkey: the “halfway” point 2010-05-07: Jeff Walden SpiderMonkey change du jour: the special __parent__ property has been removed 2010-04-16: Jeff Walden More SpiderMonkey changes: ancient, esoteric, very rarely used syntax for creating getters and setters is being removed 2010-04-06: Jeff Walden More changes coming to SpiderMonkey: the magical __count__ property is being removed 2010-03-15: David Mandelin JägerMonkey & Nitro Components 2010-02-26: David Anderson JaegerMonkey – Fast JavaScript, Always! 2010-02-26: David Mandelin Starting JägerMonkey 2010-01-15: Jeff Walden More ES5 backwards-incompatible changes: regular expressions now evaluate to a new object, not the same object, each time they’re encountered 2010-01-13: David Mandelin JavaScript speedups in Firefox 3.6, Mozilla Hacks 用一些能被优化的JavaScript的代码例子来讲解Firefox 3.6里GC和TraceMonkey所做的事情 2010-01-12: Jeff Walden More ES5 backwards-incompatible changes: the global properties undefined, NaN, and Infinity are now immutable 2009-12-21: Jeff Walden ECMA-262 ed. 5 backwards-incompatible change coming to SpiderMonkey and to Gecko-based browsers 2009-11-02: David Mandelin There’s more than one way to null a pointer 2009-09-15: David Anderson 64-bit TraceMonkey! 2009-09-01: David Anderson Trace Compilation and Recursion, Part 1 2009-07-17: David Mandelin an overview of TraceMonkey, Mozilla Hacks 2009-06-02: David Mandelin TraceMonkey@PLDI 2009-05-15: David Mandelin OSQ: Dynamic language optimization 提到了Bill McCloskey做的优化Python的项目。后来他也去了Mozilla。 2009-02-26: David Mandelin TraceVis: performance visualization for TraceMonkey 2009-02-25: David Anderson A Divine TraceMonkey Bug 2009-01-26: David Anderson More Type Instability and Specialization in JavaScript 2009-01-09: David Mandelin A History of Insanity in the Age of x86 2008-12-23: Jesse Ruderman Some differences between JavaScript engines 2008-12-23: Jesse Ruderman Fuzzing TraceMonkey 2008-10-27: David Anderson TraceMonkey and Type Instability in JavaScript 2008-09-03: 莫枢 简记V8与SquirrleFish/Tamarin的对比点 2008-09-03: Brendan Eich TraceMonkey Update 2008-08-27: David Mandelin Inline threading, TraceMonkey, etc. 2008-08-22: Andreas Gal Tracing the Web 2008-06-16: David Anderson Tamarin Tracing, Intro to Tracing JITs 2008-05-28: David Mandelin Tamarin Tracing Internals V: Running Compiled Traces 2008-05-28: David Mandelin Tamarin Tracing Internals IV: Trace Optimization 2008-05-23: David Mandelin Tamarin Tracing Internals III: LIR 2008-05-21: David Mandelin Tamarin Tracing Interals, Part II: Forth 2008-05-16: David Mandelin Tamarin Tracing Internals, Part I 2007-11-12: James Polanco Flash Internals: Just-in-time (JIT) compilation (part four) 这个系列是介绍Tamarin/AVM2的。这篇介绍了AVM2的JIT编译器。 -------------------------------------------------------------------------- 关于benchmark 2009-02-06: David Mandelin SunSpider Statistics, Part II 2009-02-06: David Mandelin SunSpider Statistics, Part I: Questions |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RednaxelaFX
2013-04-21
Chakra
(新版(>= 9.0)JScript的代号。为了与老旧的JScript区分开来,这帖里只叫它Chakra) 官方博客: http://blogs.msdn.com/b/ie/ (IE Blog里包含Chakra的内容) 兼容标准: ECMAScript 5.1 / ECMAScript 2015 2016年1月以MIT许可证开源:https://github.com/Microsoft/ChakraCore -------------------------------------------------------------------------- 我的评论: Chakra问世后的JScript已非当日吴下阿蒙。不要再拿“JScript跑得慢”来黑微软了! 即便Chakra的解释器也是字节码解释器,它的字节码设计与老版本JScript的已经相当不同,解释器自身的速度都已经有所提升。 Chakra里的隐藏类变迁机制叫做“type evolution”。每个产品都必须发明些新名词 IE9版Chakra里字段数量不超过16个的对象可以使用紧凑布局;IE10版Chakra将这限制放宽到30多个字段。 IE9 Chakra的对象布局是对象头与property数组分离的。IE10版则将构造器函数里赋值的属性直接跟对象头粘在一起分配。 Chakra里的value representation跟V8的比较类似,都是在最低的几位放tag;不过Chakra的是tagged-value,也就是在小整数的后面带上一个0x1的tag,而对象地址是8字节对齐的于是对象指针的最低3位为0。打tag的取舍正好与V8的tagged-pointer相反,而与更多其它用tagged-value的VM相似,例如说更传统的Smalltalk实现,包括现在还可以用到的Squeak,或者是像Ruby等受Smalltalk影响的VM。 注意:IE9在x64上的版本里的Chakra只有解释器,没实现JIT编译器;到IE10才开始在x64版上提供JIT编译器。 同样只有字节码解释器,IE9 64-bit的Chakra仍然可以比IE8 64-bit的JScript 5.8快近10倍:https://gist.github.com/rednaxelafx/5581610 可以想像为啥大家以前都要吐槽JScript慢了… 在.NET用Chakra的例子 Parser ParseNode FuncInfo ByteCodeGenerator Js::ByteCodeReader Js::ByteCodeWriter BackgroundCodeGenThread IR Js::OpCode IRBuilder BasicBlock Lowerer FlowGraph FlowEdge BackwardPass GlobOpt CopyProp IsTypeSpecialized LinearScan SCCLiveness NativeCodeGenerator Js::InlineCache DefferedTypeHandler<> Js::DynamicObject ChangeType Js::Int31 OverflowHelper -> box to a Js::JavascriptNumber Js::InterpreterStackFrame Js::StringBuilderString Js::SubString -------------------------------------------------------------------------- 2015-02-18: Gaurav Seth, Ed Maurer Bringing asm.js to the Chakra JavaScript engine in Windows 10, IE Blog 2014-12-15: Tom Care (@tcare_), Brian Terlson (@bterlson), Suwei Chen Classes in JavaScript: Exploring the Implementation in Chakra, IE Blog 2014-10-09: John-David Dalton, Gaurav Seth, Louis Lafreniere Announcing key advances to JavaScript performance in Windows 10 Technical Preview, IE Blog IE11: Windows 10 Preview: 2013-11-07: Rob Mauceri, Sandeep Singhal IE11 for Windows 7 Globally Available for Consumers and Businesses, IE Blog 引用 The updated Chakra JIT compiler in IE11 supports more optimizations including inline caches for polymorphic property access, in-lining of functions at polymorphic call sites, and compilation support for specific ECMAScript5 constructs like getters/setters, so even more code is JIT’ed and less time is spent in JavaScript computation. Garbage collection utilizes the background thread much more efficiently, substantially reducing the frequency and amount of time the UI thread is blocked doing garbage collection.
2013-07-25: Sandeep Singhal, Rob Mauceri IE11 Developer Preview for Windows 7: Enabling Next Generation Sites and Apps - Faster, IE Blog 看,IE11的Chakra也支持对象上的__proto__属性了。真好~ let、const、Set、Map、WeakMap等ES6标准特性也开始支持了。 2013-04-29: Larry Larsen, Andrew Richards, Amanda Silver Defrag Tools: #38 - JavaScript - Part 2, Channel 9 提到Windows Store app中的bytecode caching。相关的MSDN文档在:Reducing your app's loading time (Windows Store apps using JavaScript and HTML) 2013-04-22: Larry Larsen, Andrew Richards, Amanda Silver Defrag Tools: #37 - JavaScript - Part 1, Channel 9 2012-11-29: Writing efficient JavaScript (Windows Store apps using JavaScript and HTML), MSDN 2012-11-01: Scott Hanselman and Luke Hoban Modern JavaScript, BUILD 2012, Channel 9 2012-10-31: John-David Dalton and Amanda Silver Building High-Performing JavaScript for Modern Engines, BUILD 2012, Channel 9 2012-10-16: Charles Torre, Lars Bak and Steve Lucco Lars Bak and Steve Lucco: Chakra, V8, JavaScript, Open Source, Channel 9 2012-10-01: Steve Lucco The Inner Workings of the Chakra Javascript Engine, GOTO Conference 2012 Aarhus Slides Video 这组投影片值得一读。一开始就提到了几种JIT hardening的技巧在Chakra里都有实现。后面也形象的描述了IE9与IE10里的Chakra的GC、JIT等组件的实现方式和优化效果。 2012-07-03: Ariya Hidayat Lazy Parsing in JavaScript Engines 2012-06-14: Andrew Miadowicz Advances in JavaScript Performance in IE10 and Windows 8, IE Blog, MSDN 10比9的浮点数运算快了50%左右。咋弄的呢? 2012-03-12: Forbes Higman Enhanced Memory Protections in IE10 2012-01-31: What is the ProgId or CLSID for IE9's Javascript engine (code-named “Chakra”), StackOverflow 引用 The CLSID for the Chakra Javascript engine installed with IE9 is {16d51579-a30b-4c8b-a276-0ff4dc41e755}
只要指定合适的ID就可以在Windows Scripting Host里使用Chakra。 但要留意的是这样在WSH里使用的Chakra工作于“Quirks模式”(“杂项模式”)而非“IE9模式”。这帖也提到了这行为。 这个模式下的Chakra许多诡异的行为与老JScript一致而与规范或其它JavaScript引擎不同;另外Quirks模式的Chakra也不支持ECMAScript 5。大概有个什么变量能设一下指定Chakra以IE9模式工作,但我还不知道是啥变量。 2011-03-24: Gaurav Seth and Paul Chapman IE9’s Document Modes and JavaScript, IE Blog 2011-03-10: Steven J. Vaughan-Nichols Chrome 10 vs. Internet Explorer 9 Reconsidered 主要就是吐槽64-bit的IE9的Chakra没JIT编译器而已 2010-12-08: 黄继佳 IE9及高效互联网体验, Velocity China 2010 2010-11-19: Peter Bright Lies, damned lies, and benchmarks: is IE9 cheating at SunSpider? 2010-11-18: Dean Hachamovitch HTML5, and Real World Site Performance: Seventh IE9 Platform Preview Available for Developers Rob Sayre对此文的后续分析现在找不到了⋯名字是 Dead Code Elimination for Beginners 2010-11-17: Charles Torre, Dean Hachamovitch Dean Hachamovitch: IE9 - Questions and Answers, Channel 9 2010-10-29: Gaurav Seth Unlocking the JavaScript Opportunity with Internet Explorer 9 2010-06-26: Allen Wirfs-Brock Enhanced Scripting in IE9: ECMAScript 5 Support and More, IE Blog 2010-04-09: Charles Torre, Shanku Niyogi, Steve Lucco and GPM John Montgomery Inside IE 9’s High Performance JavaScript Engine, Channel 9 2010-03-18: Shanku Niyogi The New JavaScript Engine in Internet Explorer 9, IE Blog 2009-11-18: Charles Torre, John Montgomery, Steve Lucco and Shanku Niyogi IE 9: First look at the new JS Engine, Channel 9 http://channel9.msdn.com/Blogs/Charles/In-your-hands-IE-9-Performance-From-JS-to-COM-to-DOM-to-HTML5-on-GPU http://channel9.msdn.com/Shows/Going+Deep/Allen-Wirfs-Brock-and-Chris-Wilson-EcmaScript-5 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RednaxelaFX
2013-04-21
JavaScriptCore系
(包括JavaScriptCore/SquirrleFish/SquirrelFish Extreme (SFX)/Nitro/Nitro Extreme) 代码: http://trac.webkit.org/browser/trunk/Source/JavaScriptCore 文档: http://trac.webkit.org/wiki/JavaScriptCore Bugs: https://bugs.webkit.org/buglist.cgi?query_format=specific&order=relevance+desc&bug_status=__all__&product=WebKit&content=JavaScriptCore Stack Overflow tag: http://stackoverflow.com/questions/tagged/javascriptcore 参与人物 Filip Pizlo -------------------------------------------------------------------------- 我的评论: JavaScriptCore源自KJS,但持续得到苹果的大力投入,终而青出于蓝胜于蓝,已经完全超越了它的前身。 QtScript背后也使用JavaScriptCore。 2009-06-16: Kent Hansen Using JavaScriptCore as the QtScript Back-end Register-based bytecode SquirrelFish Bytecode Specification Direct-threaded interpreter 隐藏类叫做Structure,隐藏类迁移叫做structure transition,记录在StructureTransitionTable里。 虽然iOS的Safari和UIWebView控件里跑的都是JavaScriptCore,但只有Apple自己的程序才可以启用JIT编译,而第三方的则不行。所以Mobile Chrome for iOS就用不了JavaScriptCore的JIT。呃呵呵。 不过通过jailbreak可以让iOS上的第三方应用都用上这JIT:http://www.idownloadblog.com/2012/07/30/nitrous/ 新解释器LLint是用汇编写的。老解释器也还可以用,但是如果要用JIT的话在新版JavaScriptCore里只能跟LLint搭配而不能跟老解释器搭配使用了 JavaScriptCore的tiered compilation: Bug 67176: JavaScriptCore does not have tiered compilation 然后确定为三层: Bug 75812: JSC should be a triple-tier VM JavaScriptCore还准备要有一个“第四层JIT编译器”(FTL,Fourth-tier LLVM),拿LLVM作为JIT的后端,期望在DFG的基础上进一步提升优化效果。 http://trac.webkit.org/wiki/FTLJIT http://trac.webkit.org/attachment/wiki/JavaScriptCore/JavaScriptCore%20slides.pdf Optimizing JavaScript -------------------------------------------------------------------------- 2014-07-16: Andrew Trick FTL: WebKit’s LLVM based JIT, LLVM Project Blog 2014-05-13: Filip Pizlo Introducing the WebKit FTL JIT, Safari Blog 2013-05-08: Gabor Rapcsanyi Comparison of JavaScript execution modes of the WebKit browser engine 2013-02-07: Aaron M Brown JavaScriptCore Value Encoding 2012-12-06: 鈴木勇介 JSC Array optimization for adding new property 2012-11-07: Andy Wingo Andy Wingo: JavaScriptCore's DFG JIT, JSConf EU 2012, YouTube 2012-07-03: Ariya Hidayat Lazy Parsing in JavaScript Engines 2012-06-27: Andy Wingo inside javascriptcore's low-level interpreter 2012-03-01: Daniel Eran Dilger New low level JavaScript interpreter to boost WebKit performance more than 200%, Apple Insider 2011-10-28: Andy Wingo JavaScriptCore, the WebKit JS implementation 2011-05-18: Andy Wingo value representation in javascript implementations 2009-08-21: 莫枢 [草稿帖][2009-08-21][JavaScript][V8][Nitro] 响应号召,放一个V8/Nitro相关的草稿出来, HLLVM群组 2009-01-10: Mason Chang The Art of SquirrelFish's Bytecode Generation 2008-10-06: David Mandelin Squirrelfishing regexp-dna.js 2008-09-20: 莫枢 Webkit的SquirrelFish Extreme 2008-09-18: Maciej Stachowiak Introducing SquirrelFish Extreme, Surfin' Safari Blog 2008-09-03: 莫枢 简记V8与SquirrleFish/Tamarin的对比点 2008-06-03: David Mandelin SquirrelFish 2008-06-02: Geoffrey Garen Announcing SquirrelFish, Surfin' Safari Blog |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RednaxelaFX
2013-04-21
Carakan
-------------------------------------------------------------------------- 我的评论: “大篷车”JavaScript引擎…好含蓄的名字。 基本上是Jens Lindström单兵作战的产物。能短时间内写出那么多代码的都是神啊。 (顺带:才留意到Opera是挪威公司…) Opera今年决定放弃自行研发浏览器的渲染引擎和JavaScript引擎,转而投向基于Chromium来做定制开发。Carakan的生命也就基本到此为止,目前Opera只有非常少量的产品(例如Sphinx)还在使用Presto/Carakan,其它主线产品都改为使用Blink/V8的组合了。 可惜Opera没发发善心把Carakan开源出来。 前身有 Linear A Linear B Futhark Register-based bytecode 有polymorphic inline cache,每个cache最多记录10个隐藏类。 有独特的地方在于它有pseudothread,看起来跟green thread相似。 -------------------------------------------------------------------------- 2013-02-12: Bruce Lawson 300 million users and move to WebKit 2010-02-28: 莫枢 JägerMonkey与Carakan动态更新 2009-12-22: Jens Lindström Carakan Revisited 新链接 2009-02-04: Jens Lindström Carakan 新链接 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RednaxelaFX
2013-04-21
KJS
文档: http://api.kde.org/4.x-api/kdelibs-apidocs/tier1/kjs/src/kjs/html/index.html http://api.kde.org/4.0-api/kdelibs-apidocs/kjs/html/index.html 兼容标准: ECMAScript 3 开源许可证: LGPLv2 代码: https://projects.kde.org/projects/kde/kdelibs/repository/revisions/master/show/kjs 代码版本控制工具: Git Shell: kjscmd -------------------------------------------------------------------------- 我的评论: Apple把KHTML拿去演化出了WebKit,其中的KJS演化成了JavaScriptCore。但现在KJS已经远不如JavaScriptCore。可能是现在还能算得上主流的JavaScript引擎里唯一一个没有JIT编译器的。好吧KJS要说现在还是主流或许还是太勉强了。 现在要获取最新的KJS源码要通过Git把整个kdslibs给clone下来,要单独clone出KJS那个目录挺麻烦的。 JavaScript对象的实现类是JSObject。属性存在hashmap里,PropertyMap。 对一般JSObject,整数下标访问对象属性时整数先被转换为字符串然后转换为Identifier(一种驻留字符串)然后再拿到PropertyMap(概念上是一个Identifier -> PropertySlot的映射的hashmap,内部实际上是Identifier -> JSValue的映射)去访问。 拿到PropertySlot之后倒是有专门针对unsigned下标的访问特化,但跟Identifier版重载基本上一样。 class KJS_EXPORT PropertySlot { JSValue *getValue(ExecState *exec, JSObject *originalObject, unsigned propertyName) const { … } } 其实已经有足够基础设施来实现针对整数下标的属性访问和存储的优化。 对JSArray,整数下标的访问就有优化了。 ALWAYS_INLINE bool ArrayInstance::inlineGetOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot) 存储也有优化,同时针对密集数组与稀疏数组。紧密数组的内容存在ArrayStorage对象末位的vector里,稀疏数组内容存在一个HashMap<unsigned, ArrayEntity>里 PropertySlot是一个用来统一存储在不同地方的属性的flyweight object。 RefPtr<T>与STL的shared_ptr<T>类似。 Function.prototype.toString() -> FunctionImp::toSource() decompiles the AST to source form; lossy (comments lost); can be used as a JavaScript source formatter / pretty-printer. There's even an API exposed for that purpose: Interpreter::normalizeCode() Interpreter limits recursion count to 20 (weird?) AST is kept around. Compilation to bytecode is lazy, compile function body to bytecode upon first invocation of the function -------------------------------------------------------------------------- 2008-03-10: Maksim Orlovich Say hello to KJS/Frostbyte -40.9° and Icemaker 2008-02-09: 莫枢 KJS的一些简略笔记 2005-07-14: Martijn Klingens Apple reduced the diff between JavaScriptCore's and KHTML's kjs |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RednaxelaFX
2013-04-21
IronJS
官方网站: http://ironjs.wordpress.com/ 代码:https://github.com/fholm/IronJS 兼容标准: ECMAScript 3.0 实现语言: F# (parser)/C# (runtime) 主要人物: Fredrik Holmström -------------------------------------------------------------------------- 我的评论: IronJS原本完全使用F#实现,后来改为只用F#来实现parser,而用C#来实现runtime部分。这是个非常妙的搭配。F#(以及许多函数式语言)天生就非常适合用来写需要大量模式匹配的程序,写parser最适合不过。而runtime部分更多是与.NET的其它部分打交道,这里用C#就会更顺手些。 IronJS的parser整体采用top-down operator precedence(TDOP)方式,在JavaScript的引擎实现中比较少见。不过却正好与微软自家的Managed JScript相似。不知道作者在写IronJS时是否有受Managed JScript的思路影响呢? 如果采用TDOP不是Managed JScript的影响,那或许是受Douglas Crockford大神那篇TDOP教程的影响了。 最初的IronJS其实用的是基于ANTLR生成的parser。不过后来用F#新写的parser比老的ANTLR生成的parser快得多。 不过作者决定在下一版IronJS里改为完全使用C#,主要是出于性能方面的考虑。并不是F#本身不够快,而是F#的各种方便简洁的功能容易引人写出不那么快的代码,而要写比较高效的代码样子会跟C#看起来很像。于是还不如直接用C#好了。 IronJS的对象模型有采用hidden class,叫做Schema,记录着属性名到属性数组下标的映射关系。基本对象由CommonObject实现,里面装属性值的是一个Descriptor数组。有实现monomorphic inline cache。 IronJS使用了Nan-boxing,只不过比起那些用C/C++之类的native语言所实现的NaN-boxing tagged pointer而言,IronJS版的比较“肥”一些——例如说JavaScriptCore的一个tagged pointer在x86-64上就是64位,跟一个double一样大,指针类型的值跟值类型的值可以重叠在同一个位置上;而在IronJS的则要128位,其中值类型的值与tag在头64位,而指针类型在后64位。 虽然肥一些,作为Nan-boxing的思路和效果还是类似的。用了tagged pointer之后至少那些值类型的值的内存开销都变小了——不用tagged pointer的话自动装箱的double在32位CLR上也至少得要16字节,外加引用它的指针4字节也得要20字节了,而IronJS的BoxedValue则总共只要16字节而且不会有额外指针带来的间接层,在内存局部性上也比不用tagged pointer好。 -------------------------------------------------------------------------- 2012-07-11: Nikos Vaggalis IronJS - In Conversation with Fredrik Holmström 2012-04-19: Fredrik Holmström Why not F#? 2011-08-30: Niladri Biswas A basic tour of IronJS 2011-06-29: CoffeeDemo - A Simple Demo of IronJS, using CoffeeScript 2011-06-21: Scott Hanselman Hanselminutes Podcast 271 - Inside IronJS - A complete JavaScript/ECMAScript open source implementation on the .NET DLR 2011-06-02: Wynn Netherland Episode 0.6.2 – IronJS with Fredrik Holmström, The Changelog 2011-04-26: IronJS on Ubuntu/Mono 2011-04-25: Fredrik Holmström IronJS is now faster than IE8 2011-04-19: Fredrik Holmström IronJS 0.2 is out 2011-03-28: Rob Paveza A Recent Discovery: IronJS 2011-03-26: Fredrik Holmström JavaScript Quotations 2011-03-22: Fredrik Holmström Analyzer: Single-Pass vs. Multi-Pass 2011-03-19: Fredrik Holmström New lexer and parser in IronJS 2011-03-13: Embedding IronJS |
相关讨论
相关资源推荐
- 微软开源 JavaScript 引擎 ChakraCore-易语言
- 各类链接
- 《现代Javascript高级教程》JavaScript引擎的垃圾回收机制
- 深入了解JavaScript引擎精华,让你的代码执行更高效
- php js解析引擎,拿下JavaScript引擎的基本原理
- understand-js-runtimes:有关Java引擎的不同最新资源列表
- JS引擎(1):JS引擎擂台赛,JavaScript引擎的特征比较及术语科普
- V8 javascript 引擎
- JS引擎(0):JavaScript引擎群雄演义—起底JavaScript引擎
- JavaScript 引擎基本原理:Shapes 和 Inline Caches