自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

瀏覽器的引擎編譯、執(zhí)行原理知多少?

系統(tǒng) 瀏覽器
本文將分析瀏覽器引起對JS代碼的編譯情況,并結(jié)合實際開發(fā)經(jīng)驗,重新理解底層的編譯解析機制,將有助于理解前端開發(fā)在跨端中的應(yīng)用以及一套代碼生成多端的底層邏輯。

[[439465]]

本文轉(zhuǎn)載自微信公眾號「前端萬有引力」,作者一川 。轉(zhuǎn)載本文請聯(lián)系前端萬有引力公眾號。

1寫在前面

瀏覽器引擎是如何編譯、執(zhí)行JS代碼的呢?

本文將分析瀏覽器引起對JS代碼的編譯情況,并結(jié)合實際開發(fā)經(jīng)驗,重新理解底層的編譯解析機制,將有助于理解前端開發(fā)在跨端中的應(yīng)用以及一套代碼生成多端的底層邏輯。那么:

  • Javascript代碼被執(zhí)行分為幾個階段呢?
  • AST到底是做什么用的?

2V8引擎

我們知道程序語言分為編譯型語言和解釋型語言,他們各自的特點是:

  • 編譯型語言:在代碼執(zhí)行前編譯器直接將對應(yīng)的代碼轉(zhuǎn)換為機器碼。如C++
  • 解釋型語言:先將代碼轉(zhuǎn)換為編譯型代碼,再轉(zhuǎn)為機器碼,其是在運行時轉(zhuǎn)換的。如:Python、Javascript

為了提高運行效率,很多瀏覽器廠商在不斷努力,在現(xiàn)代瀏覽器中Chrome的v8引擎是最出類拔萃的,引入了Java虛擬機和C++編譯器的眾多技術(shù)。也正因此,Node.js也是基于V8引擎開發(fā)的。

那么v8引擎執(zhí)行JS代碼需要經(jīng)歷哪些階段,如下:

  • Parse階段:v8引擎負(fù)責(zé)將JS代碼轉(zhuǎn)換為AST(抽象語法樹)
  • Ignition階段:解釋器將AST轉(zhuǎn)換為字節(jié)碼,解析執(zhí)行字節(jié)碼,同時為下階段優(yōu)化編譯提供需要的信息
  • TurboFan階段:編譯器利用上個階段收集的信息,將字節(jié)碼優(yōu)化為可以執(zhí)行的機器碼
  • Orinoco階段:垃圾回收階段,將程序中不再使用的內(nèi)存空間進(jìn)行回收

編譯、執(zhí)行流程圖

AST

在計算機科學(xué)中,抽象語法樹(abstract syntax tree 或者縮寫為 AST),或者語法樹(syntax tree),是源代碼的抽象語法結(jié)構(gòu)的樹狀表現(xiàn)形式,這里特指編程語言的源代碼。

在開發(fā)生產(chǎn)中,我們經(jīng)常使用eslint和babel這些工具都和AST有聯(lián)系,v8引擎就是通過編譯器將源代碼解析為AST的。常見的應(yīng)用場景有:

  • JS反編譯,語法解析
  • Babel編譯ES6語法
  • 代碼高亮
  • 關(guān)鍵字匹配
  • 代碼壓縮

生成AST有兩個關(guān)鍵:詞法分析和語法分析 語法分析:這個階段會將源代碼拆分成最小的、不可再分的詞法單元,稱為token,代碼中的空格在JS中是直接忽略的。詞法單元之間都是獨立的,也即在該階段我們并不關(guān)心每一行代碼是通過什么方式組合在一起的。

語法分析:這個過程是將詞法單元轉(zhuǎn)換成一個由元素逐級嵌套所組成的待料了程序語法結(jié)構(gòu)的樹,被稱為抽象語法樹。將上一階段生成的 token 列表轉(zhuǎn)換為如下圖右側(cè)所示的 AST,根據(jù)這個數(shù)據(jù)結(jié)構(gòu)大致可以看出轉(zhuǎn)換之前源代碼的基本構(gòu)造。

簡而言之,詞法分析階段就是將代碼拆解成獨立的、不可再分的tokens,而語法分析階段就是將拆分后的tokens進(jìn)行解析,根據(jù)其在整個代碼上下文中的作用和聯(lián)系,去除多余的token形成抽象語法樹。

瀏覽器還不支持es6語法,需要將其轉(zhuǎn)換為es5語法,這個過程需要借助babel來實現(xiàn)。將es6源碼解析成AST,再將es6語法的抽象語法樹轉(zhuǎn)為es5的抽象語法樹,最后利用它來生成es5的源代碼。

生成字節(jié)碼

