re-enable JIT for ZTS builds on Apple Silicon#22712
Conversation
|
I don't know if this was in response to my mail, but thank you 😄 |
Actually yes, haha. I knew that this should work, I just was not working on it and then reading your mail reminded me of it 👍 |
| buf = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, | ||
| MAP_PRIVATE | MAP_ANON | MAP_JIT, -1, 0); |
There was a problem hiding this comment.
Could you clarify if MAP_JIT can be used freely without an com.apple.security.cs.allow-jit entitlement?
There was a problem hiding this comment.
The com.apple.security.cs.allow-jit entitlement is required only when an app adopts the Hardened Runtime capability.
i.e. it's not relevant to non-app store executables.
|
|
||
| #if defined(__APPLE__) && defined(__aarch64__) && defined(ZTS) | ||
| # define ZEND_JIT_USE_APPLE_MAP_JIT 1 | ||
| #endif |
There was a problem hiding this comment.
Would it be feasible to unify all __APPLE__ code variations?
There was a problem hiding this comment.
Technically the split could be done for all macOS builds, but the protection path cannot be unified. pthread_jit_write_protect_supported_np() is supported on Apple Silicon but returns false on Intel, where the existing shared RWX transition works.
There was a problem hiding this comment.
This makes sense. Can we merge the ZEND_JIT_USE_APPLE_MAP_JIT and HAVE_PTHREAD_JIT_WRITE_PROTECT_NP variations?
There was a problem hiding this comment.
Nice finding, I cleaned it up in 8f51da2 . I also change the config.m4 to fail on invalid combinations. I think it makes more sense to explicitly fail compared to implicitly just disable JIT.
There was a problem hiding this comment.
Thank you for the changes. There are also cases where we call pthread_jit_write_protect_np() outside of ZEND_JIT_USE_APPLE_MAP_JIT, but that's probably not reachable?
php-src/ext/opcache/jit/zend_jit.c
Lines 3528 to 3536 in 8f51da2
Fixes #13400
For
__APPLE__ && __aarch64__ && ZTS, this PR moves the JIT buffer out of the OPcache shared memory and creates a dedicated mapping.Background
OPcache JIT is currently disabled for ZTS builds on Apple Silicon. The JIT buffer normally lives at the end of OPcache's
MAP_SHARED | MAP_ANONallocation. In ZTS, one thread may generate code while another executes existing code, so the buffer must remain executable while it is writable.Apple Silicon rejects RWX anonymous mappings with
EPERM. Apple's supported solution isMAP_JITwithpthread_jit_write_protect_np(), which provides per-thread write protection, but macOS rejectsMAP_JIT | MAP_SHAREDwithEINVAL. The existing combined OPcache/JIT mapping won't work on Apple Silicon.