什么是JavaScript引擎

什么是JavaScript引擎?

簡單來講,就是能夠提供執行JavaScript代碼的運行環境。要解釋這一概念,需要了解一些編譯原理的基礎概念和現代語言需要的一些新編譯技術。

  1. 首先來看C/C++語言 - 編譯執行。
    它們是比較悠久的語言了,實際上就是使用編譯器直接將它們編譯成本地代碼,這一切都是由開發人員在代碼編寫完成之后實施。用戶只是使用這些編譯好的本地代碼,這些本地代碼被系統的加載器加載執行,這些本地代碼(也就是機器指令)由操作系統調度CPU直接執行,無需其它額外的輔助虛擬機等。這一過程基本上是從源代碼開始,然后抽象語法樹,之后中間表示,最后到本地代碼。

  2. 其次,來看看Python等腳本語言 - 解釋執行。
    處理腳本語言通常的做法是開發者將寫好的代碼直接交給用戶,用戶使用腳本的解釋器將腳本文件加載然后解釋執行。當然,現在Python也可以支持將腳本編譯生成中間表示,當然這是后話。所以這表示,對于腳本語言,沒有開發人員的編譯過程,當然也不是絕對,這主要因為使用場景不一樣,它的目的不是高性能。這一過程是源代碼,到抽象語法樹,再到解釋器解釋執行。

  3. 然后來看看Java語言。
    其做法可以理解為比較明顯的兩個階段:

    • 首先是像C++語言一樣的編譯器,但是,同C++編譯器生成的本地代碼結果不同,經過編譯器編譯之后的是字節碼,字節碼是平臺無關的。
    • 在運行字節碼階段,Java的運行環境也就是Java虛擬機會加載字節碼,使用解釋執行這些字節碼。

如果僅是這樣,那Java的性能就差C++太多了?,F代Java虛擬機一般都引入了JIT技術,也就是前面說的將字節碼轉變成本地代碼來提高執行效率。這主要兩個階段,第一階段對時間要求不嚴格,第二階段則對每個步驟所花費的時間非常敏感,時間越短越好。


最后回到JavaScript語言上來。前面已經說了它是一種解釋性腳本語言。是的,它的確是,但是隨著眾多工程師不斷投入資源來提高它的速度,這使得它能夠使用了Java虛擬機和C++編譯器中眾多的技術,它的工作方式也在演變:

  • 早期也是一樣由解釋器來解釋它們即可,就是將源代碼轉變成抽象語法樹,然后在抽象語法樹上解釋執行。
  • 隨著將Java虛擬機的JIT技術引入,現在的做法是將抽象語法樹轉成中間表示(也就是字節碼),然后通過JIT技術轉成本地代碼,這能夠大大的提高了執行效率。當然也有些做法直接從抽象語法樹生成本地代碼的JIT技術,例如V8。

這是因為JavaScript跟Java還是有以下一些區別的:

  • 其一當然是類型,JavaScript是無類型的語言,這使得對于對象的表示和屬性的訪問上比Java存在比較大的性能損失。不過現在有一些新的技術,參考C++或者Java的類型系統的優點,構建隱式的類型信息,這些后面逐一介紹。
  • 其二是Java語言通常是將源代碼編譯成字節碼,這個同執行階段是分開的,也就是從源代碼到抽象語法樹到字節碼這段時間的長短是無所謂的(或者說不是特別重要),所以主要是盡可能的生成高效的字節碼即可。而對于JavaScript而言,這些都是在網頁和JavaScript文件下載后同執行階段一起在網頁的加載和渲染過程中來實施的,所以對它們的處理時間也有著很高的要求。

描述JavaScript代碼執行的過程,這一過程中因為不同技術的引入,導致非常復雜,而且因為都是在代碼運行過程中來處理這些步驟,所以每個階段時間越少越好,而且每引入一個階段都是額外的時間開銷,可能最后的本地代碼執行效率很高,但是之前步驟如果耗費太多時間的話,最后的執行結果可能并不會好。所以不同的JavaScript引擎選擇了不同的路徑,這里先不仔細介紹,后面再描述它們。

所以一個JavaScript引擎不外乎包括以下部分:
第一, 編譯器。主要工作是將源代碼編譯成抽象語法樹,然后在某些引擎中還包含將抽象語法樹轉換成字節碼。
第二, 解釋器。在某些引擎中,解釋器主要是接受字節碼,解釋執行這個字節碼,然后也依賴來及回收機制等。
第三, JIT工具。一個能夠能夠JIT的工具,將字節碼或者抽象語法樹轉換成本地代碼,當然它也需要依賴牢記
第四, 垃圾回收器和分析工具(profiler)。它們負責垃圾回收和收集引擎中的信息,幫助改善引擎的性能和功效。

JavaScript引擎和渲染引擎

