[JSC] DFG iterator_next should dispatch fast modes by iterator type
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
- Node* hasNext = addToGraph(IsEmpty, get(bytecode.m_next));
+ Node* isEmpty = addToGraph(IsEmpty, get(bytecode.m_next));
+ Node* isArrayIterator = addToGraph(IsCellWithType, OpInfo(JSArrayIteratorType), get(bytecode.m_iterator));
+ Node* andResult = addToGraph(ArithBitAnd, isEmpty, isArrayIterator);
+ m_exitOK = true;
+ addToGraph(ExitOK);
+ ...
- addToGraph(Branch, OpInfo(branchData), hasNext);
+ addToGraph(Branch, OpInfo(branchData), andResult);
이전 변경에서 seenModes가 여러 fast mode를 동시에 보유할 수 있도록 허용되었습니다. 그러나 기존의 branch 조건은 IsEmpty(m_next) 단독이었고, 이 조건은 모든 fast mode에서 참이 됩니다. 그 결과 Map 및 Set iterator도 FastArray block에 진입한 뒤 해당 블록의 CheckStructure에서 즉시 OSR exit하는 상황이 발생했습니다. 이번 수정에서는 IsEmpty(m_next)와 IsCellWithType(iterator, JSArrayIteratorType) (또는 JSMapIteratorType / JSSetIteratorType)을 AND 연산하는 방식으로 변경되었습니다. 이미 handleIteratorOpen에서 사용 중인 패턴과 동일한 방식입니다.
Significance
Array/Map 및 Array/Set 혼합 for-of loop에서 조용히 발생하던 deoptimization을 수정하여 2.5~2.8배의 속도 향상을 복원합니다. DFG의 multi-mode fast-path dispatcher에서의 correctness 수정입니다.