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

本文涉及的产品
云解析DNS,个人版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: 类型推导是DFG JIT最重要的一个基础,WebKit官网对此做了一点解释,翻译如下做为学习参考。 Type inference通过profiling values来做到的,先是预测对哪些类型操作进行分析,再添加类型检查,最后基于类型检查的结果建立类型统计数据。

类型推导是DFG JIT最重要的一个基础,WebKit官网对此做了一点解释,翻译如下做为学习参考。


Type inference通过profiling values来做到的,先是预测对哪些类型操作进行分析,再添加类型检查,最后基于类型检查的结果建立类型统计数据。


用下面的例子来说明这个过程:

o.x * o.x + o.y * o.y


其中o是一个对象,x和y是它的属性,它们不是访问器(accessor),只是一般的属性。我们也可以说这两个属性值会返回double类型数值,但也有时会返回整型数据。JavaScriptCore通过用int32来表现整型数据,而不是用double类型。

  1. 对于表达式o.x,先要检查o有没有任何特殊的访问属性的处理。比如是一个DOM对象,那么它的属性访问操作就不是可见的。如果没有特殊的处理,JSC会在对象的属性中找出名字为'x'的属性。对象都一个将字串映射到值或访问器(accessor)的表,如果所找的字串指向一个访问器,那么这个访问器就会被调用,如果指一个值,那就直接返回。如'x'没能在对象o中找到,就到它的原型中依次找下去。类型推导对这部分操作没有什么作用。


  2. 二元的相乘操作,如'o.x * o.x',首先检查操作数(operands)的类型。如果操作数是个对象,就是调用它的valueOf方法。如果操作数是个字串,就要先转换为数值。当两个操作数已经被转为等价的数值(如果可以的话)后,JSC会再检查它们是不是全是整数,如果是则执行整型的相乘。如果溢出,就会用double类型的相乘再算一次。如果有一个操作数是double数值,它们都会转为double型,并执行double型的相乘操作。因此'o.x*o.x'所返回的结果,要么是整数,要么是浮点数(double)。


  3. 对于表达式'o.x*o.x + o.y*o.y'和上面类似,只是要多考虑一下操作数是字串的情况,中间的'+'可能会是字串合并的操作。不过在这里,我们可以很容易地确定,返回值仍然要么是整数,要么是浮点数(double)。


JSC的类型推导就是如果我可以猜到输入的数据类型,就可以给出数值操作后最可能返回的类型,以及其路径。这里使用了一系列归纳步骤, 如果我们可以预计它的输入就可以预计它的输出。对于一些非局部变量,比如从堆中取出的值(如o.x),和函数返回值,我们都称为堆值(heap values), 所有将heap values赋给局部变量的操作都视为堆操作(heap oerpations). 类型预测使用到了value profiling, LLInt和Baseline JIT都会记录在任何heap oerpation中记录下最常用的数值。每个堆操作都有一个对应的value profile bucket, 每一个value profile bucket都会存储一个最近值。


简单的看,JSC的类型推导就是把value profile中最常用的值的类型作为其以后要使用的类型。这样所有的变量都变成是可以进行类型预测的了。 事实上,在每个value profile中还有第二个内容,它是能包括已出现的一部分数据值的数据类型。这个类型使用了SpeculatedType(或SpecType)类型系统,实现在SpeculatedType.h中。每个value profile中这个类型会先设为SpecNone(就是没有数据)。当Baseline JIT执行次数超出阀值(JIT.cpp中的JIT::emitOptimizationCheck),它会生成一个新的类型,可以同时让最后一次的类型和最常用的数值符合这个类型。它或许会触发DFG,也可以让Baseline再多执行几次。当进入DFG JITF后,每个value profile通常会有一个这样可以包容多个不同值的类型。


SpecTypes之所以可行,源自于函数中的操作和变量都会使用标准的前置数据流( forward data flow )规范,实现了所谓的流程无关的不动点(fixpoint). 这是DFG编译的第一个阶段,由Baseline JIT基于执行次数决定是否激活(DFGPredictionPropagationPhase.cpp)。


在每个使用了预测数据类型的函数中,我们插入了基于预测的类型检查操作。如果类型检查失败,就会回退到Baseline JIT中。下面分解下'a+b'的附加操作是如何执行的, 假设a和b都被预测为SpecInt32类型:


check if a is Int32 -> 否则 OSR exit to Baseline JIT

