Menjalankan cuplikan ini di konsol Chrome:
function foo() {
return typeof null === 'undefined';
}
for(var i = 0; i < 1000; i++) console.log(foo());
harus mencetak 1000 kali false
, tetapi pada beberapa mesin akan mencetak false
untuk beberapa iterasi, kemudian true
sisanya.
Mengapa ini terjadi? Apakah ini hanya bug?
javascript
v8
Agos
sumber
sumber
false
. sebagaimana adanya, jumlahtrue
s berfluktuasi di chrome.Jawaban:
Ada bug kromium yang terbuka untuk ini:
Masalah 604033 - kompiler JIT tidak mempertahankan perilaku metode
Jadi ya, itu hanya bug!
sumber
Ini sebenarnya adalah mesin JavaScript V8 ( Wiki bug ).
Mesin ini digunakan di Chromium, Maxthron, Android OS, Node.js dll.
Deskripsi bug yang relatif sederhana dapat Anda temukan di topik Reddit ini :
Bug ini tampaknya telah diperbaiki di V8 itu sendiri ( commit ), juga di Chromium ( laporan bug ) dan NodeJS ( commit ).
sumber
Untuk menjawab pertanyaan langsung mengapa itu berubah, bug tersebut ada dalam rutinitas pengoptimalan "JIT" dari mesin V8 JS yang digunakan oleh Chrome. Pada awalnya, kode dijalankan persis seperti yang tertulis, tetapi semakin sering Anda menjalankannya, semakin besar potensi manfaat pengoptimalan yang melebihi biaya analisis.
Dalam kasus ini, setelah eksekusi berulang dalam loop, kompilator JIT menganalisis fungsi tersebut, dan menggantinya dengan versi yang dioptimalkan. Sayangnya, analisis membuat asumsi yang salah, dan versi yang dioptimalkan sebenarnya tidak memberikan hasil yang benar.
Secara khusus, pengguna Reddit RainHappens menyarankan bahwa ini adalah kesalahan dalam jenis propagasi :
Ini adalah salah satu masalah sulit dengan pengoptimalan kode: bagaimana menjamin bahwa kode yang telah diatur ulang untuk kinerja akan tetap memiliki efek yang sama seperti aslinya.
sumber
Ini telah diperbaiki dua bulan lalu dan akan segera mendarat di Chrome (sudah ada di Canary).
Masalah V8 1912553002 - Perbaiki kanonikalisasi 'typeof null' di crankshaft
Masalah Chromium 604033 - Penyusun JIT tidak mempertahankan perilaku metode
sumber