← All issues

[JSC] Add foundation of handling builtin iterators in fast-iteration-protocol

3d1bebd

// Source/JavaScriptCore/runtime/VM.h
+ JSValue fastArrayValuesSentinel()  const { return m_fastArrayValuesSentinel.get(); }
+ JSValue fastArrayKeysSentinel()    const { return m_fastArrayKeysSentinel.get(); }
+ JSValue fastArrayEntriesSentinel() const { return m_fastArrayEntriesSentinel.get(); }

JSC의 bytecode에는 op_iterator_openop_iterator_next가 포함되어 있습니다. built-in iterator(예: Array의 @@iterator)가 인식되면, baseline JIT와 DFG는 이를 fast-path로 처리합니다. 기존에는 fast path가 'FastArray'(values) 모드 하나만 지원했습니다. 두 opcode 사이에는 빈 JS 값이 sentinel로 전달되었는데, DFG는 이를 fast path 활성화 여부를 확인하는 용도로만 활용했습니다.

이 commit에서는 VM 수준의 새로운 heap 객체인 JSSentinel을 도입했습니다. op_iterator_openop_iterator_next 사이에서 iterator kind(values/keys/entries)를 전달하는 역할을 담당합니다. 기존의 빈 값 sentinel은 VM에 저장된 typed JSSentinel singleton(kind별로 하나씩)으로 교체되었습니다. 덕분에 DFG/FTL은 values 외에도 FastArrayKeysFastArrayEntries에 대해 특화된 inline 코드를 생성할 수 있게 되었고, 14–37%의 성능 향상이 달성되었습니다. TypedArray는 ArrayIteratorPrototype을 공유하며 의도적으로 제외되었습니다. 이후 FastTypedArrayXXX 확장에서 별도로 처리될 예정입니다.

이번 변경은 아키텍처 수준의 토대가 되는 변화입니다. iterator kind를 iterator 객체 자체로부터 분리함으로써, JS heap 객체를 건드리지 않고도 DFG가 keys와 entries를 특화 처리할 수 있게 됩니다. 아울러 JS 측의 ArrayIterator#next, MapIterator#next, SetIterator#next builtin을 C++/DFG 구현으로 완전히 대체하기 위한 토대를 마련합니다.

🔒

Cross-realm guard logic, watchpoint invalidation, and TypedArray exclusion all introduce edge cases in these new fast paths worth auditing.

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