-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Introduce mimalloc to static Linux binaries #6321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow! That's awesome. 🤩 I compared the ARM binaries at least and it turns out that the static ones are now as fast as the dynamic ones. So great! Thank you very much, @ainame!
|
Testing the changes here https://github.com/ainame/SwiftLint/actions/runs/18858095838/job/53810600398 It ran successfully after those changes! |
|
@SimplyDanny Thank you for your review! I've addressed your suggestions and updated CHANGELOG.md! |

Background
Closes #6298
Currently static Linux binary distributed isn't as performant as expected. This is because
mallocin musl libc, which is used in Static Linux SDK, doesn't work well with multiple threaded execution. It usesfutexsyscalls to safely access memory, which in turns, decrease performance in multi-threaded env.https://git.musl-libc.org/cgit/musl/tree/src/thread/__wait.c?h=v1.1.23&id=7e399fabd3db2c528b5982803eeba2841f547695
http://git.musl-libc.org/cgit/musl/tree/src/malloc/malloc.c?h=v1.1.23&id=7e399fabd3db2c528b5982803eeba2841f547695
What
To address this issue, I introduced mimalloc for static Linux binary in this PR.
https://github.com/microsoft/mimalloc
mimalloc is performant memory allocator written in C that works as drop-in replacement for
mallocand supports builds for musl. Compared with other popular allocators like jemalloc or tcmalloc, It think it's fair option. Also, in Swift compiler project (swiftlang/swift), mimaloc has been adopted for the allocator in Windows's toolchain (not runtime!).https://forums.swift.org/t/se-454-adopt-mimalloc-for-windows-toolchain/
How
Since mimalloc is only necessary when building static Linux binary, I added a new step that compiles
libmimalloc.atorelease.ymland updatedswift buildcommand.The mimalloc README recommends placing mimalloc.o (instead of the .a) at the very beginning of the linker input so its malloc overrides the standard one. With swift build, we can’t reliably force an absolute “first” position.
https://github.com/microsoft/mimalloc?tab=readme-ov-file#static-override
As a practical alternative, I link against libmimalloc.a and wrap it with --whole-archive/--no-whole-archive so all relevant objects are included, provided the library is built with the malloc override enabled. To be fair, the .o approach works fine for now. I just wanted to make sure it will keep linking correctly in the future.
Since mimalloc is MIT license, I've also updated
Makefileto include mimalloc's license file into the zip files for Linux binary.third_party_licenses/mimalloc-LICENSEis now bundled in repo.Test
GitHub Actions
I ran release.yml on my fork and worked successfully.
https://github.com/ainame/SwiftLint/actions/runs/18823390591
Artefacts
It runs faster with mimalloc.
swiftlint-static-arm64 with mimalloc from https://github.com/ainame/SwiftLint/actions/runs/18823390591
swiftlint-static-arm64 built from main branch synced with upstream from https://github.com/ainame/SwiftLint/actions/runs/18819592629/artifacts/4374908255
Symbols
nmsuggests that malloc/free/calloc/realloc are resolved from mimalloc. They are defined in the final binary (symbol type T).