You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add a compiler flag that forces the compiler to emit functions can always be hotpatched. It would be a less bloated alternative to patchable-function-entries (rust-lang/rfcs#3543). Currently it would only work on Windows as it also requires some linker support.
A function can be reliably hotpatched when the following conditions are true:
The first instruction is at least two bytes long
There is no jump to the first instruction
There are enough unused bytes before the function
This allows writing instructions for an absolute jump just before the function and replacing the first instruction with a relative jump to that absolute jump.
The patchable-function-entries flag inserts a fixed amount of nop instructions at the beginning and in front of the function, which reliably fulfils all conditions.
The hotpatch flag by itself only fullfils 1) by making use of of the LLVM function attribute 'patchable-function", "prologue-short-redirect"' (see LLVM Docs ). However, functions are only modified only if they do not already fulfil the condition. In the wild >99% of functions already do so. On x86 a function containing just a single return statement would be an exception. Many architectures fulfil this by default, as they don't have single byte instructions.
While the LLVM function attribute does not support 2) this very rarely matters in practice. Almost no functions break this condition. So far I have only seen this in parameterless functions which perform a tail call to themselves. In addition the hotpatch would need to occur while the hotpatched function is currently executed. This can be completely avoided by the hotpatching facility by hotpatching only when at a known safe instruction, e.g. the beginning of an update loop.
A special flag "functionpadmin" can be passed to some linkers (link.exe, link-lld) to ensure 3). Similar to hotpatch it only adds extra padding if needed. When functions are aligned by the linker they may already contain enough padding, so nothing more needs to be done. In addition, as patchable-function-entries is linker agnostic it needs to create extra symbols and relocations to make the function prefix padding work, creating additional bloat. However, this may require hotpatch flag in the Codeview S_COMPILE3 record, which would also be done with the proposed compiler flag. See: https://github.com/llvm/llvm-project/blob/d703b922961e0d02a5effdd4bfbb23ad50a3cc9f/lld/COFF/Writer.cpp#L1298
Inlining is not a concern for this feature. If a function is inlined, the function in which it is inlined in can be hotpatched instead.
Add the '"patchable-function", "prologue-short-redirect"' attribute to each function, so LLVM can do its magic for x86. For architectures which 1 byte instructions, nothing needs to be done.
Set TargetOptions::Hotpatch to true, so LLVM emits hotpatch flag in the Codeview S_COMPILE3 record. Some linkers require this for their function padding.
As a first step I would only implement this on x86/x64. I already have a candidate implementation: rust-lang/rust#124966
The implementation would cover x86 and aarch64, but only for windows due to required linker support.
I could see this as special option for patchable-function-entries, e.g. "patchable-function-entries=prologue-short-redirect" or "patchable-function-entries=hotpatch"
I'd prefer to have a seperate flag distinc from patchable-function-entries. But if there is good reason I could see to have hotpatch as a special option of patchable-function-entries.
A compiler team member or contributor who is knowledgeable in the area can second by writing @rustbot second.
Finding a "second" suffices for internal changes. If however, you are proposing a new public-facing feature, such as a -C flag, then full team check-off is required.
Compiler team members can initiate a check-off via @rfcbot fcp merge on either the MCP or the PR.
Once an MCP is seconded, the Final Comment Period begins. If no objections are raised after 10 days, the MCP is considered approved.
This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.
The text was updated successfully, but these errors were encountered:
This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.
Concerns or objections to the proposal should be discussed on Zulip and formally registered here by adding a comment with the following syntax:
@rustbot concern reason-for-concern
<description of the concern>
Proposal
Add a compiler flag that forces the compiler to emit functions can always be hotpatched. It would be a less bloated alternative to patchable-function-entries (rust-lang/rfcs#3543). Currently it would only work on Windows as it also requires some linker support.
A function can be reliably hotpatched when the following conditions are true:
This allows writing instructions for an absolute jump just before the function and replacing the first instruction with a relative jump to that absolute jump.
The patchable-function-entries flag inserts a fixed amount of nop instructions at the beginning and in front of the function, which reliably fulfils all conditions.
The hotpatch flag by itself only fullfils 1) by making use of of the LLVM function attribute 'patchable-function", "prologue-short-redirect"' (see LLVM Docs ). However, functions are only modified only if they do not already fulfil the condition. In the wild >99% of functions already do so. On x86 a function containing just a single return statement would be an exception. Many architectures fulfil this by default, as they don't have single byte instructions.
While the LLVM function attribute does not support 2) this very rarely matters in practice. Almost no functions break this condition. So far I have only seen this in parameterless functions which perform a tail call to themselves. In addition the hotpatch would need to occur while the hotpatched function is currently executed. This can be completely avoided by the hotpatching facility by hotpatching only when at a known safe instruction, e.g. the beginning of an update loop.
A special flag "functionpadmin" can be passed to some linkers (link.exe, link-lld) to ensure 3). Similar to hotpatch it only adds extra padding if needed. When functions are aligned by the linker they may already contain enough padding, so nothing more needs to be done. In addition, as patchable-function-entries is linker agnostic it needs to create extra symbols and relocations to make the function prefix padding work, creating additional bloat. However, this may require hotpatch flag in the Codeview S_COMPILE3 record, which would also be done with the proposed compiler flag. See: https://github.com/llvm/llvm-project/blob/d703b922961e0d02a5effdd4bfbb23ad50a3cc9f/lld/COFF/Writer.cpp#L1298
Inlining is not a concern for this feature. If a function is inlined, the function in which it is inlined in can be hotpatched instead.
When a patchable-function-entries attribute is present it takes precedence over this flag. This is also how LLVM currently implements this (see: https://github.com/llvm/llvm-project/blob/bb937e276da11c6d85318b32006f6510877c1a2c/llvm/lib/CodeGen/PatchableFunction.cpp#L43-L49)
Zulip discussion that led to this MCP: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Adding.20hotpatch.20flag.20to.20the.20compiler
Implementation
Add the '"patchable-function", "prologue-short-redirect"' attribute to each function, so LLVM can do its magic for x86. For architectures which 1 byte instructions, nothing needs to be done.
Set TargetOptions::Hotpatch to true, so LLVM emits hotpatch flag in the Codeview S_COMPILE3 record. Some linkers require this for their function padding.
As a first step I would only implement this on x86/x64. I already have a candidate implementation: rust-lang/rust#124966
I used the Clang implementation as a template: llvm/llvm-project@5af2433
The implementation would cover x86 and aarch64, but only for windows due to required linker support.
I could see this as special option for patchable-function-entries, e.g. "patchable-function-entries=prologue-short-redirect" or "patchable-function-entries=hotpatch"
I'd prefer to have a seperate flag distinc from patchable-function-entries. But if there is good reason I could see to have hotpatch as a special option of patchable-function-entries.
Mentors or Reviewers
None yet.
Process
The main points of the Major Change Process are as follows:
@rustbot second
.-C flag
, then full team check-off is required.@rfcbot fcp merge
on either the MCP or the PR.You can read more about Major Change Proposals on forge.
Comments
This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.
The text was updated successfully, but these errors were encountered: