Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 4a781308731b113c7fe7dcd01719a070a0361eb5
      
https://github.com/WebKit/WebKit/commit/4a781308731b113c7fe7dcd01719a070a0361eb5
  Author: Sosuke Suzuki <[email protected]>
  Date:   2026-05-31 (Sun, 31 May 2026)

  Changed paths:
    A JSTests/microbenchmarks/string-iterator-for-of-ascii.js
    A JSTests/microbenchmarks/string-iterator-for-of-surrogate-pairs.js
    A JSTests/microbenchmarks/string-iterator-spread-surrogate-pairs.js
    A JSTests/stress/iterator-fast-path-mode-mixing.js
    A JSTests/stress/string-iterator-fast-path.js
    A JSTests/stress/string-iterator-surrogate-pairs.js
    M Source/JavaScriptCore/CMakeLists.txt
    M Source/JavaScriptCore/DerivedSources-input.xcfilelist
    M Source/JavaScriptCore/DerivedSources.make
    M Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
    R Source/JavaScriptCore/builtins/StringIteratorPrototype.js
    M Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp
    M Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h
    M Source/JavaScriptCore/bytecode/IterationModeMetadata.h
    M Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
    M Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
    M Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
    M Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
    M Source/JavaScriptCore/dfg/DFGClobberize.h
    M Source/JavaScriptCore/dfg/DFGCloneHelper.h
    M Source/JavaScriptCore/dfg/DFGDoesGC.cpp
    M Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
    M Source/JavaScriptCore/dfg/DFGNode.h
    M Source/JavaScriptCore/dfg/DFGNodeType.h
    M Source/JavaScriptCore/dfg/DFGOperations.cpp
    M Source/JavaScriptCore/dfg/DFGOperations.h
    M Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
    M Source/JavaScriptCore/dfg/DFGSafeToExecute.h
    M Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
    M Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
    M Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
    M Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
    M Source/JavaScriptCore/ftl/FTLCapabilities.cpp
    M Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
    M Source/JavaScriptCore/jit/JITOperations.cpp
    M Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
    M Source/JavaScriptCore/runtime/IteratorOperations.cpp
    M Source/JavaScriptCore/runtime/JSGlobalObject.cpp
    M Source/JavaScriptCore/runtime/JSGlobalObject.h
    M Source/JavaScriptCore/runtime/JSStringIterator.h
    M Source/JavaScriptCore/runtime/JSStringIteratorInlines.h
    M Source/JavaScriptCore/runtime/StringIteratorPrototype.cpp
    M Source/JavaScriptCore/runtime/StringPrototype.cpp
    M Source/JavaScriptCore/runtime/StringPrototype.h

  Log Message:
  -----------
  [JSC] Add String fast iteration
https://bugs.webkit.org/show_bug.cgi?id=315330

Reviewed by Yusuke Suzuki.

Extend the iterator_open / iterator_next fast iteration protocol (currently
JSArray / JSMap / JSSet) to JSString. LLInt / Baseline use the
JSStringIterator::nextWithAdvance() helper, so no iterator result object is
allocated and surrogate pairs become a substring instead of a rope.

For DFG / FTL, iterator_next is lowered to a new tuple-returning node
StringIteratorNext(string, position) -> <resultString, nextPosition>. The
iterator's Index field is read and written with GetInternalField /
PutInternalField around the node, so the node itself never references the
JSStringIterator. This keeps the iterator's field accesses visible to
ObjectAllocationSinking, which can then eliminate the JSStringIterator
allocation entirely. The node inlines the resolved 8-bit single-character fast
path (the result is a cached single-character string, so there is no
allocation) and falls back to operationStringIteratorNext for ropes, 16-bit
strings, and surrogate pairs. nextWithAdvance() and the operation share a
common JSStringIterator::advance() core so the LLInt/Baseline and DFG/FTL paths
cannot diverge.

