首页
论坛
专栏
课程

分享:
# Chakra解析流程 最近,微软公布了一则关于Chakra引擎解析流程的视频。 首先,下图是Edge浏览器的结构概览,可以看到其中存在许多的组件如CSS解析引擎、HTML解析引擎、页面渲染引擎等等。正如之前浏览器攻击面部分所说,浏览器的结构相当复杂,Chakra作为javascript解析引擎只是其中一小部分。图中红圈部分表示Chakra。 ![捕获.PNG-879.7kB][1] 微软系列的浏览器经历了IE3~IE11以及Edge的时代,其Javascript引擎也逐步演化,在IE8以前Javascript引擎是jscript.dll,IE9到IE11时代是jscript9.dll,Edge时代是chakra.dll。其中chakracore.dll是开源版本,就是我们在github中可以看到的那个,chakracore与chakra的区别在于外部接口有一些不同。 ![捕获2.PNG-153.7kB][2] 下图是chakra的总体结构,可以看到分为前端(front end)和后端(Backend)两部分。前端包含解析器(Parser)和字节码生成器(Byte Code Generator)。后端包含全局优化器(Global Optimize)、Register Allocator、Lowerer和Encoder。 其他部分有Library,包含Javascript中各种语言特性的比如数组(Array)、字符串(String)、函数(Functicon)、类型数组(Typed Array)、正则表达式(Regex)等等。 Execution Machinery部分,包含字节码解释器(Interpreter)、内联缓存(Inline Cache)、类型系统(Types)等。 以及Memory Manager部分,包含内存管理和GC。 ![捕获3.PNG-1169.4kB][3] 以下是一个脚本解析执行的流程,我们编写了一个示例函数foo,这个函数做一个简单的加分操作。首先Chakra经由API调用解析脚本文件,首先脚本文件会被转换为UTF8格式。在Chakra中,首先由前端(Front End)中的Paser进行处理,Paser会生成抽象语法树AST。但是在Chakra中应用了延迟解析技术(deferred parsing),即并不直接生成AST而是先检查语法错误以提高效率。 ![捕获4.PNG-421.4kB][4] 之后经由前端的字节码生成器由AST生成bytecode,生成的bytecode交由后端的解释器负责解释执行。此时代码表示的形式由AST的树式变为bytecode的线式,提高了执行效率。在生成bytecode之后,就交由chakra后端的interpreter进行解析执行。 ![捕获5.PNG-342.1kB][5] 由于Javascript语法的松散性,所以在处理Javascript时存在许多不同的可能性,比如下图中的加法操作,操作数可能是数字和数字,数字和字符串,字符串和字符串甚至允许是对象和对象,这就要求在处理时要判断类型分别进行处理。 ![捕获6.PNG-61.7kB][6] 如下是一个示例函数sum,功能是一个很简单的求和操作。图示展示了这个函数的执行流程,第一步就想我们前面所说的sum函数会生成bytecode经由interpreter进行解释执行,右图给出了生成的bytecode示例。在interpreter执行bytecode时,会搜集类型信息生成profile data以处理不同类型的情况。 ![捕获7.PNG-300.5kB][7] 假如我们传入的numbers参数是一个长度极大的数组,因为循环次数很多那么就可能会触发属于后端的JIT,JIT是在一个独立的线程中执行的。在前面的章节中我们介绍过JIT,JIT的出现是为了在反复执行同一段代码时不必让interpreter反复执行同一段bytecode,因为这样的效率很低。JIT可以让我们对"热点"代码直接生成机器指令,在下一次执行时直接执行机器指令,无需使用interpreter解释执行。 ![WX20180518-172515@2x.png-725.7kB][8] 一旦JIT生成完成,程序就可以直接调用JIT生成的机器指令。右侧是JIT生成出来的指令。因为JIT是直接编译为机器指令的,所以需要预先假定操作目标的类型。可以看到JIT代码中会判断numbers数组的类型是否是IntArray,total变量是否是整数。如果不满足JIT的假设的话,此JIT代码就不能执行,否则就会发生类型混淆的错误。因此JIT代码中设计了bailout功能,一旦发现不满足假设就进行bailout,bailout会放弃执行JIT代码转回使用interpreter解释执行bytecode。 ![WX20180518-172920@2x.png-746kB][9] 如果Sum被调用次数过多的话,那么针对Sum函数的JIT也会进行。但是,因为此时还不确定Sum函数是否还会被大量调用,因此只会进行简单JIT(Simple JIT)。Simple JIT为了效率不会进行Global Optimaize,所以不能进行bailout,也不能进行类型预测的优化。我们可以看到在Simple JIT中针对每种类型都做了处理。 ![WX20180518-185034@2x.png-802kB][10] 一旦Sum函数在Simple JIT后还被不断的大量调用,就会进一步进行FULL JIT。FULL JIT生成的是完整优化后的代码,但是还是会具有基本的检查和bailout机制。bailout之后会重回使用interpreter进行解释执行。 ![WX20180518-192411@2x.png-704.8kB][11] 当FULL JIT的函数被多次以非预期的类型进行调用,就会发生ReJIT。ReJIT会舍弃原有的JIT代码并以新的类型对代码生成JIT。 ![WX20180519-012158@2x.png-644.1kB][12] ## Reference https://www.microsoft.com/en-us/research/video/chakra-script-optimized-code/ [1]: http://static.zybuluo.com/vbty/ivvmcfes2ckksriy9f10i48i/%E6%8D%95%E8%8E%B7.PNG [2]: http://static.zybuluo.com/vbty/w9cm102jbutdeqyx3mnezst1/%E6%8D%95%E8%8E%B72.PNG [3]: http://static.zybuluo.com/vbty/gbfqbrweecg82uk4xaa99bto/%E6%8D%95%E8%8E%B73.PNG [4]: http://static.zybuluo.com/vbty/klkhn0cn28ax59taj8v5ewpe/%E6%8D%95%E8%8E%B74.PNG [5]: http://static.zybuluo.com/vbty/fibnrg0j3og6kqlhia3nqa1f/%E6%8D%95%E8%8E%B75.PNG [6]: http://static.zybuluo.com/vbty/gt7i6s1vprrllj7clf7cjv6k/%E6%8D%95%E8%8E%B76.PNG [7]: http://static.zybuluo.com/vbty/u9judjd042cn5noun5vjrnah/%E6%8D%95%E8%8E%B77.PNG [8]: http://static.zybuluo.com/vbty/dy6a6q4bbmuvo11d1bjrrdot/WX20180518-172515@2x.png [9]: http://static.zybuluo.com/vbty/01jios7zae78pbhryoqralay/WX20180518-172920@2x.png [10]: http://static.zybuluo.com/vbty/bswyzex96swe6q9pdr2cqx0w/WX20180518-185034@2x.png [11]: http://static.zybuluo.com/vbty/t7n96rr2ah23ozhp0cwlp554/WX20180518-192411@2x.png [12]: http://static.zybuluo.com/vbty/ltg3lqh6h61u7uwz31w8bihc/WX20180519-012158@2x.png

上一篇 :
下一篇 :
讨论 (0)
沪ICP备16048531号-1
沪公网安备 31011502006611号