diff --git a/src/jit_compiler_a64.cpp b/src/jit_compiler_a64.cpp index d2a1d6c3..de4120d4 100644 --- a/src/jit_compiler_a64.cpp +++ b/src/jit_compiler_a64.cpp @@ -116,7 +116,7 @@ void JitCompilerA64::enableWriting() void JitCompilerA64::enableExecution() { - setPagesRX(code, CodeSize + CalcDatasetItemSize); + setPagesRXKeepIcache(code, CodeSize + CalcDatasetItemSize); } void JitCompilerA64::enableAll() diff --git a/src/virtual_memory.c b/src/virtual_memory.c index 1000d99f..cdeddfc3 100644 --- a/src/virtual_memory.c +++ b/src/virtual_memory.c @@ -198,6 +198,22 @@ void setPagesRX(void* ptr, size_t bytes) { #endif } +void setPagesRXKeepIcache(void* ptr, size_t bytes) { +#if defined(USE_PTHREAD_JIT_WP) && defined(MAC_OS_VERSION_11_0) \ + && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_11_0 + if (__builtin_available(macOS 11.0, *)) { + /* The A64 JIT already called __builtin___clear_cache on the exact + modified range inside generateProgram. Only toggle write-protect + here; re-flushing the full buffer is redundant and measurably + expensive on Apple Silicon. */ + pthread_jit_write_protect_np(1); + return; + } +#endif + char *errfunc; + pageProtect(ptr, bytes, PAGE_EXECUTE_READ, &errfunc); +} + void setPagesRWX(void* ptr, size_t bytes) { char *errfunc; pageProtect(ptr, bytes, PAGE_EXECUTE_READWRITE, &errfunc); diff --git a/src/virtual_memory.h b/src/virtual_memory.h index 5e8e31d5..063edb05 100644 --- a/src/virtual_memory.h +++ b/src/virtual_memory.h @@ -39,6 +39,7 @@ extern "C" { void* allocMemoryPages(size_t); void setPagesRW(void*, size_t); void setPagesRX(void*, size_t); +void setPagesRXKeepIcache(void*, size_t); void setPagesRWX(void*, size_t); void* allocLargePagesMemory(size_t); void freePagedMemory(void*, size_t);