2012-09-29 32 views
5

我一直在研究v8源代碼,特別是'mksnapshot'工具如何在v8二進制文件中包含原生JavaScript文件(runtime.js,json.js ...)的編譯後圖像,並注意到它還包含一個(稍微)縮小版本的源代碼。例如,檢查D8可執行文件的內容時,我看到下面的代碼片斷:爲什麼v8會在生成的二進制文件中保存原生javascript的源代碼?

var $JSON=global.JSON; 

function Revive(a,b,c){ 
var d=a[b]; 
if((%_IsObject(d))){ 
if((%_IsArray(d))){ 
var g=d.length; 

和在「SRC/json.js」我看到的開始:

var $JSON = global.JSON; 

function Revive(holder, name, reviver) { 
    var val = holder[name]; 
    if (IS_OBJECT(val)) { 
    if (IS_ARRAY(val)) { 
     var length = val.length; 

明確兩者片段是相當的,但第二個在編譯過程中轉化爲第一個。

我會理解,如果包含原始代碼用'toString'進行檢查,但是當我在d8中輸入'JSON.stringify'時,我所看到的只是'function stringify(){[native code]}'這是關鍵嗎?

+0

您應該在Google IO 2012期間提出此問題:) –

+0

以下是我對此主題的一些觀察結果。你可以如何保存這個http://nodejs.org/api/vm.html#vm_vm_createscript_code_filename的輸出並在後期運行它?當你編譯nodejs時,它似乎還沒有使用JavaScript文件,因爲我找不到它們,或者在源代碼中找不到它們。 – Prospero

回答

3

實際上,快照並不包含編譯後的所有內置函數。

V8通常寧願延遲編譯以節省空間和時間。如果你編譯的東西沒有被使用,那麼你浪費了生成代碼的內存(並且由非優化編譯器生成的代碼相當「冗長」)和時間(如果我們正在討論快照,則在編譯或反序列化時)。

因此,它可以編譯的所有事情,懶惰地編譯V8確實編譯,這包括內置。因此,快照實際上並不包含所有函數的編譯版本,編譯rest需要source。

當源存在時,另一件可能的事情就是優化:V8必須有權訪問源以應用其自適應優化管道。

+0

所以,如果我運行一個nodejs腳本有兩個功能,只有一個被使用,另一個將永遠不會被編譯?我可以在源文件中找到更多關於這種惰性編譯行爲的文件? –

+0

這取決於很多因素,在大多數情況下只會編譯一個使用過的函數。您可以從'compiler.cc'開始閱讀代碼: http://code.google.com/p/v8/source/browse/trunk/src/compiler.cc?r=12566#935 –

+0

不錯,謝謝那 –

-1

可能是因爲緩存二進制文件使得v8的速度非常快:它的構建速度非常快。所以他們採取了極端的措施來加快速度。預生成的本機代碼二進制文件帶走了客戶端的思想,使其運行速度更快。有像這樣的優化,所有的V8。 :)

+0

那正是我提出這個問題的原因。如果他們已經保存了編譯好的機器碼,爲什麼還要保存生成它的源碼? –

+0

只是萬一有什麼瘋狂的事情發生,客戶決定它需要來源。帶寬很容易得到,尤其是當您可以緩存內容時。第8版的編寫速度非常快,因此帶寬成本讓後座成爲更快的引擎。 – L0j1k

相關問題