← All issues

[JSC] Add String fast iteration

4a78130

// JSTests/stress/iterator-fast-path-mode-mixing.js
var array = [1, 2, 3];
var map = new Map([[1, 2], [3, 4]]);
var set = new Set([1, 2, 3, 4]);
var ascii = "abcde";
var unicode = "a\u{20BB7}b";
// Mixing more iterable types at one for-of site than the fast iteration
// mode limit must keep working correctly.

JSC의 fast iteration protocol은 JIT가 특정 for-of 루프가 타입이 확정된 컬렉션을 순회한다고 인식할 수 있게 합니다. 이 경우 전체 ECMAScript iteration protocol을 건너뜁니다. Symbol.iterator 호출도, .next() dispatch도, 매 단계마다 {value, done} 객체를 생성하는 작업도 필요하지 않습니다. 기존에는 Array, Map, Set만 fast mode를 지원했습니다. DFG/FTL에서는 루프 본체의 출력을 tuple node로 표현합니다. 이 node의 결과는 GetProjection으로 추출됩니다. ObjectAllocationSinking이 backing iterator가 escape하지 않음을 증명하면, 해당 iterator를 완전히 제거할 수 있습니다.

이번 commit은 이 protocol을 JSString으로 확장하여 네 가지 JIT 티어 전체에 적용합니다. LLInt/Baseline에서는 result 객체 allocation을 방지하기 위해 새로운 JSStringIterator::nextWithAdvance() helper가 도입되었습니다. DFG/FTL에서는 StringIteratorNext(string, position)이 추가되었는데, 이는 tuple을 반환하는 node입니다. allocation sinking과 결합하면 JSStringIterator 자체를 완전히 제거할 수 있습니다. 8-bit 단일 문자의 경우 캐시된 JSString을 반환하는 inline fast path가 적용됩니다. 한편 rope, 16-bit 문자열, surrogate pair는 operationStringIteratorNext를 통해 처리됩니다. per-site fast mode 상한은 2개로 제한되어 inline code 증가를 억제합니다. 3개 이상의 iterable 타입을 혼합하는 사이트는 Generic으로 강등됩니다.

ASCII for-of 루프에서 약 4배, surrogate pair 문자열에서 약 1.8배의 성능이 향상됩니다. 전체 JS iteration protocol을 우회하는 JIT fast path에 string이 네 번째 인식 타입으로 추가되어, JIT correctness 버그의 새로운 고가치 공격 대상이 됩니다.

🔒

New JIT fast path across all four tiers with surrogate handling, sinking, and mode-mixing — multiple edge cases are worth security investigation.

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