Skip to content

[JSC] Improve worst case performance of Air stack allocation#61023

Merged
webkit-commit-queue merged 1 commit intoWebKit:mainfrom
dhecht:eng/JSC-Improve-worst-case-performance-of-Air-stack-allocation
Mar 21, 2026
Merged

[JSC] Improve worst case performance of Air stack allocation#61023
webkit-commit-queue merged 1 commit intoWebKit:mainfrom
dhecht:eng/JSC-Improve-worst-case-performance-of-Air-stack-allocation

Conversation

@dhecht
Copy link
Copy Markdown
Contributor

@dhecht dhecht commented Mar 20, 2026

c03651a

[JSC] Improve worst case performance of Air stack allocation
https://bugs.webkit.org/show_bug.cgi?id=310376
rdar://173019617

Reviewed by Yusuke Suzuki.

Eventually we may want to replace the interference graph based stack
allocator with one based on live-range intervals (similar to the
greedy register allocator).

But in the meantime, optimize the stack slot assignment algorithm from
O(n²) to O(n log n). The old code tried each candidate position and
re-scanned all interfering slots to verify no overlap. The new code sorts
the interference list by offset and does a single sweep, pushing the
candidate down past any overlapping slot.

This also makes the assignment truly first-fit (closest to FP), whereas
the old code iterated interference lists in arbitrary order and took the
first valid position found.

Improves testair performance from ~5 minutes to a few seconds because
a test case (testZDefOfSpillSlotWithOffsetNeedingToBeMaterializedInARegister)
had a lot of interfering tmps.

Test: Source/JavaScriptCore/b3/air/testair.cpp
* Source/JavaScriptCore/b3/air/testair.cpp:
* Source/JavaScriptCore/b3/air/AirAllocateStackByGraphColoring.cpp:
* Source/JavaScriptCore/b3/air/AirStackAllocation.cpp:
(JSC::B3::Air::assign):
(JSC::B3::Air::attemptAssignment): Deleted.
* Source/JavaScriptCore/b3/air/AirStackAllocation.h:

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

f5eac0f

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows Apple Internal
✅ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe 🛠 win ⏳ 🛠 ios-apple
✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug ✅ 🧪 wpe-wk2 🧪 win-tests ❌ 🛠 mac-apple
✅ 🧪 webkitperl ✅ 🧪 ios-wk2 ✅ 🧪 api-mac ✅ 🧪 api-wpe ✅ 🛠 vision-apple
✅ 🧪 ios-wk2-wpt ✅ 🧪 api-mac-debug ✅ 🛠 gtk3-libwebrtc
✅ 🛠 🧪 jsc ✅ 🧪 api-ios ✅ 🧪 mac-wk1 ✅ 🛠 gtk
✅ 🛠 🧪 jsc-debug-arm64 ✅ 🛠 ios-safer-cpp ✅ 🧪 mac-wk2 ✅ 🧪 gtk-wk2
✅ 🛠 vision ✅ 🧪 mac-AS-debug-wk2 ✅ 🧪 api-gtk
✅ 🛠 🧪 merge ✅ 🛠 vision-sim ✅ 🧪 mac-wk2-stress ✅ 🛠 playstation
✅ 🧪 vision-wk2 ✅ 🧪 mac-intel-wk2 ✅ 🛠 jsc-armv7
✅ 🛠 tv ✅ 🛠 mac-safer-cpp ✅ 🧪 jsc-armv7-tests
✅ 🛠 tv-sim
✅ 🛠 watch
✅ 🛠 watch-sim

