-
-
Notifications
You must be signed in to change notification settings - Fork 30.3k
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
gh-126195: Use pthread_jit_write_protect_np on macOS #126196
base: main
Are you sure you want to change the base?
Conversation
Replace mprotect with pthread_jit_write_protect_np on MacOS Apple Silicon. Improve JIT performance by ~1.4% on this platform.
We should probably do one last benchmarking run on macOS for this PR. Unfortunately our Mac benchmark machine is offline at the moment -- I'm waiting for someone to physically go and see what's up. Hopefully less than a couple days or so. |
JIT tests are failing and I have a partial fix at #126166 (comment). But it doesn't work on Windows because I'm not sure how to detect the JIT is running on there. |
The machine is back up and I'm running the benchmarks now. |
I think the benchmarks are hitting the tests being broken on main -- failing in the |
Merging main to get rid of failures in test_embed |
I've updated the branch to check if errors disappeared... |
When looking this up, it seems that the documented way to do this now is the Probably makes sense to land this now, then explore the other API after. |
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.
One issue with an error path, and a couple of suggestions.
@@ -56,9 +56,16 @@ jit_alloc(size_t size) | |||
int flags = MEM_COMMIT | MEM_RESERVE; | |||
unsigned char *memory = VirtualAlloc(NULL, size, flags, PAGE_READWRITE); | |||
int failed = memory == NULL; | |||
#elif defined(__APPLE__) && defined(__aarch64__) |
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.
Does this work? If so, it seems a bit less fragile.
#elif defined(__APPLE__) && defined(__aarch64__) | |
#elif defined(MAP_JIT) |
I'd also like to reduce the duplication of code here. So maybe we can just add the flags in this case and use the same code path as before:
#ifdef MAP_JIT
flags |= MAP_JIT;
prot |= PROT_EXEC;
#endif
int prot = PROT_READ | PROT_WRITE | PROT_EXEC; | ||
unsigned char *memory = mmap(NULL, size, prot, flags, -1, 0); | ||
int failed = memory == MAP_FAILED; | ||
pthread_jit_write_protect_np(0); |
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 will leave the memory protection off for the entire thread if mapping the memory fails.
Even though pthread_jit_write_protect_np(0)
is logically part of jit_alloc
, and pthread_jit_write_protect_np(1)
is logically part of mark_executable
, I feel like it will be less error-prone and easier to reason about error paths if we make these calls in _PyJIT_Compile
instead. It might also make porting to the new callback API easier, since the callback will just be all of the code between the two pthread_jit_write_protect_np
calls.
What do you think?
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
BTW, benchmarking results for anyone curious: https://github.com/faster-cpython/benchmarking-public/blob/main/results/bm-20241018-3.14.0a1%2B-f74cd79-JIT/bm-20241018-darwin-arm64-diegorusso-pthread-3.14.0a1%2B-f74cd79-vs-base.svg |
Replace mprotect with pthread_jit_write_protect_np on MacOS Apple Silicon.
Improve JIT performance by ~1.4% on this platform.