Property hooks were not handled for JIT+trait+preloading.
Split the existing functions that handle op arrays, and add iterations
for property hooks.
Closes GH-18923.
During persisting, the JIT may trigger and fill in the call graph.
The call graph info is allocated on the arena which will be gone after preloading.
To prevent invalid accesses during normal requests, the arena data should be cleared.
This has to be done after all scripts have been persisted because shared op arrays between
scripts can change the call graph.
Closes GH-18916.
ZEND_FUNC_INFO() can not be used on internal CE's. If preloading makes a
CE that's an alias of an internal class, the invalid access happens when
setting the FUNC_INFO.
While we could check the class type to be of user code, we can just skip
aliases altogether anyway which may be faster.
Closes GH-18915.
This test breaks under file cache (because the opcodes are not dumped when ran
with a primed cache). run-tests.php --file-cache-* automatically skips all
ext/opcache tests, so move it there.
GAS started checking the relocation for tlsgd: it must use the %rdi
register. However, the inline assembly now uses %rax instead.
Fix it by changing the "=a" output register to "=D".
Source: ec181e1710/gas/config/tc-i386.c (L6793)
gottpoff is unaffected.
Closes GH-18779.
Add recursion protection when emitting deprecation warnings for class
constants, since the deprecation message can come from an attribute that is
using the same constant for the message, or otherwise result in recursion.
But, internal constants are persisted, and thus cannot have recursion
protection. Otherwise, if a user error handler triggers bailout before the
recursion flag is removed then a subsequent request (e.g. with `--repeat 2`)
would start with that flag already applied. Internal constants can presumably
be trusted not to use deprecation messages that come from recursive attributes.
Fixes GH-18463
Fixes GH-17711
* Move glob to main/ from win32/
In preparation to make the Win32 reimplementation the standard
cross-platform one. Currently, it doesn't do that and just passes
through the original glob implementation. We could consider also having
an option to use the standard glob for systems that have a sufficient
one.
* Enable building with win32 glob on non-windows
Kind of broken. We're namespacing the function and struct, but not yet
the GLOB_* defines. There are a lot of places callers check if i.e.
NOMATCH is defined that would likely become redundant.
Currently it also has php_glob and #defines glob php_glob (etc.) - I
suspect doing the opposite and changing the callers would make more
sense, just doing MVP to geet it to build (even if it fails tests).
* Massive first pass at conversion to internal glob
Have not tested yet. the big things are:
- Should be invisible to userland PHP code.
- A lot of :%s/GLOB_/PHP_GLOB_/g; the diff can be noisy as a result,
especially in comments.
- Prefixes everything with PHP_ to avoid conflicts with system glob in
case it gets included transitively.
- A lot of weird shared definitions that were sprawled out to other
headers are now included in php_glob.h.
- A lot of (but not yet all cases) of HAVE_GLOB are removed, since we
can always fall back to php_glob.
- Using the system glob is not wired up yet; it'll need more shim
ifdefs for each flag type than just glob_t/glob/globfree defs.
* Fix inclusion of GLOB_ONLYDIR
This is a GNU extension, but we don't need to implement it, as the GNU
implementation is flawed enough that callers have to manually filter it
anyways; just provide a stub definition for the constant.
We could consideer implementing this properly later. For now, fixes the
basic glob constant tests.
* Remove HAVE_GLOBs
We now always have a glob implementation that works. HAVE_GLOB should
only be used to check if we have a system implementation, for if we
decide to wrap the system implementation instead.
* We don't need to care about being POSIXly correct for internal glob
* Check for reallocarray
Ideally temporary until GH-17433.
* Forgot to move this file from win32/ to main/
* Check for issetugid (BSD function)
* Allow using the system glob with --enable-system-glob
* Style fix after removing ifdef
* Remove empty case for system glob
I don't know why this was guarded with ZTS, but it leaks on this test
(and a few more):
`./sapi/cli/php ./run-tests.php -c . --show-diff sapi/phpdbg/tests/stdin_001.phpt`
Closes GH-18593.
The trait handling for property hooks in preloading did not exist, we
add a check to skip trait clones and we add the necessary code to update
the op arrays.
Closes GH-18586.
The assertion is imprecise now, and the code assumed that from the
moment an internal class was encountered that there were only internal
classes remaining. This is wrong now, and we still have to continue if
we encounter an internal class. We can only skip the remaining iterations
if the entry in the hash table is not an alias.
Closes GH-18575.
JIT'ed ASSIGN_OBJ expressions will exit to VM when the prop is undef. However,
in a constructor it's very likely the case. Therefore most traces with `new`
expressions will exit to VM.
Here I ensure that we don't need to exit to VM when it's likely that the
prop will be undef.
In the function JIT we compile a slow path to handle such properties,
but not in the tracing JIT, assumingly to reduce code size. Here I enable
compilation of the slow path in the tracing JIT when it's likely the prop
will be undef. Quite conveniently we already record the prop type during
tracing, so I use that to make the decision.
This results in a 1.20% wall time improvement on the symfony demo benchmark
with 20 warmup requests.
Closes GH-18576
Loops whose number of iterations + 1 is a factor of opcache.jit_hot_loop
will always be traced at the exact moment the loop condition evaluates
to false. As a result, these loops can never be JIT'ed successfully.
Here I adjust the default value of opcache.jit_hot_loop to a prime number,
so this can not happen (unless number of iterations+1 is opcache.jit_hot_loop).
Closes GH-18573
Polymorphic calls pass this and the function to side traces via snapshotting.
However, we assume that this/func are in registers, when in fact they may be
spilled.
Here I update snapshotting of poly_func/poly_this to support spilling:
- In zend_jit_snapshot_handler, keep track of the C stack offset
of the spilled register, in a way similar to how stack variables.
- In zend_jit_start, do not pre-load the registers if they were spilled.
- In zend_jit_trace_exit / zend_jit_trace_deoptimization, load from the
stack if the register was spilled.
- Store a reference to poly_func/poly_this in zend_jit_ctx so we can use that
directly in the side trace.
Closes GH-18408
* Optimizer: Optimize `IS_IDENTICAL` with true/false/null to `TYPE_CHECK`
This optimization is already happening in the compiler for explicit `===`
expressions, but not for `match()`, which also compiles to `IS_IDENTICAL`.
* Optimizer: Optimize `T = BOOL(X) + TYPE_CHECK(T, true)` to just `BOOL`
Resolvesphp/php-src#18411
Add a new exit flag (ZEND_JIT_EXIT_CHECK_EXCEPTION) that enables exception
checking during exit/deoptimization.
We already checked for exceptions during exit/deoptimization, but only when
ZEND_JIT_EXIT_FREE_OP1 or ZEND_JIT_EXIT_FREE_OP2 were set (presumably to
handle exceptions thrown during dtor). The new flag makes it possible to request
it explicitly.
This also fixes two issues in zend_jit_trace_exit():
- By returning 1, we were telling the caller (zend_jit_trace_exit_stub()) to
execute the original op handler of EG(current_execute_data)->opline, but in
reality we want to execute EX(opline), which should be EG(exception_op).
- EX(opline) is set to the value of %r15 in zend_jit_trace_exit_stub() before
calling zend_jit_trace_exit(), but this may be the address of a
zend_execute_data when the register is being reused to cache EX(call).
Fixes GH-18262
Closes GH-18297
When a first PHP process launches, Opcache creates a shared file mapping
to use as a shm region. The size of this mapping is set by
opcache.memory_consumption.
When a new PHP process launches while the old one is still running,
Opcache tries to reattach to the shm.
When reattaching it tries to map the requested size (i.e. set by
opcache.memory_consumption). However, if the new requested size is
larger than the size used in the original file mapping, then the call
to VirtualProtect() will fail and the new PHP process will fail to
launch.
It's not possible to resize the virtual region on Windows, unless
relying on undocumented APIs like `NtExtendSection` but then we would
sitll need to communicate that to the first process.
This issue is the root cause of Psalm end-to-end tests failing in
GH-18417: Psalm estimates the required memory sizes and relaunches itself
with more memory requested, if its estimate is below the currently allocated
shared memory. This causes a crash on startup and the tests fail.
To solve this, we need to make the mappings unique per requested size.
There are two ideas:
1. Include in zend_system_id. However, this also affects other things
and may be too overkill.
2. Include it in the filename, this is an easy local change.
I went with this option.
Closes GH-18443.