Wykonywanie tego fragmentu kodu w konsoli Chrome:
function foo() {
return typeof null === 'undefined';
}
for(var i = 0; i < 1000; i++) console.log(foo());
powinien drukować 1000 razy false
, ale na niektórych komputerach będzie drukować false
przez kilka iteracji, a potem true
przez resztę.
Dlaczego to się dzieje? Czy to tylko błąd?
javascript
v8
Agos
źródło
źródło
false
. tak jak jest, liczbatrue
s waha się w chromie.Odpowiedzi:
W tym celu jest otwarty błąd chromu:
Problem 604033 - kompilator JIT nie zachowuje zachowania metody
Więc tak, to tylko błąd!
źródło
W rzeczywistości jest to błąd silnika JavaScript V8 ( Wiki ).
Ten silnik jest używany w Chromium, Maxthron, Android OS, Node.js itp.
Względnie prosty opis błędu można znaleźć w tym temacie na Reddicie :
Wydaje się, że ten błąd został naprawiony w samym V8 ( zatwierdzenie ), a także w Chromium ( zgłoszenie błędu ) i NodeJS ( zatwierdzenie ).
źródło
Aby odpowiedzieć na bezpośrednie pytanie, dlaczego to się zmienia, błąd tkwi w procedurze optymalizacji „JIT” silnika V8 JS używanego przez Chrome. Na początku kod jest uruchamiany dokładnie tak, jak został napisany, ale im częściej go uruchamiasz, tym większy potencjał korzyści z optymalizacji przewyższają koszty analizy.
W takim przypadku po powtórnym wykonaniu w pętli kompilator JIT analizuje funkcję i zastępuje ją wersją zoptymalizowaną. Niestety analiza przyjmuje błędne założenie, a zoptymalizowana wersja w rzeczywistości nie daje poprawnego wyniku.
W szczególności użytkownik Reddit RainHappens sugeruje , że jest to błąd w propagacji typu :
Jest to jeden z poważnych problemów z optymalizacją kodu: jak zagwarantować, że kod, który został zmieniony pod kątem wydajności, będzie nadal miał taki sam efekt jak oryginał.
źródło
Zostało to naprawione dwa miesiące temu i wkrótce wyląduje w Chrome (już w wersji Canary).
V8 Issue 1912553002 - Fix „typeof null” canonicalization in the crankshaft
Chromium Problem 604033 - kompilator JIT nie zachowuje zachowania metody
źródło