Skip to content

Conversation

@jmschonfeld
Copy link
Contributor

The funnel point for replacing subranges in Data for non-empty/inline representations is __DataStorage.replaceBytes(in:with:length:). Originally on Darwin, this function was declared using NSRange as the range parameter, and since it is @usableFromInline it is never inlined and is part of our ABI. NSRange exists in Foundation.framework but not in swift-foundation and other lower libraries, so using NSRange here is problematic.

In macOS 14 aligned releases, we added a new @usableFromInline ABI entry point that uses Range<Int> instead. This is the entry point that we use today on Linux/Windows, and in Foundation.framework the calling code has an availability check to call the Range<Int> variant on newer OS versions and the NSRange variant on older OS versions. This solution isn't great and these availability checks are quite expensive and can show up as heavy parts of traces.

To resolve the performance issue and make this possible to represent without a dependency on NSRange, I replaced the NSRange variant's parameter with a tuple. This tuple is the same layout as NSRange (so it is ABI compatible) and I used @_silgen_name to preserve the symbol name despite the change in type. This means that we can reliably call this function in modules where NSRange does not exist without performing an availability check. The Range<Int> variant now just calls the tuple variant, and all call sites unconditionally call the tuple variant. I confirmed that building a binary with this change (that I validated makes a direct call to the __DataStorage.replaceBytes function) runs successfully on an OS without this change (i.e. the back deployment scenario) and forward deployment should be equivalent.

@jmschonfeld jmschonfeld requested a review from glessard November 3, 2025 19:31
@jmschonfeld jmschonfeld merged commit 1ac5330 into swiftlang:future Nov 4, 2025
18 checks passed
@jmschonfeld jmschonfeld deleted the datastorage-range-abi branch November 4, 2025 01:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants