老熟女激烈的高潮_日韩一级黄色录像_亚洲1区2区3区视频_精品少妇一区二区三区在线播放_国产欧美日产久久_午夜福利精品导航凹凸

重慶分公司,新征程啟航

為企業提供網站建設、域名注冊、服務器等服務

JavaScript引擎V8執行流程概述-創新互聯

本文首發于 vivo互聯網技術 微信公眾號?
鏈接:https://mp.weixin.qq.com/s/t__Jqzg1rbTlsCHXKMwh7A
作者:賴勇高

創新互聯建站是專業的大洼網站建設公司,大洼接單;提供成都網站設計、成都網站制作,網頁設計,網站設計,建網站,PHP網站建設等專業做網站服務;采用PHP框架,可快速的進行大洼網站開發網頁制作和功能擴展;專業做搜索引擎喜愛的網站,專業的做網站團隊,希望更多企業前來合作!

本文主要講解的是V8的技術,是V8的入門篇,主要目的是了解V8的內部機制,希望對前端,快應用,瀏覽器,以及nodejs同學有些幫助。這里不涉及到如何編寫優秀的前端,只是對JS內部引擎技術的講解。

一、V8來源

JavaScript 引擎 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也漸漸的暴露出了自己架構上的缺陷:

  1. Full-Codegen編譯直接生成機器碼,導致內存占用大

  2. Full-Codegen編譯直接生成機器碼,導致編譯時間長,導致啟動速度慢

  3. Crankshaft 無法優化try,catch和finally等關鍵字劃分的代碼塊

  4. 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字節碼:

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

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

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

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

如下圖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的整體執行流程就結束了。文章中可能存在理解不正確的地方敬請指出。

  • 參考文章
  1. https://v8.dev/docs

  2. https://docs.google.com/presentation/d/1HgDDXBYqCJNasBKBDf9szap1j4q4wnSHhOYpaNy5mHU/edit#slide=id.g17d335048f\_1\_1105

  3. https://docs.google.com/presentation/d/1Z9iIHojKDrXvZ27gRX51UxHD-bKf1QcPzSijntpMJBM/edit#slide=id.p

  4. https://zhuanlan.zhihu.com/p/82854566

另外有需要云服務器可以了解下創新互聯scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業上云的綜合解決方案,具有“安全穩定、簡單易用、服務可用性高、性價比高”等特點與優勢,專為企業上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。


分享文章:JavaScript引擎V8執行流程概述-創新互聯
文章路徑:http://www.xueling.net.cn/article/ccodeg.html

其他資訊

在線咨詢
服務熱線
服務熱線:028-86922220
TOP
主站蜘蛛池模板: 奇米视频在线观看 | 热99热 | 国产精品国产自线拍免费软件 | 99黄色网| 乳尖乱颤娇喘连连A片在线观看 | 免费在线激情视频 | 99国产一区二区精品久久 | 日韩亚洲国产中文永久 | 男人的天堂视频精品乱在线 | 欧美大片一区二区 | fc2免费人成在线视频 | av日韩精品在线观看 | 人摸人操 | 欧美成人A猛片在线观看 | 97人妻碰碰碰久久久久禁片 | 欧美日韩一区二区三区四区在线观看 | 精品视频在线免费看 | 兔子先生视频在线播放 | 亚洲男同GV在线观看 | 97理论三级九七午夜在线观看 | 日本韩国一级片 | 免费观看男女性高视频 | 国产精品aⅴ | 国产在线免费视频 | www.99久| 一级特黄爽大片刺激在线 | 男女啪啪抽搐呻吟高潮动态图 | 久久久人成影片一区二区三区 | 国产亚洲色婷婷久久99精品91 | 初尝黑人巨砲波多野结衣 | 欧美专区日韩专区 | 国产精品情侣呻吟对白视频 | 高潮真紧好爽我视频 | 国产freesexvideos性中国 | 国产精品激情综合五月天中文字幕 | 亚洲综合久久无码色噜噜赖水 | 国产精品久国产精品 | 欧美操日韩 | 久久伊人一区二区 | 久久毛片免费视频 | 国产三级农村妇女做受 |