2012-09-29 12 views
5

Studiowałem źródło v8, szczególnie w tym, w jaki sposób narzędzie "mksnapshot" zawiera skompilowany obraz macierzystych plików javascript (runtime.js, json.js ...) w plikach binarnych w wersji 8 i zauważył, że zawiera również (nieco) zminimalizowana wersja źródła. Na przykład podczas sprawdzania zawartości pliku wykonywalnego d8, widzę następujący fragment:Dlaczego v8 zapisuje kod źródłowy macierzystego javascript w wygenerowanych plikach binarnych?

var $JSON=global.JSON; 

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

i na początku 'src/json.js' I See:

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; 

wyraźnie zarówno krótkich fragmentów są równoważne, ale druga została przekształcona w pierwszą w procesie kompilacji.

Zrozumiałbym, jeśli oryginalny kod został dołączony do kontroli za pomocą "toString", ale kiedy wpisuję "JSON.stringify" w d8, wszystko co widzę to "funkcja stringify() {[kod natywny]}", więc co czy to ma sens?

+0

Powinieneś zadać to pytanie podczas Google IO 2012 :) –

+0

Oto kilka moich spostrzeżeń na ten temat. Czy potrafisz zapisać wynik tego http://nodejs.org/api/vm.html#vm_vm_createscript_code_filename i uruchomić go po raz drugi? Kiedy kompilujesz nodejs, wydaje się, że nadal nie korzystamy z plików javascript, ponieważ nie mogę znaleźć ani zlokalizować ich gdziekolwiek poza źródłem. – Prospero

Odpowiedz

3

W rzeczywistości migawka nie zawiera wszystkich wbudowanych elementów w skompilowanym formularzu.

V8 ogólnie preferuje leniwą kompilację, aby zaoszczędzić miejsce i czas. Jeśli kompilujesz rzeczy, które nie są używane, tracisz pamięć na wygenerowany kod (a kod generowany przez niepoprawny kompilator jest dość "pełny") i czas (albo na kompilację, albo na deserializację, jeśli mówimy o migawce).

Wszystko, co potrafi skompilować leniwie V8, kompiluje się leniwie, włączając w to wbudowane. W związku z tym migawka faktycznie nie zawiera skompilowanych wersji dla wszystkich funkcji i źródło jest wymagane do skompilowania odpoczynku.

Inną rzeczą, która staje się możliwa, gdy źródło jest obecne, jest optymalizacja: V8 musi mieć dostęp do źródła, aby zastosować elastyczny algorytm optymalizacji.

+0

Więc jeśli uruchomię skrypt nodejs z dwiema funkcjami i tylko jedna zostanie użyta, druga nigdy nie zostanie skompilowana? Jaki plik w źródle mogę znaleźć więcej na temat tego leniwego zachowania kompilacji? –

+0

To zależy od wielu czynników, w najczęstszych przypadkach zostanie skompilowana tylko jedna używana funkcja. Możesz zacząć czytać kod w 'compiler.cc': http://code.google.com/p/v8/source/browse/trunk/src/compiler.cc?r=12566#935 –

+0

Miło, dzięki za że –

-1

Prawdopodobnie dlatego, że buforowanie pliku binarnego sprawia, że ​​v8 jest niesamowicie szybki: został zbudowany tak, aby był bardzo szybki. Podjęli więc ekstremalne kroki, aby zrobić to szybko. Wstępnie wygenerowane pliki binarne natywnego kodu odbierają myślenie od klienta, dzięki czemu działają znacznie szybciej. Istnieją optymalizacje takie jak to wszystko w wersji v8. :)

+0

To właśnie dlatego zadałem to pytanie. Jeśli już zapisują skompilowany kod maszynowy, dlaczego również zapisać źródło, które je wygenerowało? –

+0

Na wszelki wypadek, gdy dzieje się coś szalonego, a klient decyduje, że potrzebuje źródła. Przepustowość jest łatwa do zdobycia, szczególnie gdy możesz cache'ować rzeczy. v8 został napisany z myślą o szybkości, więc koszty związane z przepustowością zajęły tylne miejsce na szybszym silniku. – L0j1k