瀏覽器如何執行JS


作為JS系列的第一篇,內容當然是瀏覽器如何執行一段JS啦。

首先通過瀏覽器篇我們可以得知,JS是在渲染進程里的JS引擎線程執行的。在此之后還要了解幾個概念,編譯器(Compiler)、解釋器(Interpreter)、抽象語法樹(AST)、字節碼(Bytecode)、即時編譯(JIT)

編譯器和解釋器

之所以存在編譯器和解釋器,是因為機器不能直接理解我們所寫的代碼,所以在執行程序之前,需要將我們所寫的代碼“翻譯”成機器能讀懂的機器語言。按語言的執行流程,可以把語言划分為編譯型語言和解釋型語言。

編譯型語言

編譯型語言在程序執行之前,需要經過編譯器的編譯過程,並且編譯之后會直接保留機器能讀懂的二進制文件,這樣每次運行程序時,都可以直接運行該二進制文件,而不需要再次重新編譯了

解釋型語言

在每次運行時都需要通過解釋器對程序進行動態解釋和執行。比如 Python、JavaScript 等都屬於解釋型語言。

           image.png

                                編譯器和解釋器進行'翻譯'的流程

V8執行代碼流程

    image.png

1.通過詞法分析,語法分析生成抽象語法樹(AST)和執行上下文

  • 第一階段是分詞(tokenize),又稱為詞法分析,其作用是將一行行的源碼拆解成一個個 token。所謂 token,指的是語法上不可能再分的、最小的單個字符或字符串
  • 第二階段是解析(parse),又稱為語法分析,其作用是將上一步生成的 token 數據,根據語法規則轉為 AST。如果源碼符合語法規則,這一步就會順利完成。但如果源碼存在語法錯誤,這一步就會終止,並拋出一個“語法錯誤”。

2.根據AST生成字節碼

有了 AST 和執行上下文后,那接下來的第二步,解釋器 Ignition 就登場了,它會根據 AST 生成字節碼,並解釋執行字節碼。

字節碼就是介於 AST 和機器碼之間的一種代碼。但是與特定類型的機器碼無關,字節碼需要通過解釋器將其轉換為機器碼后才能執行。

3.執行代碼

如果有一段第一次執行的字節碼,解釋器 Ignition 會逐條解釋執行。解釋器 Ignition 除了負責生成字節碼之外,它還有另外一個作用,就是解釋執行字節碼。在 Ignition 執行字節碼的過程中,如果發現有熱點代碼(HotSpot),比如一段代碼被重復執行多次,這種就稱為熱點代碼,那么后台的編譯器 TurboFan 就會把該段熱點的字節碼編譯為高效的機器碼,然后當再次執行這段被優化的代碼時,只需要執行編譯后的機器碼就可以了,這樣就大大提升了代碼的執行效率。

V8 的解釋器和編譯器的取名也很有意思。解釋器 Ignition 是點火器的意思,編譯器 TurboFan 是渦輪增壓的意思,寓意着代碼啟動時通過點火器慢慢發動,一旦啟動,渦輪增壓介入,其執行效率隨着執行時間越來越高效率,因為熱點代碼都被編譯器 TurboFan 轉換了機器碼,直接執行機器碼就省去了字節碼“翻譯”為機器碼的過程。其實字節碼配合解釋器和編譯器是最近一段時間很火的技術,比如 Java 和 Python 的虛擬機也都是基於這種技術實現的,我們把這種技術稱為即時編譯(JIT)

 

相關問題

為什么V8代碼執行時間越久,執行效率越高?

因為即時編譯(JIT)技術的存在,解釋器執行字節碼的過程中,如果發現有熱點代碼(HotSpot),那么后台的編譯器 TurboFan 就會把該段熱點的字節碼編譯為高效的機器碼,然后當再次執行這段被優化的代碼時,只需要執行編譯后的機器碼就可以了,這樣就省去了省去了字節碼“翻譯”為機器碼的過程大大提升了代碼的執行效率。

 

參考:瀏覽器原理與實踐


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM