Google V8 引擎工作原理(翻譯)

YaHuiLiang(Ryou)發表於2019-03-04

V8 引擎如何執行JS,之前看過 Webkit 技術內幕,也只是走馬觀花。並沒有深入理解,突然看到這篇文章,翻譯之How does the Google V8 engine work?

Google V8 引擎是如何工作的?這是一個非常好的問題,這裡有少許流出的官方文件來講解,到底 V8 內部都做了什麼。我會把我知道的東西分享給你(你需要自己猜,哪部分我給拿掉了),還有很多有用的地址去幫助你明白這些內容。

V8 有兩個編譯器:

  • 一個非常簡單並且非常快的編譯器用於將 js 編譯成簡單但是很慢的機械碼,叫做 full-codegen
  • 另一個是非常複雜的實時優化編譯器,編譯高效能的可執行程式碼,叫做 Crankshaft

V8 裡面也使用了一些執行緒:

  • 主執行緒,做你希望它做的事情:載入你的程式碼,編譯它們,執行他們。
  • 有一個獨立的編譯執行緒,當主執行緒執行的時候,它去優化程式碼。
  • 一個 profiler 執行緒(不知道還有沒有了,但是會有一個同樣職責的執行緒存在),用於發現執行過程中哪個方法耗費了大量時間,這樣 Crankshaft 就可以優化這些程式碼。
  • 一些用於 GC 處理的執行緒(譯者注:這裡是一些用於 GC 的執行緒,不止一個執行緒用於垃圾回收)。

最開始執行你的程式碼的時候,V8 開始使用 full-codegenfull-codegen 直接將 JS 程式碼解釋成機械碼,沒有做任何轉化。這可以讓 V8 快速執行機械碼。注意,V8 並不使用中間位元組碼,因此也就不再需要轉譯處理。

當你的程式碼被執行的時候,profiler 執行緒有足夠的資料來找出哪些方法需要被優化。我不確定 V8 如何選擇使用哪個執行緒做的優化,簡單起見,我們就認為它用的主執行緒吧。

主執行緒通過停止正在執行的程式碼(也許就在需要優化的方法這裡),開始使用 Crankshaft 進行優化。JS 程式碼首先會被編譯成一種叫做 Hydrogen 的高階描述,它是控制流圖的靜態單賦值表示。大多數優化都是在這個級別完成的。

首先,對儘可能多的程式碼進行內聯,這使得優化變得更有意義。然後進行型別轉化。這個優化移除了打包和拆包的處理,可以認為是執行了很多指令。這意味著,如果你的程式碼在操作整數,並且沒有做型別轉換,比如轉換成 stringdouble 這些,那麼它會跑的很快。內聯快取會在這個階段起到非常重要的作用,提供了型別判斷。就像你猜到的那樣,我們需要小心型別轉換:如果你希望一個變數是一個整數,但是過一會卻被修改成了其它型別,那麼你的假設就失敗了,那麼一次重新編譯就在所難免了。還有其它的優化,比如 loop-invariant code motion(譯者注:貌似是講將迴圈內不變化的程式碼移到外面,減少每一次迴圈執行的程式碼數量),移除死程式碼(譯者注:不被執行的程式碼也要移除,否則 V8 始終都要要對這些程式碼處理的,帶來了額外負擔)等。

一旦 Hydrogen graph 被優化,Crankshaft 會降低它到一個低階別的描述,叫做 Lithium。大部分的 Lithium 執行於特定架構。分配暫存器就是在這個級別進行的。

最終,Lithium 被編譯成機械碼。然後一些叫做 OSR (on-stack replacement)的事情就發生了。記住,在我們開始編譯和優化執行耗時較長的方法之前,我們喜歡先執行它。我們不要忘記我們剛剛放慢了執行,然後開始執行優化後的程式碼。相反,我們將要轉換所有的上下文,因此我們才能在執行的中間過程中選擇執行優化後的程式碼。我讓你們感到複雜,提醒一下,其它的優化中,我們內聯了一些東西。V8 並不是唯一一個這麼做的虛擬機器,但是我發現一些比較瘋狂的地方。有一些保護機制叫 — 去優化,在做相反的事情,並且會在一些假設的特定情況下反轉一些優化後的程式碼。

還有。就是編譯/執行部分。我忘了提到 GC,不過這很短,因為我對它不太瞭解。

對於垃圾收集來說,V8 使用了傳統的方法,採用標記計數的方式來進行垃圾收集。標記階段必須停止 JavaScript 執行。為了控制 GC 成本,使執行更加穩定,V8 採用增量標記。這就是說,他們不是在堆中試圖示記每一個可能的物件,而是處理一部分堆,然後恢復正常的執行。下一個 GC 停止執行程式碼的時候處理之前未處理的堆。這允許非常短的暫停。如前所述,掃描階段由單獨的執行緒來處理。

posts tagged “v8”

Posts Tagged `v8`

V8 Resources

thlorenz/v8-perf

docs.google.com/document…

floitsch.blogspot.de/2012/04/opt…

還有這裡原始碼

相關文章