Skip to content

Commit c45be8a

Browse files
authored
GH-126195: Use M1 JIT memory protection APIs (GH-126196)
1 parent 494360a commit c45be8a

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve JIT performance by 1.4% on macOS Apple Silicon by using platform-specific memory protection APIs. Patch by Diego Russo.

Python/jit.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,12 @@ jit_alloc(size_t size)
5858
int failed = memory == NULL;
5959
#else
6060
int flags = MAP_ANONYMOUS | MAP_PRIVATE;
61-
unsigned char *memory = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, -1, 0);
61+
int prot = PROT_READ | PROT_WRITE;
62+
# ifdef MAP_JIT
63+
flags |= MAP_JIT;
64+
prot |= PROT_EXEC;
65+
# endif
66+
unsigned char *memory = mmap(NULL, size, prot, flags, -1, 0);
6267
int failed = memory == MAP_FAILED;
6368
#endif
6469
if (failed) {
@@ -102,8 +107,11 @@ mark_executable(unsigned char *memory, size_t size)
102107
int old;
103108
int failed = !VirtualProtect(memory, size, PAGE_EXECUTE_READ, &old);
104109
#else
110+
int failed = 0;
105111
__builtin___clear_cache((char *)memory, (char *)memory + size);
106-
int failed = mprotect(memory, size, PROT_EXEC | PROT_READ);
112+
#ifndef MAP_JIT
113+
failed = mprotect(memory, size, PROT_EXEC | PROT_READ);
114+
#endif
107115
#endif
108116
if (failed) {
109117
jit_error("unable to protect executable memory");
@@ -499,6 +507,9 @@ _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction trace[], siz
499507
if (memory == NULL) {
500508
return -1;
501509
}
510+
#ifdef MAP_JIT
511+
pthread_jit_write_protect_np(0);
512+
#endif
502513
// Update the offsets of each instruction:
503514
for (size_t i = 0; i < length; i++) {
504515
state.instruction_starts[i] += (uintptr_t)memory;
@@ -529,6 +540,9 @@ _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction trace[], siz
529540
data += group->data_size;
530541
assert(code == memory + code_size);
531542
assert(data == memory + code_size + data_size);
543+
#ifdef MAP_JIT
544+
pthread_jit_write_protect_np(1);
545+
#endif
532546
if (mark_executable(memory, total_size)) {
533547
jit_free(memory, total_size);
534548
return -1;

0 commit comments

Comments
 (0)