@dhecht dhecht self-assigned this Mar 20, 2026
@dhecht dhecht added the JavaScriptCore For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues. label Mar 20, 2026
@dhecht dhecht force-pushed the eng/JSC-Improve-worst-case-performance-of-Air-stack-allocation branch from b0ad24b to 682b9b7 Compare March 20, 2026 20:02
@dhecht dhecht force-pushed the eng/JSC-Improve-worst-case-performance-of-Air-stack-allocation branch from 682b9b7 to 4df3985 Compare March 20, 2026 20:06
@dhecht dhecht force-pushed the eng/JSC-Improve-worst-case-performance-of-Air-stack-allocation branch from 4df3985 to 34741bb Compare March 20, 2026 21:16
@dhecht dhecht marked this pull request as ready for review March 20, 2026 21:17
@dhecht dhecht requested a review from a team as a code owner March 20, 2026 21:17
otherSlots.append(otherSlot);
}

std::sort(otherSlots.begin(), otherSlots.end(), [](StackSlot* a, StackSlot* b) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use std::ranges::sort(otherSlots, [](...) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that's better. Also changed to use std::ranges::greater { }, &StackSlot::offsetFromFP.
And changed the upper_bound too to this syntax.

auto sortByOffsetDescending = [](StackSlot* a, StackSlot* b) {
return a->offsetFromFP() > b->offsetFromFP(); // Negative, so sort descending
};
std::sort(assignedEscapedStackSlots.begin(), assignedEscapedStackSlots.end(), sortByOffsetDescending);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

@dhecht dhecht force-pushed the eng/JSC-Improve-worst-case-performance-of-Air-stack-allocation branch from 34741bb to d04e195 Compare March 20, 2026 22:00
@dhecht dhecht force-pushed the eng/JSC-Improve-worst-case-performance-of-Air-stack-allocation branch from d04e195 to f5eac0f Compare March 20, 2026 23:20
@dhecht dhecht added safe-merge-queue Applied to automatically send a pull-request to merge-queue after passing EWS checks merge-queue Applied to send a pull request to merge-queue and removed safe-merge-queue Applied to automatically send a pull-request to merge-queue after passing EWS checks labels Mar 21, 2026
https://bugs.webkit.org/show_bug.cgi?id=310376
rdar://173019617

Reviewed by Yusuke Suzuki.

Eventually we may want to replace the interference graph based stack
allocator with one based on live-range intervals (similar to the
greedy register allocator).

But in the meantime, optimize the stack slot assignment algorithm from
O(n²) to O(n log n). The old code tried each candidate position and
re-scanned all interfering slots to verify no overlap. The new code sorts
the interference list by offset and does a single sweep, pushing the
candidate down past any overlapping slot.

This also makes the assignment truly first-fit (closest to FP), whereas
the old code iterated interference lists in arbitrary order and took the
first valid position found.

Improves testair performance from ~5 minutes to a few seconds because
a test case (testZDefOfSpillSlotWithOffsetNeedingToBeMaterializedInARegister)
had a lot of interfering tmps.

Test: Source/JavaScriptCore/b3/air/testair.cpp
* Source/JavaScriptCore/b3/air/testair.cpp:
* Source/JavaScriptCore/b3/air/AirAllocateStackByGraphColoring.cpp:
* Source/JavaScriptCore/b3/air/AirStackAllocation.cpp:
(JSC::B3::Air::assign):
(JSC::B3::Air::attemptAssignment): Deleted.
* Source/JavaScriptCore/b3/air/AirStackAllocation.h:

Canonical link: https://commits.webkit.org/309668@main
@webkit-commit-queue webkit-commit-queue force-pushed the eng/JSC-Improve-worst-case-performance-of-Air-stack-allocation branch from f5eac0f to c03651a Compare March 21, 2026 05:03
@webkit-commit-queue
Copy link
Copy Markdown
Collaborator

Committed 309668@main (c03651a): https://commits.webkit.org/309668@main

Reviewed commits have been landed. Closing PR #61023 and removing active labels.

@webkit-commit-queue webkit-commit-queue merged commit c03651a into WebKit:main Mar 21, 2026
@webkit-commit-queue webkit-commit-queue removed the merge-queue Applied to send a pull request to merge-queue label Mar 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

JavaScriptCore For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants