日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

詳解JavaScript引擎V8執行流程

瀏覽:118日期:2023-06-02 08:10:16
目錄一、V8來源二、V8的服務對象三、V8的早期架構四、V8早期架構的缺陷五、V8的現有架構六、V8的詞法分析和語法分析七、V8 AST抽象語法樹八、字節碼九、Turbofan一、V8來源

V8的名字來源于汽車的“V型8缸發動機”(V8發動機)。V8發動機主要是美國發展起來,因為馬力十足而廣為人知。V8引擎的命名是Google向用戶展示它是一款強力并且高速的JavaScript引擎。

V8未誕生之前,早期主流的JavaScript引擎是JavaScriptCore引擎。JavaScriptCore是主要服務于Webkit瀏覽器內核,他們都是由蘋果公司開發并開源出來。據說Google是不滿意JavaScriptCore和Webkit的開發速度和運行速度,Google另起爐灶開發全新的JavaScript引擎和瀏覽器內核引擎,所以誕生了V8和Chromium兩大引擎,到現在已經是最受歡迎的瀏覽器相關軟件。

二、V8的服務對象

V8是依托Chrome發展起來的,后面確不局限于瀏覽器內核。發展至今V8應用于很多場景,例如流行的nodejs,weex,快應用,早期的RN。

三、V8的早期架構

V8引擎的誕生帶著使命而來,就是要在速度和內存回收上進行革命的。JavaScriptCore的架構是采用生成字節碼的方式,然后執行字節碼。Google覺得JavaScriptCore這套架構不行,生成字節碼會浪費時間,不如直接生成機器碼快。所以V8在前期的架構設計上是非常激進的,采用了直接編譯成機器碼的方式。后期的實踐證明Google的這套架構速度是有改善,但是同時也造成了內存消耗問題。可以看下V8的初期流程圖:

詳解JavaScript引擎V8執行流程

早期的V8有Full-Codegen和Crankshaft兩個編譯器。V8 首先用 Full-Codegen把所有的代碼都編譯一次,生成對應的機器碼。JS在執行的過程中,V8內置的Profiler篩選出熱點函數并且記錄參數的反饋類型,然后交給 Crankshaft 來進行優化。所以Full-Codegen本質上是生成的是未優化的機器碼,而Crankshaft生成的是優化過的機器碼。

四、V8早期架構的缺陷

隨著版本的引進,網頁的復雜化,V8也漸漸的暴露出了自己架構上的缺陷:

Full-Codegen編譯直接生成機器碼,導致內存占用大 Full-Codegen編譯直接生成機器碼,導致編譯時間長,導致啟動速度慢 Crankshaft 無法優化try,catch和finally等關鍵字劃分的代碼塊 Crankshaft新加語法支持,需要為此編寫適配不同的Cpu架構代碼五、V8的現有架構

為了解決上述缺點,V8采用JavaScriptCore的架構,生成字節碼。這里是不是感覺Google又繞回來了。V8采用生成字節碼的方式,整體流程如下圖:

詳解JavaScript引擎V8執行流程

Ignition是V8的解釋器,背后的原始動機是減少移動設備上的內存消耗。在Ignition之前,V8的Full-codegen基線編譯器生成的代碼通常占據Chrome整體JavaScript堆的近三分之一。這為Web應用程序的實際數據留下了更少的空間。

Ignition的字節碼可以直接用TurboFan生成優化的機器代碼,而不必像Crankshaft那樣從源代碼重新編譯。Ignition的字節碼在V8中提供了更清晰且更不容易出錯的基線執行模型,簡化了去優化機制,這是V8 自適應優化的關鍵特性。最后,由于生成字節碼比生成Full-codegen的基線編譯代碼更快,因此激活Ignition通常會改善腳本啟動時間,從而改善網頁加載。

TurboFan是V8的優化編譯器,TurboFan項目最初于2013年底啟動,旨在解決Crankshaft的缺點。Crankshaft只能優化JavaScript語言的子集。例如,它不是設計用于使用結構化異常處理優化JavaScript代碼,即由JavaScript的try,catch和finally關鍵字劃分的代碼塊。很難在Crankshaft中添加對新語言功能的支持,因為這些功能幾乎總是需要為九個支持的平臺編寫特定于體系結構的代碼。

采用新架構后的優勢

不同架構下V8的內存對比,如圖:

詳解JavaScript引擎V8執行流程

結論:可以明顯看出Ignition+TurboFan架構比Full-codegen+Crankshaft架構內存降低一半多。

不同架構網頁速度提升對比,如圖:

詳解JavaScript引擎V8執行流程

結論:可以明顯看出Ignition+TurboFan架構比Full-codegen+Crankshaft架構70%網頁速度是有提升的。

接下來我們大致的講解下現有架構的每個流程:

六、V8的詞法分析和語法分析

學過編譯原理的同學可以知道,JS文件只是一個源碼,機器是無法執行的,詞法分析就是把源碼的字符串分割出來,生成一系列的token,如下圖可知不同的字符串對應不同的token類型。

詳解JavaScript引擎V8執行流程

詞法分析完后,接下來的階段就是進行語法分析。語法分析語法分析的輸入就是詞法分析的輸出,輸出是AST抽象語法樹。當程序出現語法錯誤的時候,V8在語法分析階段拋出異常。

詳解JavaScript引擎V8執行流程

七、V8 AST抽象語法樹

下圖是一個add函數的抽象語法樹數據結構

詳解JavaScript引擎V8執行流程

V8 Parse階段后,接下來就是根據抽象語法樹生成字節碼。如下圖可以看出add函數生成對應的字節碼:

詳解JavaScript引擎V8執行流程

BytecodeGenerator類的作用是根據抽象語法樹生成對應的字節碼,不同的node會對應一個字節碼生成函數,函數開頭為Visit****。如下圖+號對應的函數字節碼生成:

詳解JavaScript引擎V8執行流程

void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { FeedbackSlot slot = feedback_spec()->AddBinaryOpICSlot(); Expression* subexpr; Smi* literal; if (expr->IsSmiLiteralOperation(&subexpr, &literal)) { VisitForAccumulatorValue(subexpr); builder()->SetExpressionPosition(expr); builder()->BinaryOperationSmiLiteral(expr->op(), literal, feedback_index(slot)); } else { Register lhs = VisitForRegisterValue(expr->left()); VisitForAccumulatorValue(expr->right()); builder()->SetExpressionPosition(expr); // 保存源碼位置 用于調試 builder()->BinaryOperation(expr->op(), lhs, feedback_index(slot)); // 生成Add字節碼 }}

上述可知有個源碼位置記錄,然后下圖可知源碼和字節碼位置的對應關系:

詳解JavaScript引擎V8執行流程

生成字節碼,那字節碼如何執行的呢?接下來講解下:

八、字節碼

首先說下V8字節碼:

每個字節碼指定其輸入和輸出作為寄存器操作數

Ignition 使用registers寄存器 r0,r1,r2... 和累加器寄存器(accumulator register)

registers寄存器:函數參數和局部變量保存在用戶可見的寄存器中

累加器:是非用戶可見寄存器,用于保存中間結果

如下圖ADD字節碼:

詳解JavaScript引擎V8執行流程

字節碼執行

下面一系列圖表示每個字節碼執行時,對應寄存器和累加器的變化,add函數傳入10,20的參數,最終累加器返回的結果是50。

詳解JavaScript引擎V8執行流程

詳解JavaScript引擎V8執行流程

詳解JavaScript引擎V8執行流程

詳解JavaScript引擎V8執行流程

詳解JavaScript引擎V8執行流程

詳解JavaScript引擎V8執行流程

詳解JavaScript引擎V8執行流程

詳解JavaScript引擎V8執行流程

每個字節碼對應一個處理函數,字節碼處理程序保存的地址在dispatch_table_中。執行字節碼時會調用到對應的字節碼處理程序進行執行。Interpreter類成員dispatch_table_保存了每個字節碼的處理程序地址。

詳解JavaScript引擎V8執行流程

詳解JavaScript引擎V8執行流程

例如ADD字節碼對應的處理函數是(當執行ADD字節碼時候,會調用InterpreterBinaryOpAssembler類):

IGNITION_HANDLER(Add, InterpreterBinaryOpAssembler) { BinaryOpWithFeedback(&BinaryOpAssembler::Generate_AddWithFeedback);} void BinaryOpWithFeedback(BinaryOpGenerator generator) { Node* reg_index = BytecodeOperandReg(0); Node* lhs = LoadRegister(reg_index); Node* rhs = GetAccumulator(); Node* context = GetContext(); Node* slot_index = BytecodeOperandIdx(1); Node* feedback_vector = LoadFeedbackVector(); BinaryOpAssembler binop_asm(state()); Node* result = (binop_asm.*generator)(context, lhs, rhs, slot_index, feedback_vector, false); SetAccumulator(result); // 將ADD計算的結果設置到累加器中 Dispatch(); // 處理下一條字節碼 }

其實到此JS代碼就已經執行完成了。在執行過程中,發現有熱點函數,V8會啟用Turbofan進行優化編譯,直接生成機器碼,所以接下來講解下Turbofan優化編譯器:

九、Turbofan

Turbofan是根據字節碼和熱點函數反饋類型生成優化后的機器碼,Turbofan很多優化過程,基本和編譯原理的后端優化差不多,采用的sea-of-node。

詳解JavaScript引擎V8執行流程

add函數優化:

function add(x, y) { return x+y;}add(1, 2);%OptimizeFunctionOnNextCall(add);add(1, 2);

V8是有函數可以直接調用指定優化哪個函數,執行%OptimizeFunctionOnNextCall主動調用Turbofan優化add函數,根據上次調用的參數反饋優化add函數,很明顯這次的反饋是整型數,所以turbofan會根據參數是整型數進行優化直接生成機器碼,下次函數調用直接調用優化好的機器碼。(注意執行V8需要加上 --allow-natives-syntax,OptimizeFunctionOnNextCall為內置函數,只有加上 --allow-natives-syntax,JS才能調用內置函數 ,否則執行會報錯)。

JS的add函數生成對應的機器碼如下:

詳解JavaScript引擎V8執行流程

這里會涉及small interger小整數概念,可以查看這篇文章https://zhuanlan.zhihu.com/p/82854566

如果把add函數的傳入參數改成字符

function add(x, y) { return x+y;}add(1, 2);%OptimizeFunctionOnNextCall(add);add(1, 2);

優化后的add函數生成對應的機器碼如下:

詳解JavaScript引擎V8執行流程

對比上面兩圖,add函數傳入不同的參數,經過優化生成不同的機器碼。

如果傳入的是整型,則本質上是直接調用add匯編指令

如果傳入的是字符串,則本質上是調用V8的內置Add函數

到此V8的整體執行流程就結束了。

以上就是詳解JavaScript引擎V8執行流程的詳細內容,更多關于JavaScript引擎V8的資料請關注好吧啦網其它相關文章!

標簽: JavaScript
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
欧美中文高清| 国产精品jk白丝蜜臀av小说| 日本不卡免费高清视频在线| 国产成人精选| 精品国产亚洲一区二区三区在线 | 麻豆一区在线| 天海翼精品一区二区三区| 亚洲综合三区| 石原莉奈在线亚洲三区| 亚洲免费中文| 亚洲69av| 国产精品一在线观看| 久久av中文| 伊人久久视频| 国产在线日韩| 亚洲精品综合| 国产伦理一区| 国产一区二区三区四区五区| 亚洲美女久久精品| 亚洲二区精品| 亚洲日本欧美| 亚洲精品国产日韩| 欧美一级网站| 国产欧美欧美| 麻豆视频在线观看免费网站黄 | 日韩成人精品一区二区| 涩涩av在线| 99亚洲精品| 日韩精品视频一区二区三区| 中文无码日韩欧| 国产精品xxx在线观看| 超级白嫩亚洲国产第一| 国产一区观看| 欧美一区=区三区| 精品美女在线视频| 亚洲精品一区二区在线看| 亚洲精选91| 97精品97| 最新亚洲国产| 麻豆国产在线| 免费在线观看日韩欧美| 国产精品亚洲综合色区韩国| 性感美女一区二区在线观看| 噜噜噜久久亚洲精品国产品小说| 国产免费av一区二区三区| 成人啊v在线| 婷婷五月色综合香五月| а√天堂8资源在线| 国产农村妇女精品一二区| 日本精品另类| 久久狠狠婷婷| 日韩国产一二三区| 久久人人97超碰国产公开结果| 一区二区三区午夜视频| 精品国产91| 日韩中文字幕亚洲一区二区va在线| 国产精品天天看天天狠| 欧美精品黄色| 国产一区二区三区免费在线| 久久成人国产| yellow在线观看网址| 最新国产精品视频| 日韩中文影院| 日本午夜精品久久久久| 亚洲精品永久免费视频| 亚洲精品在线二区| 日韩欧美二区| 日本不卡视频一二三区| 老牛影视一区二区三区| 超级白嫩亚洲国产第一| 每日更新成人在线视频| 精品亚洲成人| 亚洲人成在线影院| 成人av三级| 国产日韩免费| 三级一区在线视频先锋| 欧美黄色网页| 久久精品国产福利| 成人日韩av| 噜噜噜躁狠狠躁狠狠精品视频| 欧美日韩国产免费观看| 久久久777| 青青青国产精品| 久久精品福利| 日韩毛片在线| 在线国产一区| 久久久久久色 | 精品日韩视频| 国户精品久久久久久久久久久不卡 | 影院欧美亚洲| 日本在线高清| 久久成人av| 国产日韩欧美一区二区三区在线观看| 久久久久久美女精品| 国产日韩亚洲| 最新国产精品| 亚洲国产专区校园欧美| 亚洲在线一区| 日本精品另类| 久久亚洲国产精品一区二区| 国产精品美女久久久浪潮软件| 日本亚洲三级在线| 欧美精品一二| 欧美日韩调教| 激情久久五月| 精品日韩一区| 日韩精选在线| 久久亚洲风情| 国产一区二区三区久久| 亚洲精品成人一区| 麻豆久久一区二区| 蜜芽一区二区三区| 成人av动漫在线观看| 日本不卡免费高清视频在线| 久久丁香四色| 日韩超碰人人爽人人做人人添| 先锋影音国产一区| 日本成人在线网站| 久久中文欧美| 中文一区一区三区高中清不卡免费| 成人日韩在线| 精品五月天堂| 国产精品v亚洲精品v日韩精品| 国产日韩免费| 精品久久久久中文字幕小说| 国产高潮在线| 日本v片在线高清不卡在线观看| 国产一在线精品一区在线观看| 麻豆成人综合网| 久久久久久黄| 精精国产xxxx视频在线野外| 国产日本精品| 国产欧美日韩免费观看| 日韩和欧美的一区| 国产精一区二区| 美女精品一区二区| 国产福利片在线观看| 久久激情婷婷| 日韩影院精彩在线| 久久激情五月婷婷| 狠狠久久伊人| 久久精品国产大片免费观看| 免费日韩视频| 国产欧美在线| 天堂8中文在线最新版在线| 人人草在线视频| 99成人在线| 国产精品igao视频网网址不卡日韩| 狠狠久久伊人中文字幕| 亚洲一本视频| 国产精品最新| 亚洲第一精品影视| 欧美精品九九| 国产精品网址| 亚洲国内精品| 女人天堂亚洲aⅴ在线观看| 巨乳诱惑日韩免费av| 久久国产免费看| 92国产精品| 日韩欧乱色一区二区三区在线| 美女国产一区| 亚洲一区激情| 超碰成人av| 日韩综合一区二区| 精品国产91| 欧美精品一卡| 精品亚洲a∨一区二区三区18| 免费观看亚洲| 日韩中文字幕亚洲一区二区va在线 | 日韩欧美另类中文字幕| 狠狠久久婷婷| 亚洲精品在线a| 国产精品麻豆成人av电影艾秋 | 91伊人久久| 9色国产精品| 国产精品毛片视频| 国产一区亚洲| 欧产日产国产精品视频| 亚洲国产影院| 91综合网人人| 欧美日韩18| 香蕉精品999视频一区二区| 在线看片国产福利你懂的| 日韩专区精品| 精品国产a一区二区三区v免费| 久久午夜视频| 影音国产精品| 亚洲女同中文字幕| 国产精品伦一区二区| 蜜臀精品久久久久久蜜臀| 亚洲在线成人| 精品99在线| 极品日韩av| 香蕉精品久久| 日本不卡视频在线观看| 亚洲欧美日韩综合国产aⅴ| 日韩国产在线不卡视频| 精品国产一区二区三区2021| 国产一区二区三区探花| 一本大道色婷婷在线|