Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

186
Vistas
¿V8 supervisa la ejecución del código de máquina optimizado?

AFAIK, hay aproximadamente dos tipos de objetos de código en V8. Uno es el código de bytes de javascript interpretado por Ignition, y el otro es un código de máquina compilado y optimizado por Turbofan. De acuerdo con la ejecución/frames.h , V8 construye un marco de pila diferente para cada tipo de objeto de código. Significa que V8 debe conocer el tipo de callee antes de ejecutarlo.

Cuando el código no optimizado (JS Bytecode) llama al optimizado, supongo que Ignition podría manejar el caso correctamente para construir un nuevo stackframe para uno optimizado. Sin embargo, cuando el código optimizado (código de máquina) llama al no optimizado, tengo curiosidad acerca de cómo V8 determina si callee de la llamada no está optimizado o no. Si el código de la máquina se ejecuta directamente en el procesador, nada puede ayudar a V8 a determinar el tipo de callee .

Además, según tengo entendido, V8 debería detectar si alguna dependencia del código se ve comprometida para marcar o desoptimizar los objetos de código invalidados. También parece inviable si V8 no supervisa la ejecución del código de máquina.

Entonces mi pregunta es:

  1. ¿V8 supervisa la ejecución del código de máquina (optimizado)? Si es así, ¿cómo sucede?

  2. Si 1 es falso, entonces, ¿cómo verifica V8 la invalidación de la dependencia del código o detecta si el callee está compilado o no?

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

(Desarrollador V8 aquí.)

V8 construye un marco de pila diferente para cada tipo de objeto de código. Significa que V8 debe conocer el tipo de destinatario antes de ejecutarlo.

Los marcos de pila los configura quien los necesita, por lo que las personas que llaman no tienen que inspeccionar a los destinatarios de las llamadas. (Podrían, si tuvieran que hacerlo).

Si el código de la máquina se ejecuta directamente en el procesador, nada puede ayudar a V8 a determinar el tipo de destinatario.

V8 podría emitir un código de máquina que verifica el tipo de destinatario. Pero para repetirme: no es necesario conocer el estado de optimización de un destinatario.

¿V8 supervisa la ejecución del código de máquina (optimizado)?

No, no lo hace.

¿Cómo comprueba V8 la invalidación de la dependencia del código?

Las dependencias se instalan en algo que puede cambiar (por ejemplo, mapas, protectores). Cuando ocurra ese cambio, las dependencias del código registrado se desoptimizarán (es decir, se marcarán como "desoptimización perezosa" cuando tengan activaciones en la pila, o simplemente se descartarán de lo contrario).

[¿Cómo detecta V8] si el destinatario está compilado o no?

No es necesario. Cuando una función aún no está compilada, su "código" será un código auxiliar que activa la compilación.

about 4 years ago · Juan Pablo Isaza Denunciar

0

Para ver el ejemplo concreto que diste en los comentarios:

 var b = false; function change_o() { // as long as b is false, this won't be reassigned ... if (b) o = { y : 1, x : 0}; } var o = { x : 1 }; function f() { change_o(); // ... and thus ox can be compiled down return ox; } // f and change_o are compiled somewhen f(); f(); f(); // ... // a precondition changes b = true; // during execution of change_o o is reassigned and changes its shape, accessing ox will now need a different offset and thus f (which is currently on the stack) becomes invalid f();

Por lo tanto, en el momento en que ocurre la asignación o = , el tiempo de ejecución salta a alguna lógica de desoptimización, que tiene que invalidar todo el código en función de la suposición falsa. Invalidar llamadas de código no compilado a código compilado es fácil, simplemente elimine la referencia al código compilado de algún tipo de registro y nadie volverá a llamarlo. Invalidar llamadas futuras de funciones compiladas a la función compilada invalidada es más difícil, aunque si la llamada utiliza alguna indirección, esta indirección se puede reescribir para redirigir todas las llamadas futuras. Esto deja dos tipos de problemas de invalidación:

  • la función evaluada actualmente debe ser invalidada (-> desoptimización ansiosa), tampoco es tan problemático ya que es la función que rescató a la rutina de desoptimización
  • una función que llamó a la función evaluada debe ser invalidada (-> desoptimización diferida), esto es problemático, ya que podría estar en algún lugar de la pila, y la ejecución continua se reanudaría en algún momento (por ejemplo, f en el ejemplo anterior)

Sin embargo, en el último caso, hay una manera de encontrar y reemplazar esas funciones: cada vez que una función call a otra, empuja la dirección de retorno a la pila (ver, por ejemplo, el uso de la pila x86 ), y cuando la función llamada ejecuta el ret instrucción, aparece la dirección y salta allí. Por lo tanto, al escanear la pila en busca de direcciones de retorno que residen dentro de funciones invalidadas y reemplazarlas por otra dirección, cuando la función interna como change_o regresa a f , en realidad no salta de regreso al código f compilado sino a un controlador, que luego puede hacer los ajustes necesarios.

Entonces V8 no "supervisa" la ejecución, la modifica activamente cuando es necesario reescribiendo la pila.

Puede encontrar un tutorial detallado aquí .

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda