Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS 引擎基础:Shapes 和 ICs #1

Open
lihongxun945 opened this issue Jul 2, 2018 · 0 comments
Open

JS 引擎基础:Shapes 和 ICs #1

lihongxun945 opened this issue Jul 2, 2018 · 0 comments

Comments

@lihongxun945
Copy link
Owner

lihongxun945 commented Jul 2, 2018

本文是一篇读书笔记, 原文地址 JavaScript engine fundamentals: Shapes and Inline Caches

讲的主要是JS引擎中的两个重要部分: Shapes 和 ICs。这两部分是JS引擎对对象存储的实现方式,了解这部分可以帮我更好的理解JS的底层存储逻辑,也可以为以后优化代码提供思路。

JS 引擎的工作原理

  1. JS源码会首先被解析成一棵抽象语法树 AST
  2. 然后会由一个解释器将这棵语法树解析成字节码,同时,会保存一些metadata
  3. 一个优化引擎会读取 metadata和字节码,然后经过一些猜测来优化代码
  4. 如果猜错了,会进行 deoptimize

上图是V8的工作流程

Shapes

Shapes 是JS引擎内部存储对象的一种方式,所有的引擎都会有这种方式,不过他们各自的叫法不同。

如上图所示,如果我们定义了一个对象 object,那么他会生成一个对应的 Shape,这个Shape 其实就是用来存储对象的KV值的。Shape中会以偏移位置来记录每个值。

如果两个对象的key不同,那么他们他们对应的Shape就不同。不同的Shape会形成一个树状的结构 Shape Tree,如下图所示:

ICs

ICs 是 inline Caches的缩写,为什么要有Shape呢?为了更快的读写对象的属性。而ICs就是对象属性存储的地方。如下图所示:

当我们读取一个对象的属性的时候,会被解析成对ICs 的一个偏移地址的读取,因为没有查找过程,所以这个操作是非常高效的。

Arrays

我们了解了对象的存储。那么数组是怎么存储的呢?

其实数组的存储分两部分,首先,数组本身是一个对象,他有一个 length 属性,这个带有 length 属性的对象会被当做一个正常的对象存储起来。

然后,数组的内容会有一个单独的数据结构来存储:

这样当我们查找数组中的元素的时候,直接根据 index 计算出偏移值,在 Elements 中就可读写。

如果我们把数组中的 indices 的定义给修改了会怎么样呢? 如下图所示:

我们把 数组的 0 变成了一个key,那么 以前按照偏移存储的数据结构 Elements 将被变成 一个字典 Dictionary Elements ,这样数组就变成一个对象了,而读写性能也会大幅下降。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant