温故知新(八二)说下 V8 引擎解释执行 js 代码的大致流程

说下 V8 引擎解释执行 js 代码的大致流程

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

一、前置知识

1.1编程语言是如何运行的?

众所周知,我们通过编程语言完成的程序是通过处理器运行的。但是处理器不能直接理解我们通过高级语言(如 C++、Go、JavaScript等)编写的代码,只能理解机器码,所以在执行程序之前,需要经过一系列的步骤,将我们编写的代码翻译成机器语言。这个过程一般是由编译器(Compiler)或者解释器(来完成)。

编译器工作流程

源代码-->词法分析、语法分析-->AST-->语义分析-->中间代码-->代码优化-->机器码-->执行

解释器工作流程

源代码-->词法分析、语法分析-->AST-->语义分析-->字节码-->执行

那么既然编译器和解释器都可以完成代码的翻译工作,为何还同事存在呢?

这是因为编程语言有两个类别:静态类型和动态类型。静态类型的语言,比如 C++,GO 等,都需要提前编译(AOT)成机器码然后执行,这个过程主要使用编译器来完成;而动态语言,比如 JavaScript 、Python 等,只在运行时进行编译执行(JIT),这个过程通过解释器完成。
V8 并没有采用某种单一的技术,而是混合编译器和解释器的技术称为 JIT(Just In Time)技术。
这是一种权衡策略,因为这两种方法都各自有各自的优缺点,解释执行的启动速度快,但是执行的速度慢,而编译执行的启动速度慢,但是执行的速度快。

二、V8 执行 js 代码流程

V8 启动执行 JavaScript 之前,它还需要准备执行 JavaScript 时所需要的的一些基础环境,这些基础环境包括了“堆空间”“栈空间”“全局执行上下文”“全局作用域”“消息循环系统”“内置函数”等,这些内容都是执行 JavaScript 过程中所需要的使用到的,比如:

1.JavaScript 全局执行上下文就包括了执行过程中的全局信息,比如一些内置函数,全局变量等信息;

2.全局作用域包含了一些全局变量,在执行过程中的数据都需要放在内存中;

3.而 V8 是采用了经典的堆和栈的内存管理模式,所以 V8 还需要初始内存中的堆和栈结构;

4.另外,想要我们的 V8 系统活起来,还需要初始化消息循环系统,消息循环系统包括了消息驱动器和消息队列,它如同 V8 的心脏,不断接受消息并决策如何处理消息。

基础环境准备好之后,接下来就可以向 V8 提交要执行的 JavaScript 代码了

1.首先 V8 会接收到要执行的 JavaScript 源代码,不过这对 V8 来说只是一堆字符串,V8 并不能直接理解这段字符串的含义,他需要结构化这段字符串,生成了抽象语法树(AST),AST 是便于 V8 理解的结构。在生成 AST 的同时,V8 还会生成相关的作用域,作用域中存放相关便令;

2.有了 AST 和作用域之后,接下来就可以生成字节码了。字节码是介于 AST 和机器码的中间代码。但是与特定类型的机器代码无关,解释器可以直接解释执行字节码,或者通过编译器将其编译为 二进制的机器代码再执行。

3.解释器就登场了,它会按照顺序执行字节码,并输出执行结果。

4.有一个监控解释器执行状态的模块,在解释器执行字节码的过程中,如果发现了某一段代码会被重复多次执行,那么监控机器人就会将这段代码标记为热点代码。

5.当某段代码被标记为热点代码后, V8 就会将这段字节码丢给优化编译器,优化编译器会在后台将字节码编译为二进制代码,然后再对编译后的二进制代码执行优化操作,优化后的二进制机器代码的执行效率会得到大幅提升。如果下面再执行这段代码时,那么 V8 会优先选择优化之后的二进制代码,这样代码的执行速度就会大幅提升。

6.不过,和静态语言不同的是,JavaScript 是一种非常灵活的动态语言,对象的结构和属性是可以在运行时任意修改的,而经过优化编译器优化过的代码只能针对某种固定的结构,一旦在执行过程中,对象的结构被动态修改了,那么优化之后的代码势必会变成无效的代码;这时候优化编译器就需要执行去优化操作,经过去优化的代码,下次执行时就会回退到解释器解释执行。

总结:V8 执行一段 JS 代码的大致流程

1.初始化基础环境;

2.解释源码生成 AST 和作用域;

3.依据 AST 和作用域生成字节码;

4.解释执行字节码;

5.监听热点代码;

6.优化热点代码为二进制的机器代码;

7.去优化生成的二进制机器代码。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值