[WebKit] JavaScriptCore解析--高级篇(三) Register Allocation & Trampoline

Register Allocation

对于一个JIT而言,寄存器分配对系统的消耗通常是一个瓶径。之前有Graph Coloring Allocators, Chaitin style等分配方式,现在要介绍的是DFG JIT使用的Linear Scan算法。其基本工作方式是将占用寄存器的变量根据生命周期长短排列出来,在使用时查看可以回收哪些寄存器加以利用。

先看一些定义:

Live interval:是某个变量可以存活的一个指令序列,也可以称为了连续性。这个也依赖于算法使用的是深度优先还是广度优先。如下图,B1~B4代表的是四个Basic Blocks,w/r代表的是读和写.

Spilling:当变量存储到堆栈时就称为溢出。

Interference: 当两个活动区间共同存在于一个程序中时,称他们之间会有干扰。

  

算法的执行过程简述如下:

 1. 计算变量的live interval.

 2. 遍历:

   2.1 如果live interval已经过期就扔掉。

   2.2 分配新的live interval和寄存器。

   2.3 如果无法分配(所需的interval过长等),则spill出去,再选择较低成本的变量。

复杂度:O(V logR) (V是变量数,R寄存器数)

下面是示意图:

Trampoline

再介绍一下JIT中应用的Trampoline,蹦床或者弹簧技术,可以达到延迟编译的效果(其它领域的效果不同,比如编译器里的PLT)。一个“弹簧床”就是一个函数存根,它能在被调用的时候,触发JIT执行。一旦JIT编译这个函数成为机器码,那么“弹簧床”的指针就会被替换为真实函数的指针。

在JSC中,相关代码查看JITStubs.cpp中的实现,如ctiTrampoline等。下面是一个调用堆栈:

然后再跳转到具体的操作(可能会调回到LLInt对应的slow path进行处理):

转载请注明出处: http://blog.csdn.net/horkychen

参考:

 Massimilliano Poletto, Linear Scan Register Allocation

 CS 380C Lecture 14, Register Allocation

 Mono:Runtime:Documentation:Trampoline

 ctiTrampoline

 Trampoline on Wikipedia


系列索引:

基础篇 (一)JSC与WebCore

基础篇(二)解释器基础与JSC核心组件

基础篇(三)从脚本代码到JIT编译的代码实现

基础篇(四) 页面解析与JavaScript元素的执行

高级篇(一) SSA (static single assignment)

高级篇(二) 类型推导(Type Inference)

高级篇(三) Register Allocation & Trampoline

时间: 2024-11-03 20:45:45

[WebKit] JavaScriptCore解析--高级篇(三) Register Allocation & Trampoline的相关文章

[WebKit] JavaScriptCore解析--高级篇(二) 类型推导(Type Inference)

类型推导是DFG JIT最重要的一个基础,WebKit官网对此做了一点解释,翻译如下做为学习参考. Type inference通过profiling values来做到的,先是预测对哪些类型操作进行分析,再添加类型检查,最后基于类型检查的结果建立类型统计数据. 用下面的例子来说明这个过程: o.x * o.x + o.y * o.y 其中o是一个对象,x和y是它的属性,它们不是访问器(accessor),只是一般的属性.我们也可以说这两个属性值会返回double类型数值,但也有时会返回整型数据

[WebKit] JavaScriptCore解析--基础篇(三)从脚本代码到JIT编译的代码实现

前面说了一些解析.生成ByteCode直至JIT的基本概念,下面是对照JavaScriptCore源代码来大致了解它的实现. 从JS Script到Byte Code 首先说明Lexer, Parser和ByteCode的生成都是由ProgramExecutable初始化过程完成的.先在JSC的API evaluate()中会创建ProgramExecutable并指定脚本代码.然后传入Interpreter时,再透过CodeCache获取的UnlinkedProgramCodeBlock就是已

[WebKit] JavaScriptCore解析--高级篇(一) SSA (static single assignment)

