Skip to content

Conversation

@Keno
Copy link
Member

@Keno Keno commented Dec 5, 2025

The preserve_none calling convention is a new calling convention in clang (>= 19) and gcc that preserves a more minimal set of registers (rsp, rbp on x86_64; lr, fp on aarch64). As a result, if this calling convention is used with setjmp, those registers do not need to be stored in the setjmp buffer, allowing us to reduce the size of this buffer and use fewer instructions to save the buffer. The tradeoff of course is that these registers may need to be saved anyway, in which case both the stack usage and the instructions just move to the caller (which is strictly worse). It is not clear that this is useful for exceptions (which already have a fair bit of state anyway, so even in the happy path the savings are not necessarily that big), but I am thinking about using it for #60281, which has different characteristics, so this is an easy way to try out whether there are any unexpected challenges.

Note that preserve_none is a very recent compiler feature, so most compilers out there do not have it yet. For compatibility, this PR supports using different jump buffer formats in the runtime and the generated code.

The `preserve_none` calling convention is a new calling convention in
clang (>= 19) and gcc that preserves a more minimal set of registers
(rsp, rbp on x86_64; lr, fp on aarch64). As a result, if this calling
convention is used with setjmp, those registers do not need to be stored
in the setjmp buffer, allowing us to reduce the size of this buffer and
use fewer instructions to save the buffer. The tradeoff of course is
that these registers may need to be saved anyway, in which case
both the stack usage and the instructions just move to the caller
(which is strictly worse). It is not clear that this is useful for
exceptions (which already have a fair bit of state anyway, so even
in the happy path the savings are not necessarily that big), but
I am thinking about using it for #60281, which has different
characteristics, so this is an easy way to try out whether there
are any unexpected challenges.

Note that preserve_none is a very recent compiler feature, so most
compilers out there do not have it yet. For compatibility, this PR
supports using different jump buffer formats in the runtime and
the generated code.
@gbaraldi
Copy link
Member

gbaraldi commented Dec 5, 2025

If the function doesn't use all the registers available to it, does this potentially make the setjmp cheaper since it won't save useless information? I doubt this is true on x86 since it has so few registers, but it might be true on aarch64. I've seen setjmp taking a couple % of the runtime on aarch64 macOS when spawning lots and lots of tasks

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.

3 participants