[翻译] V8引擎的解析
本文档介绍了 V8 引擎是如何解析 JavaScript 源代码的,以及我们将改进它的计划。
动机
我们有个解析器和一个更快的预解析器(~2x),但是预解析器对大多数现代 JavaScript 无用。此外假如还没有编译了外部函数,否则我们必须再解析一遍内部函数。 那现在的 V8 引擎什么时候会立即编译(eager compilation)呢?
顶层的括号函数(function...
在 ( 之后的不是函数声明的内部函数
当我们把一个内部函数当做非脚本级的一部分来解析的时候,是不能使用预解析器的。我们将不会编译一个内部函数,所以如果我们永远不先行编译函数,那么一般的 n 层嵌套函数会先被预解析,然后会有 n 次解析(以及一次编译)。或从另一方面来看待它,考虑了以下格式的顶级“模块”:
!function f() {
function A() {
function B() {...}
}
function C() {
function D() {...}
}
...
}(), function g() {....}()
压缩程序经常用 (function() {...})();(function(){...}))() 替换上面的代码。但是,你可以看到它没有被括号括起来,所以我们不会在顶层运行完整的解析器。这是为什么呢?因为我们不知道这些函数会被立即调用。因此会使用更快的预解析器。但是确实需要这些函数,这就打脸了,而 V8 就不得不去再解析。预解析阶段会将整个顶层函数看一遍,包括 A, B, C, D(假如原本的 (function f() {...})() 编译过那么就会跳过本阶段)。
因为顶层函数被调用了,所以引擎会去解析它。这次解析是完全的。为什么呢?因为需要做范围解析以便知道在哪里分配变量。而唯一的正确的方式是知道什么变量被引用了。而知道什么变量被引用的唯一方式是对内部函数也进行完全的解析。所以解析/编译顶层函数会迫使引擎对 A,B,C,D 这些函数也进行完全解析。
现在我们需要调用函数 A,因此需要去编译它。为了解析它,我们也需要知道在哪里分配变量。就像我说的:你需要知道从内部函数引用了上面。所以我们完全解析了 B 函数。
现在我们假定预解析需要1费,解析需要2费。编译它需要另外的2费,但是我们实际上编译的是压缩的版本,因此可以忽略。 假如现在运行 A 函数,那么将花费 3*(f + A + B) + 2*(A + B)。如果 A 将会调用 B,我们就花费另外的2费用于 B 函数。
一方面,要得到一个内部函数,你需要解析一大堆。 另一方面,顶层函数越多,解析它的成本就越高,因为你要算上解析所有嵌套函数的时间。
建议的解决方案
那么计划怎么解决呢?
预解析的同时也进行范围解析(scope resolution),这样未编译部分的花费会从2降低到1.x。
将函数的上下文内存分配信息序列化到持久存储中,以避免不必要的重解析成本。
立即编译可能会支持 ! 和 , 。
至于成本?所有懒解析函数在初始加载时的开销为1.x,如果实际使用则为3.x。.x是内部函数范围解析和序列化的额外未知成本。
立即编译的优点是,对于已知的立即执行的顶级函数,我们可以进一步将成本从3.x下降到2。它是从顶层向内的。如果我们决定不将预解析(eagerly parse)作为主编译工作的一部分,那么我们可以等到它被执行,这样我们至少可以确定只需要支付实际使用的功能的编译成本(2解析和2编译)。
立即编译的缺点是我们需要在解析和编译之间在内存中保持AST(Abstract syntax tree)。显著增加了使用内存的峰值。如果我们可以预解析那些在被立即解析的函数的内部函数,情况可能会看起来好多了。即使如此,在低内存设备上,我们应该禁用启发式的立即编译。
如果我们序列化这些数据,那么在热启动时就完完全全不需要去查看未使用的代码。热启动时,即使在顶层的时候也是与启发式的立即编译不相关,因为我们将只解析/编译我们需要的函数。 搭载了比使用的代码还要多10倍以上的页面将会立即热启动。(目前已经可以是这种情况,但它是一个有点hit-and-miss)。
相关链接:
[翻译] V8引擎的解析的更多相关文章
- 深入V8引擎-引擎内部类管理解析
v8的初始化三部曲,前面花了三篇解决了第一步,由于只是生成了一个对象,第二步就是将其嵌入v8中,先看一下三个步骤. // 生成默认Platform对象 std::unique_ptr<v8::P ...
- jQuery 2.0.3 源码分析Sizzle引擎 - 词法解析
声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 浏览器从下载文档到显示页面的过程是个复杂的过程,这里包含了重绘和重排.各家浏览器引擎的工作原理略有差别,但也有一定规则. 简 ...
- 分析Sizzle引擎 - 词法解析
分析Sizzle引擎 - 词法解析 声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 浏览器从下载文档到显示页面的过程是个复杂的过程,这里包含了重绘和重排.各家浏览器引擎的工 ...
- V8引擎嵌入指南
如果已读过V8编程入门那你已经熟悉了如句柄(handle).作用域(scope)和上下文(context)之类的关键概念,以及如何将V8引擎作为一个独立的虚拟机来使用.本文将进一步讨论这些概念,并介绍 ...
- JavaScript工作机制:V8 引擎内部机制及如何编写优化代码的5个诀窍
概述 JavaScript引擎是一个执行JavaScript代码的程序或解释器.JavaScript引擎可以被实现为标准解释器,或者实现为以某种形式将JavaScript编译为字节码的即时编译器. 下 ...
- JavaScript是如何工作的02:深入V8引擎&编写优化代码的5个技巧
概述 JavaScript引擎是执行 JavaScript 代码的程序或解释器.JavaScript引擎可以实现为标准解释器,或者以某种形式将JavaScript编译为字节码的即时编译器. 以为实现J ...
- 深入浏览器工作原理和JS引擎(V8引擎为例)
浏览器工作原理和JS引擎 1.浏览器工作原理 在浏览器中输入查找内容,浏览器是怎样将页面加载出来的?以及JavaScript代码在浏览器中是如何被执行的? 大概流程可观察以下图: 首先,用户在浏览器搜 ...
- 高性能JavaScript模板引擎原理解析
随着 web 发展,前端应用变得越来越复杂,基于后端的 javascript(Node.js) 也开始崭露头角,此时 javascript 被寄予了更大的期望,与此同时 javascript MVC ...
- 精读《V8 引擎 Lazy Parsing》
1. 引言 本周精读的文章是 V8 引擎 Lazy Parsing,看看 V8 引擎为了优化性能,做了怎样的尝试吧! 这篇文章介绍的优化技术叫 preparser,是通过跳过不必要函数编译的方式优化性 ...
随机推荐
- Maven环境配置
1.下载Maven: 下载地址:http://maven.apache.org/ 2..安装 Maven 如果需要使用到 Maven ,必须首先安装 Maven , Maven 的下载地址在 Apac ...
- "检索COM类工厂中 CLSID为 {00024500-0000-0000-C000-000000000046}的组件时失败,原因是出现以下错误: 80070005" 问题的解决
一.故障环境 Windows 2008 .net 3.0 二.故障描述 调用excel组件生成excel文档时页面报错.报错内容一大串,核心是"检索COM类工厂中 CLSID为 {000 ...
- C#开发微信门户及应用(4)--关注用户列表及详细信息管理
在上个月的对C#开发微信门户及应用做了介绍,写过了几篇的随笔进行分享,由于时间关系,间隔了一段时间没有继续写这个系列的博客了,并不是对这个方面停止了研究,而是继续深入探索这方面的技术,为了更好的应用起 ...
- 使用 Vue 2.0 实现服务端渲染的 HackerNews
Vue 2.0 支持服务端渲染 (SSR),并且是流式的,可以做组件级的缓存,这使得极速渲染成为可能.同时, 和 2.0 也都能够配合 SSR 提供同构路由和客户端 state hydration.v ...
- 深入理解javascript函数参数与闭包(一)
在看此文章,希望先阅读关于函数基础内容 函数定义与函数作用域 的章节,因为这篇文章或多或少会涉及函数基础的内容,而基础内容,我放在函数定义函数作用域 章节. 本文直接赘述函数参数与闭包,若涉及相关知识 ...
- 检索Google Maps地图位置(小训练)
名称:检索地图位置 内容:地图初期显示和检索显示 功能:根据条件检索地图的经度与纬度 1.在这之前我们需要创建一个表(Accoun__c),添加一个重要的字段地理位置情報,它会默认的给你两个字段经度和 ...
- iOS从零开始学习直播之音频4.歌词
上一篇讲了歌曲的切换,这一篇主要讲歌词部分的实现. 先看效果图.当歌手唱到这句歌词时候,我们要标记出来,这里显示字体为黄色. 1.获取歌词 一般歌词都是一个链接.类似于"http ...
- android Fragments介绍
Fragments是Android3.0引入的概念,译为片段.碎片,为了解决不同屏幕分辩率的动态和灵活UI设计. Fragment表现Activity中UI的一个行为或者一部分.可以将多个fragme ...
- UITableView cell复用出错问题 页面滑动卡顿问题 & 各杂七杂八问题
UITableView 的cell 复用机制节省了内存,但是有时对于多变的自定义cell,重用时会出现界面出错(例如复用出错,出现cell混乱重影).滑动卡顿等问题,这里只简单敲下几点复用出错时的解决 ...
- Android教程收集贴
Loader & REST Rest Loader Tutorial [github源码] [源码演示] [github作者主页] Twitter Timeline Sample for An ...