Ignition階段就是將AST轉(zhuǎn)換為字節(jié)碼,但是之前的v8版本不會經(jīng)歷此過程,最早只是直接通過AST轉(zhuǎn)成機器碼,后面的版本才開始對其進(jìn)行改進(jìn)。將AST直接轉(zhuǎn)為機器碼是存在問題的,因為:

  • 直接轉(zhuǎn)換會帶來內(nèi)存占用過大的問題。因為將抽象語法樹全部生成了機器碼,而機器碼相比字節(jié)碼占用的內(nèi)存更多
  • 某些JS使用場景使用解釋器更為合適。解析成字節(jié)碼,有些代碼沒必要解析成機器碼,進(jìn)而可以減少占用大量的內(nèi)存空間

V8引擎重新引進(jìn)Ignition解釋器,將抽象語法樹轉(zhuǎn)換成字節(jié)碼后,內(nèi)存占用顯著降低,同時可以使用JIT編譯器做進(jìn)一步優(yōu)化。

字節(jié)碼是介于AST和機器碼之間的代碼,需要將其轉(zhuǎn)換為機器碼后才能執(zhí)行,字節(jié)碼可以理解為機器碼的一種抽象。

解釋器在得到AST后,會按需進(jìn)行解釋和執(zhí)行,也就是說如果某個函數(shù)沒有被調(diào)用,則不會去解釋執(zhí)行它。

解釋器創(chuàng)建了調(diào)用棧來記錄函數(shù)的調(diào)用流程,每調(diào)用一個函數(shù),解釋器就會把該函數(shù)添加進(jìn)調(diào)用棧。解釋器會為被添加進(jìn)入的函數(shù)創(chuàng)建一個棧幀,這個棧幀是用來保存函數(shù)的局部變量以及執(zhí)行語句,因此會立即執(zhí)行這個棧幀。如果正在執(zhí)行的函數(shù)還調(diào)用了其他函數(shù),那么新函數(shù)也將會被添加進(jìn)調(diào)用棧并執(zhí)行,一旦這個函數(shù)執(zhí)行結(jié)束,對應(yīng)的棧幀就會被立即銷毀。查看調(diào)用棧的方式有兩種:調(diào)用函數(shù)console.log()打印到控制臺,利用瀏覽器開發(fā)者工具進(jìn)行斷點調(diào)試。

生成機器碼

如果發(fā)現(xiàn)一段代碼被重復(fù)執(zhí)行多次的情況,生成的字節(jié)碼以及分析數(shù)據(jù)會傳給TurboFan編譯器,它會根據(jù)分析數(shù)據(jù)的情況生成優(yōu)化好的機器碼。

TurboFan編譯器是JIT優(yōu)化的編譯器,TurboFan的編譯線程和生成字節(jié)碼不會在同一個線程上,這樣可以和Ignition解釋器相互配合著使用,不受另外一方的影響。由Ignition解釋器收集的分析數(shù)據(jù)被TurboFan編譯器使用,主要是通過一種推測優(yōu)化的技術(shù),生成已經(jīng)優(yōu)化的機器碼進(jìn)行執(zhí)行。

優(yōu)化后的機器碼作用與緩存很類似,當(dāng)解釋器再次遇到相同的內(nèi)容時,就可以直接執(zhí)行優(yōu)化后的機器碼。當(dāng)然優(yōu)化后的代碼有可能會無法運行(比如函數(shù)參數(shù)類型改變),那么會再次反優(yōu)化為字節(jié)碼交給解釋器。

3參考文章

《Javascript核心原理精講》

《前端也要懂編譯:AST 從入門到上手指南》

《編譯原理》

4寫在最后

 

當(dāng)前市面上比較主流的JS引擎編譯過程大部分類似,主要原因可能是在某些地方加入了特定的優(yōu)化,但是其核心思路和v8大體差不多。AST是比較重要的知識點,深入了解之后有助于自己實現(xiàn)前端工具。對此可以通過多研究一些前端工具,來提升自己的業(yè)務(wù)開發(fā)效率和編程能力。

 

責(zé)任編輯:武曉燕 來源: 前端萬有引力
相關(guān)推薦

2018-08-31 10:53:25

MySQL存儲引擎

2021-12-08 07:55:41

EventLoop瀏覽器事件

2015-07-13 09:21:50

風(fēng)速傳感器物聯(lián)網(wǎng)

2010-09-29 09:28:04

DHCP工作原理

2020-11-06 15:20:45

瀏覽器前端架構(gòu)

2013-05-23 16:01:56

瀏覽器

2013-06-14 13:56:29

瀏覽器渲染原理

2019-01-03 13:09:58

瀏覽器緩存原理

2021-04-19 11:40:15

瀏覽器路徑

2020-03-12 11:29:51

JavaScript瀏覽器語言

2013-11-20 13:47:43

瀏覽器渲染引擎

2021-03-22 09:57:30

Godot游戲引擎Web

2010-04-05 21:57:14

Netscape瀏覽器

2024-04-10 09:05:37

2015-02-28 09:39:24

Windows 10Spartan

2012-02-01 13:42:19

2022-08-30 09:01:11

瀏覽器渲染前端

2009-04-14 08:52:46

微軟IE8瀏覽器

2018-11-30 09:00:19

html5cssjavascript

2024-08-06 10:07:15

點贊
收藏

51CTO技術(shù)棧公眾號