[javascript] 루프 내에서 null 유형의 값이 변경되는 이유는 무엇입니까?

Chrome 콘솔에서이 스 니펫을 실행합니다.

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

1000 번 인쇄해야 false하지만 일부 컴퓨터 false에서는 여러 번 반복 한 다음 true나머지 를 인쇄 합니다 .

여기에 이미지 설명 입력

왜 이런 일이 발생합니까? 그냥 버그입니까?



답변

이에 대해 열려있는 크롬 버그가 있습니다.

문제 604033-JIT 컴파일러가 메서드 동작을 보존하지 않음

그래서 예 그것은 단지 버그입니다!


답변

실제로 V8 JavaScript 엔진 ( Wiki ) 버그입니다.

이 엔진은 Chromium, Maxthron, Android OS, Node.js 등에서 사용됩니다.

Reddit 주제 에서 찾을 수있는 비교적 간단한 버그 설명 :

최신 JavaScript 엔진은 JS 코드가 실행될 때 최적화 된 기계 코드로 컴파일됩니다 (Just In Time 컴파일). 그러나 최적화 단계에는 장기적인 속도 향상의 대가로 초기 성능 비용이 발생하므로 엔진은 방법이 얼마나 일반적으로 사용되는지에 따라 방법이 가치가 있는지 여부를 동적으로 결정합니다.

이 경우 최적화 된 경로에만 버그가있는 것처럼 보이지만 최적화되지 않은 경로는 제대로 작동합니다. 따라서 처음에는 메서드가 의도 한대로 작동하지만 어느 시점에서 충분히 자주 루프에서 호출되면 엔진이 최적화하기로 결정하고 버그가있는 버전으로 교체합니다.

이 버그는 V8 자체 ( commit ), Chromium ( bug report ) 및 NodeJS ( commit ) 에서 수정 된 것으로 보입니다 .


답변

변경 이유에 대한 직접적인 질문에 답하기 위해 버그는 Chrome에서 사용하는 V8 JS 엔진의 “JIT”최적화 루틴에 있습니다. 처음에는 코드가 작성된대로 정확하게 실행되지만 더 많이 실행할수록 최적화의 이점이 분석 비용을 능가 할 가능성이 더 커집니다.

이 경우 루프에서 반복 실행 된 후 JIT 컴파일러는 함수를 분석하여 최적화 된 버전으로 대체합니다. 불행히도 분석은 잘못된 가정을하고 최적화 된 버전은 실제로 올바른 결과를 생성하지 않습니다.

특히 Reddit 사용자 RainHappens는 유형 전파 오류 라고 제안 합니다 .

또한 일부 유형 전파를 수행합니다 (변수 등의 유형에서와 같이). 변수가 정의되지 않거나 null 인 경우 특수한 “감지 불가능”유형이 있습니다. 이 경우 옵티마이 저는 “null은 감지 할 수 없으므로 비교를 위해”정의되지 않은 “문자열로 바꿀 수 있습니다.

이것은 코드 최적화의 어려운 문제 중 하나입니다. 성능을 위해 재 배열 된 코드가 원본과 동일한 효과를 갖도록 보장하는 방법입니다.


답변

이 문제는 두 달 전에 수정되었으며 곧 Chrome에 출시 될 예정입니다 (이미 Canary에 있음).

V8 Issue 1912553002-크랭크 샤프트의 ‘typeof null’정규화 수정

Chromium 문제 604033-JIT 컴파일러가 메서드 동작을 보존하지 않음


답변