← All issues

[JSC] MapIterator / SetIterator should be handled in DFG

300fd8c

// Source/JavaScriptCore/builtins/MapIteratorPrototype.js: 제거됨.
// Source/JavaScriptCore/builtins/SetIteratorPrototype.js: 제거됨.
+ JSC::VM::fastMapKeysSentinel
+ JSC::VM::fastMapValuesSentinel
+ JSC::VM::fastSetEntriesSentinel
+ JSC::iteratorOpenTryFastImpl
+ JSC::iteratorNextTryFastImpl

JSC의 DFG는 관찰된 타입을 기반으로 speculative optimization을 수행합니다. "iterator를 DFG에서 처리한다"는 것은 IteratorOpenIteratorNext IR 노드를 생성하는 동작을 의미합니다. 이 노드들은 JS 함수 호출 방식을 거치지 않고, C++ fast-path 함수를 직접 호출하도록 낮춰집니다. 이 fast path는 watchpoint로 보호됩니다. Watchpoint는 약한 참조로, MapIteratorPrototype.nextMap.prototype[@@iterator] 같은 보호 대상 객체가 변경되면 즉시 발동하여 OSR-exit를 유발합니다.

이 commit은 MapIterator#next()SetIterator#next()를 builtin JavaScript에서 C++로 이동시켰습니다. 아울러 Map/Set 관련 여섯 가지 iteration 메서드 전체를 DFG의 first-class fast path로 연결했습니다. VM에는 세 가지 새로운 sentinel 값(fastMapKeysSentinel, fastMapValuesSentinel, fastSetEntriesSentinel)이 추가되었으며, iteration 모드 구분에 사용됩니다. 기존에는 next()가 JS 수준의 safety guarantee를 통해 실행되었지만, C++로 이동하면서 이 안전망이 제거되었습니다. 따라서 C++ 구현은 JS 버전이 자동으로 보장하던 모든 invariant를 직접 유지해야 합니다.

이번 변경으로 JIT fast-path가 대규모로 추가되었습니다. 새로운 C++ iterator state machine, DFG IR 노드, watchpoint guard, cross-realm check가 한 번에 도입되었습니다. 각 레이어 모두 type confusion, lifetime 버그, 또는 guard bypass의 잠재적 원인이 될 수 있습니다.

🔒

New JIT-generated code for security-critical iterator operations — several edge cases in the fast path and its guards are worth audit investigation.

더 확인하려면 구독해 주세요