(1)v8簡介

V8 並沒有採用某種單一的技術,而是混合編譯執行和解釋執行這兩種手段,我們把這種混合使用編譯器和解釋器的技術稱爲 JIT(Just In Time)技術。
這是一種權衡策略,因爲這兩種方法都各自有各自的優缺點,解釋執行的啓動速度快,但是執行時的速度慢,而編譯執行的啓動速度慢,但是執行時的速度快。你可以參考下面完整的 V8 執行 JavaScript 的流程圖:

初始化基礎環境

  • JavaScript 全局執行上下文就包含了執行過程中的全局信息,比如一些內置函數,全局變量等信息;
  • 全局作用域包含了一些全局變量,在執行過程中的數據都需要存放在內存中;
  • 而 V8 是採用了經典的堆和棧的內存管理模式,所以 V8 還需要初始化內存中的堆和棧結構;
  • 另外,想要我們的 V8 系統活起來,還需要初始化消息循環系統,消息循環系統包含了消息驅動器和消息隊列,它如同 V8 的心臟,不斷接受消息並決策如何處理消息。

解析源碼生成 AST(抽象語法樹)

d8 --print-ast test.js

[generating bytecode for function: ]
--- AST ---
FUNC at 0
. KIND 0
. LITERAL ID 0
. SUSPEND COUNT 0
. NAME ""
. INFERRED NAME ""
. DECLS
. . VARIABLE (0x7fd47200fc90) (mode = VAR, assigned = true) "test"
. BLOCK NOCOMPLETIONS at -1
. . EXPRESSION STATEMENT at 11
. . . INIT at 11
. . . . VAR PROXY unallocated (0x7fd47200fc90) (mode = VAR, assigned = true) "test"
. . . . LITERAL "sullay"

解析源碼生成作用域

d8 --print-scopes test.js

Global scope:
global { // (0x7fe60004e248) (0, 19)
  // will be compiled
  // 1 stack slots
  // temporary vars:
  TEMPORARY .result;  // (0x7fe60004e5a8) local[0]
  // local vars:
  VAR test;  // (0x7fe60004e490) 
}

依據AST和作用域生成字節碼

d8 --print-bytecode test.js

[generated bytecode for function:  (0x16d008292e4d <SharedFunctionInfo>)]
Bytecode length: 18
Parameter count 1
Register count 3
Frame size 24
OSR nesting level: 0
Bytecode Age: 0
         0x16d008292ed6 @    0 : 13 00             LdaConstant [0]
         0x16d008292ed8 @    2 : c2                Star1 
         0x16d008292ed9 @    3 : 19 fe f8          Mov <closure>, r2
         0x16d008292edc @    6 : 64 4f 01 f9 02    CallRuntime [DeclareGlobals], r1-r2
         0x16d008292ee1 @   11 : 13 01             LdaConstant [1]
         0x16d008292ee3 @   13 : 23 02 00          StaGlobal [2], [0]
         0x16d008292ee6 @   16 : 0e                LdaUndefined 
         0x16d008292ee7 @   17 : a8                Return 
Constant pool (size = 3)
0x16d008292ea1: [FixedArray] in OldSpace
 - map: 0x16d008002205 <Map>
 - length: 3
           0: 0x16d008292e95 <FixedArray[1]>
           1: 0x16d008292e2d <String[6]: #sullay>
           2: 0x16d00820c015 <String[4]: #test>
Handler Table (size = 0)
Source Position Table (size = 0)

優化熱點代碼爲二進制的機器代碼

生成字節碼之後,解釋器會解釋執行這段字節碼,如果重複執行了某段代碼,監控器就會將其標記爲熱點代碼,並提交給編譯器優化執行。

d8 --trace-opt test.js

反優化生成的二進制機器代碼

JavaScript 是一門動態語言,在運行過程中,某些被優化的結構可能會被 V8 動態修改了,這會導致之前被優化的代碼失效,如果某塊優化之後的代碼失效了,那麼編譯器需要執行反優化操作

d8 --trace-deopt test.js
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章