When returning an UNDEF value, it actually becomes NULL.
The following code took this into account:
28344e0445/ext/opcache/jit/zend_jit_trace.c (L2196-L2199)
But the stack does not update the type to NULL, causing a mismatch.
Closes GH-16784.
Co-authored-by: Dmitry Stogov <dmitry@zend.com>
When a recursive call happens with invalid arguments, the maximum valid
arguments are computed and stored in `num_args`, but the RECV entry
block we jump to is `call_num_args` instead. This can skip argument
validation checks. Fix this by using `num_args` instead.
Closes GH-16575.
zend_jit() assumes that Closure op_arrays have no scope, but this is not true
when using the hot counters, first exec, or trace triggers as they use the
executed op_array, which is in case of Closures is a copy, with a scope.
In the tracing JIT this problem is avoided as we fetch the original op_array
when compiling a Closure. Here I replicate this for the hot counters and first
exec triggers.
Fixes GH-16186
Closes GH-16200
Now it's possible that PHP tracing JIT loses some parts of the "hot"
code. In case we have a root LOOP trace with an inlined call of some
function, and we get a SIDE exit inside that function - we recorded a
side trace, but finished it a the RETURN of the inlined function. As
result the opcodes betwee RETURN from SIDE trace and LOOP exit were not
covered by tracer and were executed in interpreter.
This patch introduces a "ret_depth" argument that prevents stopping
tracing on RETURN of such SIDE trace.
The frameless function handlers do not update the op variables when
handling the result is undefined. In this case this causes propagating
an UNDEF value into a temporary, which results in an extra undefined
variable warning for a temporary in this case.
The original issue also reports a crash in some cases, which is also
fixed by this patch.
Closes GH-16012.
Internally accessible via zend_jit_blacklist_function / externally via opcache_jit_blacklist.
The functionality currently only affects tracing JIT, but may be extended to other JIT modes in future.
zend_get_property_info_for_slot(obj, slot) assumes that 'slot' belongs to 'obj', but that may not be the case for lazy proxies.
Fortunately, the property info is often already available in path when it is needed.
For other cases, I make zend_get_property_info_for_slot() aware of lazy objects, and add zend_get_property_info_for_slot_self() for cases where the 'slot' is known to belong to the object itself.
Fixes oss-fuzz #71446
* Improve trace SSA construction and type inference
* Fix incorrect abstract stack maintenance
* Add missing register store
* Avoid IR binding for the dangerous case
* Fix access to possibly uninitilezed variable
* Improve trace SSA construction and type inference
* Fix IR constuction
Force load values into regesters before any branches to guarantee SSA
dominance property
We also add zend_map_ptr_static, so that we do not incur the overhead of constantly recreating the internal run_time_cache pointers on each request.
This mechanism might be extended for mutable_data of internal classes too.
* Check VM interrupt while internal frame is on top
* Use tab instead of spaces
* fix frame used in interrupt and refactor
* remove unused failures for zend_jit_check_timeout
* Fix JIT support
Co-authored-by: Bob Weinand <bobwei9@hotmail.com>
* Fix the missing store to vm_interrupt
* Rename new functions
* Special case zend_interrupt_function in JIT code
* refactor to use ZEND_VM_SET_OPCODE_NO_INTERRUPT
* Split atomic exchange into load + store
It is difficult to determine performance of atomics sometimes. In this
case, the separate load+store is still correct, and a load does not
cause a modification, and might be faster for some platforms than an
exchange. A load+store is slower than an exchange, but we're fine
trading the penalty to the slow path and keeping the happy path faster.
---------
Co-authored-by: Bob Weinand <bobwei9@hotmail.com>