剛才還是忍不住到V8的官網讀了些文檔,想看看到底它的技術特點是什么。
V8官網:Google V8 JavaScript Engine
設計概念的文檔:Design Elements
有人初試V8的經過:http://d.hatena.ne.jp/amachang/20080903/1220405193
V8是BSD許可證的,比較自由,方便用在各種項目中。
它是一個相當快的JavaScript實現。根據其設計概念的文檔,它的高性能主要來自:
其中前兩點應該是緊密相關聯的。在JavaScript引擎的實現中,V8特別就特別在“隱藏類”(hidden class)的使用。Hidden class的概念可以到那篇文檔去看,解釋得比較生動。簡單來說,對于某個對象,每次屬性的數量(或類型?這個得回頭仔細研究下)發生改變時,虛擬機就會新創建一個對應的隱藏類,記錄下其中各個屬性的相對偏移量,并將原本的隱藏類與新的隱藏類之間建立一個關聯。當再次有同一類型的對象創建時則不會重復創建隱藏類,而能復用前面已經出現的隱藏類。
其它JavaScript引擎(以及許多其它腳本語言的實現)一般使用某種形式的關聯容器來儲存所有變量;通常叫字典,也會被稱為映射表或者關聯數組,典型的實現方式是哈希表或者紅黑樹等。對象中的成員變量(下面將稱為“屬性”)一般也是這樣與某個對象關聯在一起的。訪問某個對象的某個屬性時就需要動態查詢這樣的關聯容器,是不可忽視的開銷。
V8則不使用關聯容器來儲存屬性,而是采用更接近于靜態編譯的類的形式,將對象中每個屬性的相對偏移量記下來,在生成機器碼時直接把偏移量寫到指令中。這樣,訪問某個對象的某個屬性就只需要很少量的指令就能完成,比起關聯容器的方式高效許多。
V8使用動態機器碼生成,先把要執行的JavaScript代碼直接編譯為機器碼,而不使用字節碼也不通過解釋的方式來執行。這樣在執行一些被大量重讀執行的代碼時效果會特別好。與之相對,Apple Webkit的JavaScriptCore/
SquirrelFish是先將JavaScript編譯到字節碼,然后以純解釋的方式執行字節碼;Mozilla/Adobe的
Tamarin則是先將JavaScript編譯到字節碼,然后以即時編譯(JIT)的方式執行。SquirrelFish與Tamarin的字節碼設計思路又不一樣:前者是基于寄存器的,而后者是基于棧的。一般認為基于寄存器形式的字節碼比較快,而基于棧形式的字節碼比較小,總之也是各有特點。
與“隱藏類”相關的是,V8會預先猜測某段代碼中的對象對應的隱藏類,如果命中的話就能直接用已經生成到機器碼里的偏移量;如果沒有命中,則使用實際的隱藏類中的信息來修改已生成的機器碼。這樣,如果多次執行中對象的“實際類型”都與猜測一樣,執行速度就可以非常的快。
Mozilla的新JavaScript執行引擎,TraceMonkey則通過別的方式來提高執行速度。通過記錄代碼執行的路徑,當發現某條執行路徑回到了某個早先經過的節點,就發現了一個“trace”;然后對trace花時間做重點優化,編譯為高效的機器碼。與HotSpot JVM不同的是,trace不是以函數(或者說方法)為單位的,可以在更小的范圍內做精確的優化,減少不必要的優化開銷。
在垃圾收集器方面,V8采用的是一個兩代的分代式準確垃圾收集器。相對的,JavaScriptCore的GC繼承自KJS,沒記錯的話是一個沒有分代的準確M&S式(mark-and-sweep)垃圾收集器;Tamarin使用的則是Adobe提供的
MMgc,主要算法是“延遲的引用計數”(DRC,Deffered Reference Counting),外加增量式保守M&S的垃圾收集器。這三種實現方式各有特點,實際效果要比較起來恐怕比較難。準確式的垃圾收集器必須知道堆的位置和布局,所以難以做成通用的;保守式收集器則可以做得很通用,著名的
Boehm GC是個典型的例子。但保守式收集器有潛在的內存泄漏的危險,因為可能會把并不是對象指針的數據識別為指針,使本來應該已經可以釋放的空間無法被釋放。
===========================================================================
V8中使用了下列第三方庫:
引用
- Jscre, located under third_party/jscre. This code is copyrighted
by the University of Cambridge and Apple Inc. and released under a
2-clause BSD license.
- Dtoa, located under third_party/dtoa. This code is copyrighted by
David M. Gay and released under an MIT license.
- Strongtalk assembler, the basis of the files assembler-arm-inl.h,
assembler-arm.cc, assembler-arm.h, assembler-ia32-inl.h,
assembler-ia32.cc, assembler-ia32.h, assembler.cc and assembler.h.
This code is copyrighted by Sun Microsystems Inc. and released
under a 3-clause BSD license.
Jscre我沒怎么聽說過,不知道跟PCRE(Perl Compatible Regular Expressions)的關系是怎樣的。在Jscre源碼的目錄里看到了"pcre"的字樣,不過詳細情況還是以后再看看好了。Apple Webkit里的JavaScriptCore應該是直接用了PCRE的吧?還是說我看漏了……
===========================================================================
今天Mozilla方面也沒忘記對Chrome/V8的發布作出反應。Brendan Eich,JavaScript的創始者,在其blog上發表了一篇相關評論:
Brendan Eich: TraceMonkey Update
Brendan Eich 寫道
(向右多的是TraceMonkey比較快,向左多的是V8比較快)
可以看到在Brendan做的SunSpider測試中,TraceMonkey在遞歸密集的程序中速度會比V8慢許多,而在正則表達式等方面則比V8快。據Brendan稱,TraceMonkey的開發時間還不長,遞歸方面的trace還沒多少進度,所以在這部分是比較慢的。但下一步將會解決這個問題。