我們寫的JavaScript代碼直接交給瀏覽器或者Node執(zhí)行時狸页,底層的CPU是不認(rèn)識的哈踱,也沒法執(zhí)行。CPU只認(rèn)識自己的指令集玉转,指令集對應(yīng)的是匯編代碼。寫匯編代碼是一件很(不)痛(可)苦(能)的事情殴蹄。
V8:強(qiáng)大的JavaScript引擎
V8由許多子模塊構(gòu)成究抓,其中這4個模塊是最重要的:
- Parser:負(fù)責(zé)將JavaScript源碼轉(zhuǎn)換為Abstract Syntax Tree (AST)
- Ignition:即解釋器,負(fù)責(zé)將AST轉(zhuǎn)換為Bytecode饶套,解釋執(zhí)行Bytecode漩蟆;同時收集TurboFan優(yōu)化編譯所需的信息,比如函數(shù)參數(shù)的類型
- TurboFan:即編譯器妓蛮,利用Ignition所收集的類型信息怠李,將Bytecode轉(zhuǎn)換為優(yōu)化的匯編代碼;
- Orinoco:垃圾回收模塊,負(fù)責(zé)將程序不再需要的內(nèi)存空間回收捺癞;
將JS源碼編譯為匯編代碼流程圖
簡單地說夷蚊,Parser將JS源碼轉(zhuǎn)換為AST,然后Ignition將AST轉(zhuǎn)換為Bytecode髓介,最后TurboFan將Bytecode轉(zhuǎn)換為經(jīng)過優(yōu)化的Machine Code(實際上是匯編代碼)惕鼓。
圖片中的紅線是逆向的,這的確有點奇怪唐础,Optimized Machine Code會被還原為Bytecode箱歧,這個過程叫做Deoptimization。這是因為Ignition收集的信息可能是錯誤的一膨,比如add函數(shù)的參數(shù)之前是整數(shù)呀邢,后來又變成了字符串。生成的Optimized Machine Code已經(jīng)假定add函數(shù)的參數(shù)是整數(shù)豹绪,那當(dāng)然是錯誤的价淌,于是需要進(jìn)行Deoptimization。
function add(x, y) {
return x + y;
}
add(1, 2);
add("1", "2");