iT邦幫忙

2021 iThome 鐵人賽

DAY 9
1
Modern Web

舌尖上的JS系列 第 9

D9 - 酸 V 啊酸 V8 引擎

前言

前一天提到 v8,那就再深入一點點兒討論 V8 是什麼 以及 它 怎麼翻譯 JavaScript 給電腦

注意:本篇含有大量的專有名詞,會同步以中英文呈現,但閱讀時建議以英文為主,畢竟中文翻譯百花齊放,英文比較不會有爭議

V8 小簡介

  • V8 是 google 開發的一支 JavaScript 開源引擎,以 C++ 語言寫成

  • 應用在 Chrome 及 Node.js 上。

  • V8 實現了 ECMAScript 和 WebAssembly,可跑在 Windows 7 以上的版本、macOS 10.12+ 和使用 x64、IA-32 或 ARM 處理器的 Linux 系統上。

  • V8 一開始被設計來提升 JavaScript 在瀏覽器上的執行速度,透過 JIT 技術更快速的將 JavaScript 翻譯為電腦能理解的代碼。

  • 附上 V8 的介紹網站

V8 引擎的翻譯步驟

接下來看看 V8 是怎麼進行翻譯的步驟,從一張圖解釋起
取自 Understanding V8’s Bytecode

當 V8 引擎要翻譯 JavaScript 時

第一步:先透過自己的 解析器 Parser ,將一行行的語法拆解成個別的 小單位 token

let cookie = 'Oreo' 會拆解成 let、cookie、=、'Oreo'

這些小單位構成了一顆樹,稱為 語法樹 Abstract Syntax Tree,這顆樹呈現出 JavsScript 程式碼間的語法結構

第二步:解釋器 Ignition ,V8 的直譯器,透過內部的 bytecode 格式從這顆語法樹中產生出 bytecode

第三步:渦輪扇 TurboFan ,V8 的最新優化編譯器,將這些 bytecode 轉換為電腦能閱讀的 機器代碼 Machined Code

程式碼的轉換過程會像這樣,左邊是要翻譯 JavaScript,先轉換成 bytecode 後,最後再輸出電腦能閱讀的 Machine Code

印出 V8 產出的 bytecode

有沒有想過 bytecode 到底長怎樣,神奇的傑克,在 node 環境中竟然可以印出 bytecode! 這裡教你 3 招:

  1. node --print-bytecode <檔案名稱>

直接在 command line 輸入這段語法,當你實際輸入後,會咻咻咻印出落落長一段,這是因為除了自己檔案中的程式碼外,其他內建的語法也會被印出來

請留意,node 環境須至少在版本 8.3 以上才支援

以一段程式碼做示範

//檔案 test.js
let cookie = 'Oreo';
countCookie();
function countCookie() {
  let cookie = 'Ritz';
  console.log(cookie); //'Ritz'
}

//terminal 輸入 
Desktop % node --print-bytecode test.js

印出的 bytecode 像這樣

  1. node --print-bytecode --print-bytecode-filter= <想印出的函式名稱> <檔案名稱>

如果只想看部分內容,可以在剛剛那段語法中加上 filter=function 便可只印出你要的特定 function bytecode 結果

// terminal 輸入
Desktop % node --print-bytecode --print-bytecode-filter=countCookie test.js

只呈現 countCookie 的 bytecode 結果

  1. node --print-bytecode --print-bytecode-filter= <想印出的函式名稱> <檔案名稱> > <存入檔案.txt>

最後最後,如果覺得在 terminal 中很難閱讀的話,可以用 > 檔案.txt 將 bytecode 結果存入一支 txt 檔中唷

// terminal 輸入
Desktop % node --print-bytecode --print-bytecode-filter=countCookie test.js > result.js

結語

其實 V8 引擎內部的運作還有很多細節,像是 Inlining、Inline caching、Garbage collection...
但內化成自己的知識還要點時間,畢竟寫成文章是能用自己的語言輸出,還是先分享自己有把握的知識點,我需要一台 JIT

進入未知的領域總是揣揣不安,但踏出的每一步都是勇敢的證明,當回頭看看踩下的每步腳印,你會更有勇氣向前進 - 共勉之。

Reference

Understanding V8’s Bytecode
How to get javascript bytecode from V8 and others in 2019
How V8 compiles JavaScript code ?
Understanding JavaScript’s Engine with Cartoons
How JavaScript works: inside the V8 engine + 5 tips on how to write optimized code


上一篇
D8 - 你不知道Combo : 甜點用一杯 Mojito 解釋 直譯器、編譯器
下一篇
D10 - 點一籠熱呼呼的小籠閉包 Closure
系列文
舌尖上的JS30
0
Chiahsuan
iT邦新手 5 級 ‧ 2021-09-24 15:00:15

勇者Sherry~~~/images/emoticon/emoticon08.gif

我要留言

立即登入留言