2012-09-29 12 views
5

Ich habe die v8-Quelle studiert, vor allem, wie das "mksnapshot" -Tool ein kompiliertes Bild der nativen Javascript-Dateien (runtime.js, json.js ...) in den v8-Binärdateien enthält und bemerkte, dass es auch beinhaltet eine (etwas) verkleinerte Version der Quelle. Wenn zum Beispiel des Inhalts des d8 ausführbaren Inspektion, ich sehe den folgenden Ausschnitt:Warum speichert v8 den Quellcode von nativem JavaScript in generierten Binärdateien?

var $JSON=global.JSON; 

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

und zu Beginn der ‚src/json.js‘ Ich sehe:

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; 

eindeutig beiden Schnipsel sind gleichwertig, aber die zweite wurde in die erste im Kompilierungsprozess umgewandelt.

Ich hätte verstanden, wenn der ursprüngliche Code für die Untersuchung mit 'toString' enthalten war, aber wenn ich 'JSON.stringify' in d8 eingeben, sehe ich nur 'Funktion stringify() {[native code]}', also was ist der Sinn dieses?

+0

Sie sollten diese Frage während Google IO 2012 gestellt haben :) –

+0

Hier sind einige meiner Beobachtungen zu diesem Thema. Kannst du die Ausgabe von http://nodejs.org/api/vm.html#vm_vm_createscript_code_filename speichern und zu einem späteren Zeitpunkt ausführen? Wenn Sie Nodejs kompilieren, scheint es die JavaScript-Dateien immer noch nicht zu verwenden, da ich sie nirgendwo außer in der Quelle finden oder finden kann. – Prospero

Antwort

3

Eigentlich Snapshot enthält nicht alle Builtins in der kompilierten Form.

V8 im Allgemeinen bevorzugt faule Kompilierung, um Platz und Zeit zu sparen. Wenn Sie Dinge kompilieren, die nicht verwendet werden, verschwenden Sie Speicher für generierten Code (und Code, der von einem nicht optimierenden Compiler generiert wird, ist ziemlich "ausführlich") und Zeit (entweder beim Kompilieren oder bei der Deserialisierung, wenn wir über Snapshot sprechen).

Also alles, was es faul kompilieren kann kompiliert V8 kompiliert und das beinhaltet Builtins. Daher enthält der Snapshot keine kompilierten Versionen für alle Funktionen und die Quelle wird benötigt, um den Rest kompilieren zu können.

Eine andere Sache, die möglich wird, wenn die Quelle vorhanden ist, ist die Optimierung: V8 muss Zugriff auf die Quelle haben, um seine adaptive Optimierungspipeline anzuwenden.

+0

Also, wenn ich ein Nodejs-Skript mit zwei Funktionen ausführen und nur eine verwendet wird, wird die andere nie kompiliert werden? Welche Datei in der Quelle konnte ich mehr über dieses träge Kompilierungsverhalten finden? –

+0

Das hängt von vielen Faktoren ab, in den meisten Fällen wird nur eine verwendete Funktion kompiliert. Sie können Code in 'compiler.cc' lesen: http://code.google.com/p/v8/source/browse/trunk/src/compiler.cc?r=12566#935 –

+0

Nizza, danke für Das –

-1

Wahrscheinlich, weil das Zwischenspeichern der Binärdatei das v8 so unglaublich schnell macht: Es wurde gebaut, um sehr schnell zu sein. Sie haben also extreme Schritte unternommen, um es schnell zu machen. Vorgenerierte Binärdateien von nativem Code nehmen dem Kunden das Denken ab und lassen ihn so viel schneller laufen. Es gibt solche Optimierungen auf v8. :)

+0

Genau deshalb habe ich diese Frage gestellt. Wenn sie den kompilierten Maschinencode bereits speichern, warum auch die Quelle speichern, die sie generiert hat? –

+0

Nur für den Fall, dass etwas Irrsinniges vor sich geht und der Klient entscheidet, dass er die Quelle braucht. Bandbreite ist leicht zu bekommen, besonders wenn Sie Dinge zwischenspeichern können. v8 wurde im Hinblick auf Geschwindigkeit geschrieben, so dass die Bandbreitenkosten zu einem schnelleren Motor wurden. – L0j1k