在编译器优化领域,数据结构的选择会直接影响程序优化的有效性.SSA是一种编译器使用的中间语言(intermediate language), 作为编译优化的基础(也是DFG JIT的基础),它和Control Dependence Graph一起被用来表示程序的数据流和控制流. 大家都知道编译器是这样工作的:解析.优化,最后生成代码.中间会使用到一个中间语言的进行过度,好的中间语言一定要      1. 简单,这样优化工作就可以变得简单.      2. 很好的表达能力,这样就可以很容易从源代码

[WebKit] JavaScriptCore解析--基础篇(四) 页面解析与JavaScript元素的执行

很多地方都已经介绍了JavaScript在浏览器是如何被执行的,这里介绍一下WebKit是如何实现的.主要涉及JS的async,defer及普通脚本的解析与执行过程的代码实现. 1. 概要说明 先概要说明一下浏览器如何执行JavaScript的. 首先浏览器的页面解析器(Document Parser)遇到<script>就会发起下载(脚本内容在页面内的就不用下载了).然后针对不同情况执行的方式有所不同:   . async (在script标签中启用了async属性)       这是异步执

[WebKit] JavaScriptCore解析--基础篇 (一)JSC与WebCore

先看一下官方的基本介绍,短短几句就塞满了关键字. SquirrelFish,正式名称是JavaScriptCore,包括register-based(基于寄存器的虚拟机), direct-threaded, high-level bytecode engine(字节码引擎).它使用基于内置copy propagation(复制性传播算法)的一次性编译器(one-pass compiler),能够延迟从语法树(Syntax Tree)上生成字节码(Bytecodes). 由此可见JavaScrip

[WebKit] JavaScriptCore解析--基础篇(二)解释器基础与JSC核心组件

这一篇主要说明解释器的基本工作过程和JSC的核心组件的实现. 作为一个语言,就像人在的平时交流时一样,当接收到信息后,包含两个过程:先理解再行动.理解的过程就是语言解析的过程,行动就是根据解析的结果执行对应的行为.在计算机领域,理解就是编译或解释,这个已经被研究的很透彻了,并且有了工具来辅助.而执行则千变万化,也是性能优化的重心.下面就来看看JSC是如何来理解.执行JavaScript脚本的. 解释器工作过程 JavaScriptCore基本的工作过程如下: 对于一个解释器,首先必须要明确所支持

c#扩展方法奇思妙用高级篇三:Enumerable.Cast&amp;lt;T&amp;gt;应用

Enumerable.Cast<T>用于将IEnumerable转换为泛型版本IEnumerable<T>.转换后可尽情享用Enumerable的其它方法(如Where.Select),给我们的编码带来极大便利. 但MSDN中仅给出一个转换ArrayList的例子,很多人看了感觉现在都在用List<T>,还有谁会用ArrayList,Cast<T>没多少用处,除非处理一些之前遗留的一些代码. 其实Cast<T>并非如此简单,它可以用在很多地方.

一起谈.NET技术,DataTable 深入解析数据源绑定原理之高级篇

前言 在上篇写了篇 实战系列之天气预报实时采集 ,有个别同志认为没技术含量,也许正如所说. 只是人各有看法,当我写出一篇文章时,我只是希望:1:如果你还不懂,请看写法,了解想法.2:如果你已懂,略过写法,请看想法. 其实纵观我一直写来的200多篇文章,基本都可以看出那么点痕迹: 一:没有水文.二:没有华丽理论型的文章.三:实战型文章很多.四:文章尽量面向新手的表述,尽量了. 一.Winform下的DataGridView不支持使用DataReader绑定 1:问题产生 在 CYQ.Data 框架

ASP漏洞全接触-高级篇

高级 看完入门篇和进阶篇后,稍加练习,破解一般的网站是没问题了.但如果碰到表名列名猜不到,或程序作者过滤了一些特殊字符,怎么提高注入的成功率?怎么样提高猜解效率?请大家接着往下看高级篇. 第一节.利用系统表注入SQLServer数据库 SQLServer是一个功能强大的数据库系统,与操作系统也有紧密的联系,这给开发者带来了很大的方便,但另一方面,也为注入者提供了一个跳板,我们先来看看几个具体的例子: ①http://Site/url.asp?id=1;exec master..xp_cmdshe