-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Fix GH-18136: tracing JIT floating point register clobbering on Windows and ARM64 #18352
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
Just when I thought it was finished, turns out the same issue exists on macOS+arm64 (or on more arm64 platforms as well?)... That will be fun without access to the native hardware, but I suppose it's gonna be the same principle but easier since those platforms do support inline asm. |
…ndows and ARM64 On win64, xmm6-xmm15 are preserved registers, but the prologues and epilogues of JITted code don't handle these. The issue occurs when calling into the JIT code again via an internal handler (like call_user_func). Therefore, we want to save/restore xmm registers upon entering/leaving execute_ex. Since MSVC x64 does not support inline assembly, we create an assembly wrapper around the real execute_ex function. The alternative is to always save/restore these xmm registers into the fixed call frame, but this causes unnecessary overhead. The same issue occurs for ARM64 platforms for floating point register 8 to 15. However, there we can use inline asm to fix this.
#if defined(__GNUC__) && defined(__aarch64__) | ||
__asm__ __volatile__ (""::: "v8","v9","v10","v11","v12","v13","v14","v15"); | ||
#endif | ||
|
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.
Do we need this for HYBRID VM?
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.
I think we do. The reason we don't save registers in HYBRID VM JIT'ed code is that execute_ex
does it in HYBRID_JIT_GUARD()
before calling handlers, but this doesn't save these registers.
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.
Yes. If I remember correctly, the test also originally failed on circleci which is Linux+arm64+gcc so should use hybrid VM.
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.
This should work.
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.
This looks good to me. It also fixes the test for me on both Windows/x86_64 and Linux/aarch64.
On win64, xmm6-xmm15 are preserved registers, but the prologues and epilogues of JITted code don't handle these. The issue occurs when calling into the JIT code again via an internal handler (like call_user_func). Therefore, we want to save/restore xmm registers upon entering/leaving execute_ex. Since MSVC x64 does not support inline assembly, we create an assembly wrapper around the real execute_ex function.
The alternative is to always save/restore these xmm registers into the fixed call frame, but this causes unnecessary overhead.
The same issue occurs for ARM64 platforms for floating point register 8 to 15. However, there we can use inline asm to fix this.