2012-09-29 25 views
5

He estado estudiando la fuente v8, particularmente en cómo la herramienta 'mksnapshot' incluye una imagen compilada de los archivos javascript nativos (runtime.js, json.js ...) en los binarios de v8 y notó que también incluye una versión (un tanto) minimizada de la fuente. Por ejemplo, al inspeccionar el contenido del archivo ejecutable d8, veo el siguiente fragmento:¿Por qué v8 guarda el código fuente de javascript nativo en binarios generados?

var $JSON=global.JSON; 

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

y al inicio de la 'src/json.js -Veo:

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; 

claramente tanto de fragmentos son equivalentes, pero el segundo se transformó en el primero en el proceso de compilación.

Hubiera entendido si el código original se incluyó para inspeccionar con 'toString' pero cuando ingreso 'JSON.stringify' en d8 todo lo que veo es 'function stringify() {[native code]}', entonces qué es el punto de esto?

+0

Deberías haber hecho esta pregunta durante Google IO 2012 :) –

+0

Aquí hay algunas de mis observaciones sobre este tema. ¿Puede alguna forma guardar el resultado de este http://nodejs.org/api/vm.html#vm_vm_createscript_code_filename y ejecutarlo en un momento posterior? Cuando compila nodejs, parece que todavía no usa los archivos javascript ya que no puedo encontrarlos ni localizarlos en ningún lugar, excepto en la fuente. – Prospero

Respuesta

3

En realidad, la instantánea no incluye todos los builtin en el formulario compilado.

V8 en general prefiere la compilación perezosa para ahorrar espacio y tiempo. Si compila cosas que no se usan, se desperdicia memoria para el código generado (y el código generado por un compilador no optimizador es bastante "detallado") y el tiempo (ya sea en la compilación o en la deserialización si estamos hablando de instantáneas).

Por lo tanto, todo lo que se puede compilar perezosamente V8 se compila de forma perezosa y esto incluye instrucciones internas. Por lo tanto, la instantánea en realidad no contiene versiones compiladas para todas las funciones y la fuente es necesaria para compilar el resto.

Otra cosa que es posible cuando la fuente está presente es la optimización: V8 tiene que tener acceso a la fuente para aplicar su canal de optimización adaptativa.

+0

Entonces, si ejecuto un script nodejs con dos funciones y solo se usa uno, ¿el otro nunca se compilará? ¿Qué archivo en la fuente podría encontrar más acerca de este comportamiento de compilación perezoso? –

+0

Eso depende de muchos factores, en la mayoría de los casos comunes solo se compilará una función utilizada. Puede comenzar a leer el código en 'compiler.cc': http://code.google.com/p/v8/source/browse/trunk/src/compiler.cc?r=12566#935 –

+0

Bien, gracias por ese –

-1

Probablemente porque el almacenamiento en caché del binario es lo que hace que v8 sea increíblemente rápido: fue creado para ser muy rápido. Entonces han tomado medidas extremas para hacerlo rápido. Los binarios pregenerados de código nativo le quitan el pensamiento al cliente y lo hacen funcionar mucho más rápido. Hay optimizaciones como esta en todo v8. :)

+0

Eso es exactamente por lo que hice esta pregunta. Si ya guardan el código de máquina compilado, ¿por qué también guardar la fuente que lo generó? –

+0

Por si acaso hay algo loco y el cliente decide que necesita la fuente. El ancho de banda es fácil de obtener, especialmente cuando puedes almacenar cosas en caché. v8 se escribió con la velocidad en mente, por lo que los costos de ancho de banda tomaron el asiento trasero a un motor más rápido. – L0j1k

Cuestiones relacionadas