StringIteratorPrototype.next becomes a C++ host function used by the generic
path. Since this adds a 4th fast mode, we also limit the number of fast modes
inlined per iteration site to 2; beyond that, new iterable types are recorded
as Generic.

                                             ToT                     Patched

string-iterator-for-of-ascii            108.2338+-1.7953     ^     
26.2858+-0.6488        ^ definitely 4.1176x faster
string-iterator-for-of-surrogate-pairs  712.0298+-10.1006    ^    
392.1395+-4.2522        ^ definitely 1.8158x faster

Tests: JSTests/microbenchmarks/string-iterator-for-of-ascii.js
       JSTests/microbenchmarks/string-iterator-for-of-surrogate-pairs.js
       JSTests/microbenchmarks/string-iterator-spread-surrogate-pairs.js
       JSTests/stress/iterator-fast-path-mode-mixing.js
       JSTests/stress/string-iterator-fast-path.js

* JSTests/microbenchmarks/string-iterator-for-of-ascii.js: Added.
(sumCodePoints):
* JSTests/microbenchmarks/string-iterator-for-of-surrogate-pairs.js: Added.
(sumCodePoints):
* JSTests/microbenchmarks/string-iterator-spread-surrogate-pairs.js: Added.
(spread):
* JSTests/stress/iterator-fast-path-mode-mixing.js: Added.
(shouldBe):
(countValues):
(sumValues):
(generatorValues):
* JSTests/stress/string-iterator-fast-path.js: Added.
(shouldBe):
(sumCodePoints):
(collect):
(firstChar):
(countValues):
(makeRope):
(exhaustManually):
(joinChars):
(String.prototype.Symbol.iterator):
* JSTests/stress/string-iterator-surrogate-pairs.js: Added.
(assert):
(referenceSegments):
(forOfSegments):
(manualSegments):
(dump):
(check):
(runExactCases):
(runBoundaryCombinations):
(rnd):
(randomUnit):
(runRandomStrings):
* Source/JavaScriptCore/bytecode/IterationModeMetadata.h:
(JSC::canUseFastIterationMode):
* Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleIteratorOpen):
(JSC::DFG::ByteCodeParser::handleIteratorNext):
* Source/JavaScriptCore/dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* Source/JavaScriptCore/dfg/DFGCloneHelper.h:
* Source/JavaScriptCore/dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* Source/JavaScriptCore/dfg/DFGNode.h:
(JSC::DFG::Node::isTuple const):
(JSC::DFG::Node::tupleSize const):
* Source/JavaScriptCore/dfg/DFGNodeType.h:
* Source/JavaScriptCore/dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/dfg/DFGOperations.h:
* Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:
* Source/JavaScriptCore/dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::cellTupleResultWithoutUsingChildren):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* Source/JavaScriptCore/jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/runtime/CommonSlowPaths.cpp:
(JSC::iteratorOpenTryFastImpl):
(JSC::iteratorNextTryFastImpl):
* Source/JavaScriptCore/runtime/IteratorOperations.cpp:
(JSC::getIterationMode):
* Source/JavaScriptCore/runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildrenImpl):
* Source/JavaScriptCore/runtime/JSGlobalObject.h:
* Source/JavaScriptCore/runtime/JSStringIterator.h:
* Source/JavaScriptCore/runtime/JSStringIteratorInlines.h:
(JSC::JSStringIterator::advance):
(JSC::JSStringIterator::nextWithAdvance):
* Source/JavaScriptCore/runtime/StringIteratorPrototype.cpp:
(JSC::StringIteratorPrototype::finishCreation):
(JSC::JSC_DEFINE_HOST_FUNCTION):
* Source/JavaScriptCore/runtime/StringPrototype.cpp:
(JSC::StringPrototype::finishCreation):
* Source/JavaScriptCore/runtime/StringPrototype.h:

Canonical link: https://commits.webkit.org/314265@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to