Ejecutando este fragmento en la consola de Chrome:
function foo() {
return typeof null === 'undefined';
}
for(var i = 0; i < 1000; i++) console.log(foo());
debería imprimir 1000 veces false
, pero en algunas máquinas se imprimirá false
para varias iteraciones, luego true
para el resto.
¿Por qué está pasando esto? ¿Es solo un error?
javascript
v8
Agos
fuente
fuente
false
. tal cual, el número detrue
s fluctúa en Chrome.Respuestas:
Hay un error de cromo abierto para esto:
Problema 604033: el compilador JIT no conserva el comportamiento del método
Así que sí, ¡es solo un error!
fuente
En realidad, es un error del motor V8 JavaScript ( Wiki ).
Este motor se utiliza en Chromium, Maxthron, Android OS, Node.js, etc.
Puede encontrar una descripción de error relativamente simple en este tema de Reddit :
Este error parece haberse solucionado en la propia V8 ( confirmación ), así como en Chromium ( informe de error ) y NodeJS ( confirmación ).
fuente
Para responder a la pregunta directa de por qué cambia, el error está en la rutina de optimización "JIT" del motor V8 JS utilizado por Chrome. Al principio, el código se ejecuta exactamente como está escrito, pero cuanto más lo ejecuta, más posibilidades hay de que los beneficios de la optimización superen los costos del análisis.
En este caso, después de la ejecución repetida en el bucle, el compilador JIT analiza la función y la reemplaza con una versión optimizada. Desafortunadamente, el análisis hace una suposición incorrecta y la versión optimizada no produce el resultado correcto.
Específicamente, el usuario de Reddit RainHappens sugiere que se trata de un error en la propagación de tipos :
Este es uno de los problemas difíciles con la optimización del código: cómo garantizar que el código que se ha reorganizado para el rendimiento seguirá teniendo el mismo efecto que el original.
fuente
Esto se solucionó hace dos meses y pronto llegará a Chrome (ya en Canary).
V8 Issue 1912553002 - Se corrigió la canonicalización de 'tipo de nulo' en el cigüeñal
Chromium Issue 604033: el compilador JIT no conserva el comportamiento del método
fuente