Description
Description
Disclaimer: I encountered this issue using a threading extension. Well aware this may not be the best source of truth on issues like this, especially due to the difficulty of reproducing.
With the following INI:
opcache.jit=tracing
opcache.jit_buffer_size=0
the following happens:
- INI is loaded on the main thread and sets
JIT_G(enabled) = 1
andJIT_G(on) = 1
accel_post_startup()
is called during process init, and overrides thread-locals here to force-disable JIT:
php-src/ext/opcache/ZendAccelerator.c
Lines 3279 to 3280 in 6dec6a6
dasm_buf
is therefore null becausezend_jit_startup()
wasn't called due tojit_buffer_size=0
:php-src/ext/opcache/ZendAccelerator.c
Lines 3277 to 3286 in 6dec6a6
php-src/ext/opcache/jit/zend_jit.c
Line 3675 in 6dec6a6
- when a second thread is started, INI is loaded again, setting
JIT_G(enabled) = 1
andJIT_G(on) = 1
, but this timeaccel_post_startup()
does not override these settings - finally, the following calls fail on Windows with errors like
VirtualProtect() failed [87] The parameter is incorrect
duringzend_accel_persist_script()
becausedasm_buf
isNULL
- this is becauseJIT_G(on) = 1
although it was supposed to be forcibly disabled:php-src/ext/opcache/zend_persist.c
Lines 1384 to 1386 in 6dec6a6
php-src/ext/opcache/zend_persist.c
Lines 1419 to 1424 in 6dec6a6
Proposed solution
JIT_G(enabled)
needs to become a true globalzend_jit_config()
needs to respect the existing value ofJIT_G(enabled)
(or its replacement true global) instead of overwriting it like it currently doesJIT_G(enabled)
(or its replacement true global) should be set totrue
inaccel_post_startup()
afterzend_jit_startup()
returns a success code
PHP Version
8.1, 8.2, 8.3, 8.4, master
Operating System
Windows