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

  Changed paths:
    A JSTests/stress/array-sort-inline-boolean-comparator.js
    A JSTests/stress/array-sort-inline-closure-comparator.js
    A JSTests/stress/array-sort-inline-comparator-speculation-exit.js
    A JSTests/stress/array-sort-inline-constant-comparator.js
    A JSTests/stress/array-sort-inline-contiguous.js
    A JSTests/stress/array-sort-inline-full.js
    A JSTests/stress/array-sort-inline-holey.js
    A JSTests/stress/array-sort-inline-large.js
    A JSTests/stress/array-sort-inline-len2.js
    A JSTests/stress/array-sort-inline-mixed-sizes.js
    A JSTests/stress/array-sort-inline-noncallable-typeerror.js
    A JSTests/stress/array-sort-inline-osr-exit-in-comparator-with-spread.js
    A JSTests/stress/array-sort-inline-osr-exit-in-comparator.js
    A JSTests/stress/array-sort-inline-polymorphic-comparator.js
    A JSTests/stress/array-sort-inline-small.js
    A JSTests/stress/array-sort-inline-stack-trace.js
    M Source/JavaScriptCore/bytecode/BytecodeList.rb
    M Source/JavaScriptCore/bytecode/InlineCallFrame.cpp
    M Source/JavaScriptCore/bytecode/InlineCallFrame.h
    M Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
    M Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
    M Source/JavaScriptCore/dfg/DFGClobberize.h
    M Source/JavaScriptCore/dfg/DFGDoesGC.cpp
    M Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
    M Source/JavaScriptCore/dfg/DFGMayExit.cpp
    M Source/JavaScriptCore/dfg/DFGNode.h
    M Source/JavaScriptCore/dfg/DFGNodeType.h
    M Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
    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/dfg/DFGStoreBarrierInsertionPhase.cpp
    M Source/JavaScriptCore/ftl/FTLCapabilities.cpp
    M Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
    M Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
    M Source/JavaScriptCore/llint/LLIntSlowPaths.h
    M Source/JavaScriptCore/llint/LLIntThunks.cpp
    M Source/JavaScriptCore/llint/LLIntThunks.h
    M Source/JavaScriptCore/llint/LowLevelInterpreter.asm
    M Source/JavaScriptCore/runtime/ArrayPrototype.cpp
    M Source/JavaScriptCore/runtime/Intrinsic.h
    M Source/JavaScriptCore/runtime/VM.cpp
    M Source/JavaScriptCore/runtime/VM.h

  Log Message:
  -----------
  [JSC] Inline small sorting in DFG / FTL
https://bugs.webkit.org/show_bug.cgi?id=313668
rdar://175871778

Reviewed by Yijia Huang.

This patch enables fully-inlining Array.prototype.sort function in DFG /
FTL graph, including inlining a comparator call.

1. We fully inline Contiguous / Int32 / Undecided array sorting up to 16
   elements. Right now, we do not support Double array.
2. The form is

    scratch = ArraySortCompact(array)
    ... sorting scratch ...
    ArraySortCommit(scratch, array)

   And we do sorting inline against scratch. ArraySortCompact filters
   hole array case etc., and they are going to the slow path call (which
   just uses normal sort). ArraySortCommit will apply sorted result back
   to array.
3. The most notable interesting part is OSR exit handling. In
   Array.prototype.sort, all OSR exit will be handled as "retry entire
   sorting again". This is fine because the spec does not define
   anything about how the comparator is called. This characteristics is
   leveraged in V8 too.
4. When comparator is inlined and OSR exit happens, then comparator must
   continue running its code. But after returning from the comparator,
   we are returning to array_sort_comparator_return_trampoline. Then it
   adjust the next PC and restart `op_call` of Array.prototype.sort again.

Tests: JSTests/stress/array-sort-inline-closure-comparator.js
       JSTests/stress/array-sort-inline-constant-comparator.js
       JSTests/stress/array-sort-inline-contiguous.js
       JSTests/stress/array-sort-inline-full.js
       JSTests/stress/array-sort-inline-holey.js
       JSTests/stress/array-sort-inline-len2.js
       JSTests/stress/array-sort-inline-osr-exit-in-comparator.js
       JSTests/stress/array-sort-inline-small.js
       JSTests/stress/array-sort-inline-stack-trace.js

