Why does the value of typeof null change inside a loop?

JavascriptV8

Javascript Problem Overview


Executing this snippet in the Chrome console:

function foo() {
    return typeof null === 'undefined';
}
for(var i = 0; i < 1000; i++) console.log(foo());

should print 1000 times false, but on some machines will print false for a number of iterations, then true for the rest.

enter image description here

Why is this happening? Is it just a bug?

Javascript Solutions


Solution 1 - Javascript

There is a chromium bug open for this:

Issue 604033 - JIT compiler not preserving method behavior

So yes It's just a bug!

Solution 2 - Javascript

It's actually a V8 JavaScript engine (Wiki) bug.

This engine is used in Chromium, Maxthron, Android OS, Node.js etc.

Relatively simple bug description you can find in this Reddit topic: > Modern JavaScript engines compile JS code into optimized machine code > when it is executed (Just In Time compilation) to make it run faster. > However, the optimization step has some initial performance cost in > exchange for a long term speedup, so the engine dynamically decides > whether a method is worth it depending on how commonly it is used. > > In this case there appears to be a bug only in the optimized path, > while the unoptimized path works fine. So at first the method works as > intended, but if it's called in a loop often enough at some point the > engine will decide to optimize it and replaces it with the buggy > version.

This bug seems to have been fixed in V8 itself (commit), aswell as in Chromium (bug report) and NodeJS (commit).

Solution 3 - Javascript

To answer the direct question of why it changes, the bug is in the "JIT" optimisation routine of the V8 JS engine used by Chrome. At first, the code is run exactly as written, but the more you run it, the more potential there is for the benefits of optimisation to outweigh the costs of analysis.

In this case, after repeated execution in the loop, the JIT compiler analyses the function, and replaces it with an optimised version. Unfortunately, the analysis makes an incorrect assumption, and the optimised version doesn't actually produce the correct result.

Specifically, Reddit user RainHappens suggests that it is an error in type propagation:

> It also does some type propagation (as in what types a variable etc can be). There's a special "undetectable" type for when a variable is undefined or null. In this case the optimizer goes "null is undetectable, so it can be replaced with the "undefined" string for the comparison.

This is one of the hard problems with optimising code: how to guarantee that code which has been rearranged for performance will still have the same effect as the original.

Solution 4 - Javascript

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAgosView Question on Stackoverflow
Solution 1 - JavascriptSlumber86View Answer on Stackoverflow
Solution 2 - JavascriptSergey NovikovView Answer on Stackoverflow
Solution 3 - JavascriptIMSoPView Answer on Stackoverflow
Solution 4 - Javascriptuser835611View Answer on Stackoverflow