V8 引擎如何運行


原文地址 www.quora.com/How-does-th…c++

v8是google的開源高性能js和WebAssembly引擎,用c++編寫。 v8是一個c++程序,它接收js代碼,編譯並執行它。web


功能
  • 編譯並執行js代碼
  • 處理調用棧-某種順序運行js函數
  • 管理對象的內存分配-內存堆
  • 垃圾收集-再也不使用的對象
  • 提供全部數據類型,運算符、對象和函數

可是V8不能瞭解文檔對象模型BOM,由於這是由瀏覽器提供和Nodejs沒有關係。

V8是單線程執行引擎,構建爲每一個js執行上下文只運行一個線程。實際上,你能夠在同一個進程中運行兩個v8引擎(web-workers)可是不會像真正的線程那樣子共享任何變量或上下文。這並不意味這v8在單個線程上運行,可是確實意味着 它提供了單個線程的js流




v8和其餘現代js引擎在執行以前經過just-in-time compilation 腳本編譯到本機機器代碼來決定速度。代碼最初由 基線編譯器編譯,能夠 快速生成非優化的機器代碼。編譯後的代碼在運行時進行分析,並 可選擇使用更高級的優化編譯器動態地從新編譯,以實現最佳性能。在v8中,此腳本執行通道具備各類特殊和條件,這些特殊狀況和條件須要 複雜的機制才能在基線編譯器和兩個優化編譯器Crankshaft和TurboFan之間切換

這種方法的一個問題(除了架構複雜性)是JITed機器代碼可能消耗大量內存,即便代碼只執行一次。 爲了 減輕這種開銷,V8團隊構建了一個名爲Ignition的新JavaScript解釋器,它能夠 取代V8的基線編譯器,以更少的內存開銷執行代碼,併爲更簡單的腳本執行管道鋪平道路。 經過Ignition,V8將JavaScript函數編譯爲簡潔的字節碼,該字節碼的大小爲等效基線機器代碼的50%到25%。 而後,該字節碼由高性能解釋器執行,該解釋器在真實世界的網站上產生接近V8現有基線編譯器生成的代碼的執行速度。 在Chrome 53中,將爲具備有限RAM(512 MB或更低)的Android設備啓用Ignition,從而最須要節省內存。 現場早期實驗的結果顯示,Ignition可將每一個Chrome標籤的內存減小約5%。

在構建Ignition的字節碼解釋器時,該團隊考慮了許多潛在的實現方法。 用C ++編寫的傳統解釋器沒法與V8生成的其他代碼高效交互。 另外一種方法是在彙編代碼中手動編寫解釋器代碼,可是若是V8支持9個架構端口,這將須要大量的工程開銷。 相反,咱們選擇了一種利用TurboFan強度的方法,TurboFan是咱們新的優化編譯器,已經針對與V8運行時和其餘生成代碼的最佳交互進行了調整。 Ignition解釋器使用TurboFan的低級,與體系結構無關的宏彙編指令爲每一個操做碼生成字節碼處理程序。 TurboFan將這些指令編譯到目標體系結構,在此過程當中執行低級指令選擇和機器寄存器分配。 這致使高度優化的解釋器代碼,該代碼能夠執行字節碼指令並以低開銷方式與V8虛擬機的其他部分進行交互,而且在代碼庫中添加了最少許的新機器。 Ignition是一個寄存器機器,每一個字節碼將其輸入和輸出指定爲顯式寄存器操做數,而不是堆棧機器,其中每一個字節碼將消耗輸入並在隱式堆棧上推送輸出。 特殊累加器寄存器是許多字節碼的隱式輸入和輸出寄存器。這經過避免指定特定寄存器操做數的須要來減少字節碼的大小。 因爲許多JavaScript表達式涉及從左到右計算的操做鏈,所以這些操做的臨時結果一般能夠在表達式的評估過程當中保留在累加器中,從而最大限度地減小了加載和存儲到顯式寄存器的操做的須要。 生成字節碼時,它會經過一系列內聯優化階段。 這些階段對字節碼流執行簡單分析,用更快的序列替換常見模式,刪除一些冗餘操做,並最小化沒必要要的寄存器加載和傳輸的數量。 優化一塊兒進一步減少了字節碼的大小並提升了性能。
相關文章
相關標籤/搜索