網頁的工作過程需要使用到兩個引擎,也就是渲染引擎和JavaScript引擎。從模塊上看,目前,它們是兩個獨立的模塊,分別負責不同的事情:JavaScript引擎負責執行JavaScript代碼,而渲染引擎負責渲染網頁。

JavaScript引擎提供調用接口被渲染引擎使用,渲染引擎使用JavaScript引擎來處理JavaScript代碼并獲取結果。這當然不是全部,事情不是這么簡單,JavaScript引擎需要能夠訪問渲染引擎構建的DOM樹,所以JavaScript引擎通常需要提供橋接的接口,而渲染引擎則根據橋接接口來提供讓JavaScript訪問DOM的能力。

在現在眾多的HTML5能力中,很多都是通過JavaScript接口提供給開發者的,所以這部分同樣需要根據橋接接口來實現具體類,以便讓JavaScript引擎能夠回調渲染引擎的具體實現。下圖是一個簡單的關于兩者引擎的關系。

Paste_Image.png

在WebKit/Blink項目中,這兩種引擎通過橋接接口來訪問DOM結構,這對性能來說是一個重大的損失,因為每次JavaScript代碼訪問DOM都需要通過復雜和低效的橋接接口來完成。鑒于訪問DOM樹的普遍性,這是一個常見的問題。希望以后可以減少這一方面的開銷。

JavaScriptCore引擎

JavaScriptCore引擎是WebKit中默認的引擎,在早期階段,它的性能不是特別突出。特別是,它只有解釋器來解釋執行JavaScript代碼。這一效率十分的低效,當然從2008年開始,JavaScriptCore引擎開始一個新的優化工作,就是重新實現了編譯器和字節碼解釋器,這就是SquirrelFish。該工作對于引擎的性能優化作了比較大的改進。隨后,蘋果內部代號為”Nitro”的JavaScript引擎也是基于JavaScriptCore項目的,它的性能還是非常出色的,鑒于其是內部項目,所以具體還有什么特別的處理就不得而知了。在這之后,開發者們又將內嵌緩存、基于正則表達式的JIT和簡單的JIT引入到JavaScriptCore中。然后,又陸續加入的字節碼解釋器??梢钥闯?,JavaScriptCore引擎也在不斷的高速發展中。

V8引擎

V8是Google的一個開源項目,現在成為了JavaScript引擎和眾多相關技術的引領者。它的目的很簡單,就是為了提高性能。因為之前不管JavaScriptCore引擎還是其它JavaScript引擎,在當時的情況下,它們的性能都不能令人非常滿意。為了達到高性能的JavaScript代碼執行效率從而獲得更好的網頁瀏覽效果,它甚至采用直接將JavaScript編譯成本地代碼的方式。

V8支持眾多的操作系統,包括但是不限于Windows、Linux、Android、Mac OS X等。同時它也是能夠支持眾多的硬件架構,例如IA32、X64、ARM、MIPS等。這么看下來,它將主流軟硬件平臺一網打盡,由于它是一個開源項目,開發者可以自由的使用它的強大能力,一個例子就是目前炙手可熱的NodeJS項目,它就是基于V8項目的。開源的好處就是大家可以很方便地學習、貢獻和使用,下圖是V8引擎最基礎的代碼執行過程。

V8

從圖中可以看出,首先它也是將源代碼轉變成抽象語法樹的,這一點同JavaScriptCore引擎一樣,之后兩個引擎開始分道揚鑣。不同于JavaScriptCore引擎,V8引擎并不將抽象語法樹轉變成字節碼或者其它中間表示,而是通過JIT編譯器的全代碼生成器(full code generator)從抽象語法樹直接生成本地代碼,所以沒有像Java一樣的虛擬機或者字節碼解釋器。

這樣做的原因,主要是因為減少這抽象語法樹到字節碼的轉換時間,這一切都在網頁加載時候完成,雖然可以提高優化的可能,但是這些分析可能帶來巨大的時間浪費。

當然,缺點也很明顯,至少包括兩點:

  • 第一是某些JavaScript使用場景其實使用解釋器更為合適,因為沒有必要生成本地代碼;
  • 第二是因為沒有中間表示,會減少優化的機會因為缺少一個中間表示層。

在之后的版本中,V8工程師們引入了Crankshaft編譯器,它能夠對熱點的JS函數進行分析和優化后再生成本地代碼,原因在于不是所有的JavaScript代碼都合適做如此深層次的優化,因為優化本身也需要花費一定的時間。

目前V8和JavaScriptCore引擎各有特色,相信兩者的發展能夠不斷推進JavaScript語言的執行性能。

本文參考http://blog.csdn.net/milado_nju/article/details/22101681

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,967評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,273評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,870評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,742評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,527評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,010評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,108評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,250評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,769評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,656評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,853評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,371評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,103評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,472評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,717評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,487評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,815評論 2 372

推薦閱讀更多精彩內容