Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bug with typeof null in JS V8 engine [duplicate]

Tags:

javascript

v8

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?

like image 801
Agos Avatar asked Jun 21 '16 08:06

Agos


3 Answers

There is a chromium bug open for this:

Issue 604033 - JIT compiler not preserving method behavior

So yes It's just a bug!

like image 114
Slumber86 Avatar answered Oct 21 '22 06:10

Slumber86


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).

like image 42
Sergey Novikov Avatar answered Oct 21 '22 05:10

Sergey Novikov


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.

like image 18
IMSoP Avatar answered Oct 21 '22 07:10

IMSoP