The current check always evaluated to false because if `!page_size`
is true, then `page_size & (page_size - 1)` equals `0 & (0 - 1)` which
is always 0. The if condition is meant to check if page_size is zero or
not a power of two, thus we must change the AND to an OR to fix this
issue.
Closes GH-10427
Signed-off-by: George Peter Banyard <girgias@php.net>
This moves them from ``.data`` to ``.rodata`` and allows more compiler optimizations.
* ext/opcache/zend_accelerator_hash: make prime_numbers const
* Zend/zend_signal: make zend_sigs const
* ext/dba: make dba_handler pointers const
* ext/exif: make php_tiff_bytes_per_format and other globals const
* ext/intl/grapheme: make grapheme_extract_iters const
* ext/mstring: make rare_codepoint_bitvec const
* ext/snmp: make objid_mib const
* ext/opcache: make all zend_shared_memory_handlers const
Previously function JIT for the whole script (opcache.jit=1205) dumped
all op_arrays before JIT-ing the first functon. This complicated debugging
of particular JIT-ed function and leaded to usage of opcache.jit=1204.
Now both options should produce similar op_array/disasm interlived
output.
* Revert "ext/opcache: use C11 atomics for "restart_in" (#10276)"
This reverts commit 061fcdb0a5.
While the commit does indeed improve performance, @dstogov complained
that it disables the code path calling kill_all_lockers(), and thus
hanging workers are never killed and restarted.
https://github.com/php/php-src/pull/10276#issuecomment-1383593046
The fact that this feature was not implemented in the existing atomic
code path (i.e. Windows) did not mean that the feature was considered
not strictly necessary, but that the Windows implementation just did
not need the feature because SAPIs that work on Windows do not manage
child processes
https://github.com/php/php-src/pull/10276#issuecomment-1383868696https://github.com/php/php-src/pull/10276#issuecomment-1384235011
* ext/opcache: document lack of kill_all_lockers() on Windows
kill_all_lockers() is not implemented on Windows, and does not need to
be.
Cheaper than fcntl(F_SETLK). The same is done already on Windows, so
if that works, why not use it everywhere? (Of course, only if the
compiler supports this C11 feature.)
As a bonus, the code in this commit also works on C++ via C++11
std::atomic, just in case somebody adds some C++ code to the opcache
extension one day.
This make sure the tests do not fail if they are not run from the
repository root.
Closes GH-10266
Signed-off-by: George Peter Banyard <girgias@php.net>
The name "new" happens to be a C++ keyword, which was the my reason to
rethink those names.
The "xlat_table" is not only used to translate pointers for persisting
scripts to shared memory, but is also used to annoate pointers
(e.g. by the JIT to associate an op_array with its jit_extension).
The names "old" and "new" aren't good for that; often, there's nothing
"old" or "new" about them. It's actually a generic lookup table, and
"old" shall be named "key" (which it is called internally already),
and "new" is renamed to simply "value".
A copy of this piece of code exists in zend_jit_compile_side_trace(),
but there, the leak bug does not exist.
This bug exists since both copies of this piece of code were added in
commit 4bf2d09ede
Commit 6c25413183 added the flag ZEND_JIT_EXIT_INVALIDATE which
resets the trace handlers in zend_jit_trace_exit(), but forgot to
lock the shared memory section.
This could cause another worker process who still saw the
ZEND_JIT_TRACE_JITED flag to schedule ZEND_JIT_TRACE_STOP_LINK, but
when it arrived at the ZEND_JIT_DEBUG_TRACE_STOP, the handler was
already reverted by the first worker process and thus
zend_jit_find_trace() fails.
This in turn generated a bogus jump offset in the JITed code, crashing
the PHP process.
Commit 6c25413 added the flag ZEND_JIT_EXIT_INVALIDATE which resets
the trace handlers in zend_jit_trace_exit(), but forgot to consider
that on ZEND_JIT_TRACE_STOP_LINK, this changed handler gets passed to
zend_jit_find_trace(), causing it to fail, either by returning 0
(results in bogus data) or by aborting due to ZEND_UNREACHABLE(). In
either case, this crashes the PHP process.
I'm not quite sure how to fix this multi-threading problem properly;
my suggestion is to just fail the zend_jit_trace() call. After all,
the whole ZEND_JIT_EXIT_INVALIDATE fix was about reloading modified
scripts, so there's probably no point in this pending zend_jit_trace()
call.