* JSTests/stress/array-sort-inline-boolean-comparator.js: Added.
(check):
(sortIt):
(expected):
(i.const.cmp):
(i.const.neg.valueOf):
(i.const.pos.valueOf):
(i.const.zero.valueOf):
(i.catch):
* JSTests/stress/array-sort-inline-closure-comparator.js: Added.
(test):
(descendingTest):
* JSTests/stress/array-sort-inline-comparator-speculation-exit.js: Added.
(cmp):
(sortIt):
(assertSorted):
(throwingCmp):
(catch):
* JSTests/stress/array-sort-inline-constant-comparator.js: Added.
(cmp):
(test):
* JSTests/stress/array-sort-inline-contiguous.js: Added.
(sortIt):
(return.a.sort):
(throw.new.Error):
* JSTests/stress/array-sort-inline-full.js: Added.
(sortAsc):
(runSize):
(bigTest):
(stableTest):
(catch):
* JSTests/stress/array-sort-inline-holey.js: Added.
(cmp):
(sortIt):
(runHoley):
* JSTests/stress/array-sort-inline-large.js: Added.
(cmp):
(cmpDesc):
(doSort):
(makeReversed):
(makeRandomish):
(assertSorted):
(alternating):
(catch):
* JSTests/stress/array-sort-inline-len2.js: Added.
(cmpAsc):
(sortWith):
(countingCmp):
* JSTests/stress/array-sort-inline-mixed-sizes.js: Added.
(cmp):
(makeSmall):
(makeLarge):
(harness):
(vm.useFTLJIT):
(check):
(large.sort):
* JSTests/stress/array-sort-inline-noncallable-typeerror.js: Added.
(expectThrow):
(makeEmpty):
(makeSingle):
(sortIt):
(i.expectThrow.sortIt.makeEmpty):
(i.expectThrow.sortIt.makeSingle):
* JSTests/stress/array-sort-inline-osr-exit-in-comparator-with-spread.js: Added.
(cmp):
(sortAndSpread):
(check):
* JSTests/stress/array-sort-inline-osr-exit-in-comparator.js: Added.
(inlinedComparator):
(test):
(multiset):
(sameMultiset):
* JSTests/stress/array-sort-inline-polymorphic-comparator.js: Added.
(cmpAsc):
(cmpDesc):
(cmpMod3Asc):
(cmpByAbs):
(doSort):
(expectedFor):
(w.try.doSort.seed.slice):
(w.catch):
(cmpThrow):
(catch):
* JSTests/stress/array-sort-inline-small.js: Added.
(cmp):
(callSort):
* JSTests/stress/array-sort-inline-stack-trace.js: Added.
(inlined):
(test):
(catch):
* Source/JavaScriptCore/bytecode/BytecodeList.rb:
* Source/JavaScriptCore/bytecode/InlineCallFrame.cpp:
(WTF::printInternal):
* Source/JavaScriptCore/bytecode/InlineCallFrame.h:
(JSC::InlineCallFrame::callModeFor):
(JSC::InlineCallFrame::specializationKindFor):
* Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::emitExitOK):
(JSC::DFG::ByteCodeParser::handleCallVariant):
(JSC::DFG::ByteCodeParser::handleIntrinsicCall):
(JSC::DFG::ByteCodeParser::handleArraySort):
* Source/JavaScriptCore/dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* Source/JavaScriptCore/dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* Source/JavaScriptCore/dfg/DFGMayExit.cpp:
* Source/JavaScriptCore/dfg/DFGNode.h:
(JSC::DFG::Node::hasArrayMode):
* Source/JavaScriptCore/dfg/DFGNodeType.h:
* Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp:
(JSC::DFG::callerReturnPC):
* 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:
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp:
* Source/JavaScriptCore/ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileGetCellButterflySlot):
(JSC::FTL::DFG::LowerDFGToB3::compilePutCellButterflySlot):
(JSC::FTL::DFG::LowerDFGToB3::compileArraySortCompact):
(JSC::FTL::DFG::LowerDFGToB3::compileArraySortCommit):
* Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:
(JSC::LLInt::dispatchToCurrentInstructionDuringExit):
(JSC::LLInt::llint_slow_path_array_sort_comparator_return):
* Source/JavaScriptCore/llint/LLIntSlowPaths.h:
* Source/JavaScriptCore/llint/LLIntThunks.cpp:
(JSC::LLInt::arraySortComparatorReturnTrampolineThunk):
* Source/JavaScriptCore/llint/LLIntThunks.h:
* Source/JavaScriptCore/llint/LowLevelInterpreter.asm:
* Source/JavaScriptCore/runtime/ArrayPrototype.cpp:
(JSC::ArrayPrototype::finishCreation):
* Source/JavaScriptCore/runtime/Intrinsic.h:
* Source/JavaScriptCore/runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::visitAggregateImpl):
* Source/JavaScriptCore/runtime/VM.h:

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



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

Reply via email to