check if b is Int32 -> 否则 OSR exit to Baseline JIT

result = a + b // integer addition

check if 溢出 -> 否则 OSR exit to Baseline JIT


操作执行完成后,我们可以知道:

  • 'a' 是整数.
  • 'b' 是整理.
  • 结果也是整数.

后面的操作就不用再检查'a' or 'b'的类型了这有一个消除类型检查的操作,是通过第二个数据流分析来完成的,被称为DFG CFA (DFGCFAPhase.cpp DFGAbstractState.cpp) . 它也实现了稀疏条件传播(sparse conditional constant propagation),让它可以有能力像确定类型一样确定某些值是不是常量。


对于表达式 'o.x * o.x + o.y * o.y',只需要在取o.x和o.y时进行类型检查。然后我们就知道它们的值是doubles, 就是只需触发double的相乘和相加。DFG绝大多数的类型检查通常是在加载堆数据时发生的。


深入阅读:

 Fast and Precise Hybrid Type Inference for JavaScript

 动态查看Type Inference的结果

 Type Inference in SpiderMonkey


原文地址: http://trac.webkit.org/wiki/JavaScriptCore

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

系列索引:

基础篇 (一)JSC与WebCore

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

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

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

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

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

高级篇(三) Register Allocation & Trampoline



目录
相关文章
|
24天前
|
存储 监控 NoSQL
MongoDB索引解析:工作原理、类型选择及优化策略
MongoDB索引解析:工作原理、类型选择及优化策略
|
1月前
|
缓存 网络协议 安全
常见的DNS记录类型总结
【6月更文挑战第17天】DNS记录类型:A(IPv4)、AAAA(IPv6)、CNAME(别名)、MX(邮件路由)、TXT(文本信息)和NS(DNS服务器指定)。常见DNS攻击有DDoS、DNS缓存中毒、域名劫持和查询嗅探。防护措施包括使用防火墙、安全软件,选择安全DNS服务,定期检查更新服务器,避免旧版软件,及时响应异常。
85 1
|
1月前
|
NoSQL 定位技术 MongoDB
深入探索 MongoDB:高级索引解析与优化策略
深入探索 MongoDB:高级索引解析与优化策略
|
2天前
|
存储 分布式计算 DataWorks
MaxCompute产品使用合集之如何在代码中解析File类型的文件内容
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
27 11
|
10天前
|
JavaScript 开发者 索引
TypeScript接口与类型别名:深入解析与应用实践
【7月更文挑战第10天】TypeScript的接口和类型别名是定义类型的关键工具。接口描述对象结构,用于类、对象和函数参数的形状约束,支持可选、只读属性及继承。类型别名则为复杂类型提供新名称,便于重用和简化。接口适合面向对象场景,类型别名在类型重用和复杂类型简化时更有优势。选择时要考虑场景和灵活性。
|
19天前
|
域名解析 存储 网络协议
了解域名解析:解析记录类型详解
了解域名解析:解析记录类型详解
51 2
|
2月前
|
域名解析 网络协议
【域名解析 DNS 专栏】DNS 记录类型全解析:A、MX、CNAME 与更多
【5月更文挑战第22天】DNS记录类型包括A、MX、CNAME等,用于确保域名与网络资源准确关联。A记录将域名指向IPv4地址,MX记录指定邮件服务器,CNAME则用于创建域名别名。其他记录如NS记录指定名称服务器,TXT记录用于验证和设置策略,SRV记录定义服务位置。正确配置DNS记录对网络运行至关重要,需注意信息准确性和及时更新。理解和运用这些记录能优化网络环境,支持各种在线服务。
【域名解析 DNS 专栏】DNS 记录类型全解析:A、MX、CNAME 与更多
|
2月前
|
监控 Linux 数据处理
|
24天前
|
数据采集 弹性计算 供应链
付费类型选择全解析:包年包月、按量付费和抢占式实例
阿里云服务器付费模式包括包年包月、按量付费和抢占式实例。包年包月适合长期稳定使用,价格优惠,支持备案;按量付费适合短期或波动需求,按小时计费;抢占式实例价格低廉但可能被系统自动释放,适合无状态应用。选择时考虑业务需求的稳定性和资源成本。更多详情见阿里云官方文档。
28 0
|
26天前
|
机器学习/深度学习 自然语言处理 Python
Softmax函数解析:从入门到高级
Softmax函数解析:从入门到高级

推荐镜像

更多