In my local performance testing, function JIT/arm64 failed for wordpress
benchmark after commit d4ed6b6 (including the follow-up fix commit
487efac).
The root cause lies in that immediate encoding for ADD instruction is
unsafe. In this patch, we use the safe macro ADD_SUB_64_WITH_CONST_32.
Besides, safe macro MEM_ACCESS_64_WITH_UOFFSET is used for the two sites
where `opline->result.num` is used as the offset to access memory.
Change-Id: I4704ff27e9527e70061046d634652600e55ccc4f
This can occur on opcache OOM conditions, where the function/class
names are not interned and the script does not get cached. In
that case the functions/classes get transferred from the persistent
script to the global tables, without incrementing the key refcount.
To mirror that, we should also not try to free the keys when freeing
the persistent script. For this by setting the number of elements
to zero, which will free only the hashtable structure itself.
offsetSet did not account for the fact that the array may no longer exist after
the field is overwritten. This fixes that.
Add test of resizing both to the empty array and a smaller array - there should
be no valgrind warnings with a proper fix.
Alternate approach to #7486 (described in https://bugs.php.net/bug.php?id=81429)
The evaluation of the initializer may throw. This could be refined
by checking whether the initializer is a constant AST. For now
just fix the miscompile.
The do_fcall opcode may have been optimized away if an opcode like
exit is present in the arguments. In that case the opcode scan
would go past the end of the op array.
Ensure current_observed_frame always points to an actually observed frame.
This solution has a caveat of being O(stack size), with the worst case occurring if there are a lot of frames between the current and previous observed frames.
An O(1) solution would require keeping track of the previous observed frame, which would require some additional frame attached metadata, which is best not attempted in an already released version.
Permanent opcache interned strings could have ce_cache pointing to
non-permanent map_ptr slots. On reset, those would be left dangling.
Clear any non-permanent ce_cache slots when the interned string
state is reset.
This was fun to debug...
We should report the undefined variable here and convert it to
null. Passing on undef is particularly insidious here, because
a write_dimension handler may insert it into a hash table
(observed with WeakMap).
PHP JIT supports three configurations: HYRBID, CALL with global register
variables feature(CALL+GRV for short), and CALL+noGRV.
CALL+GRV mode can be built with the following commands:
```
php Zend/zend_vm_gen.php --with-vm-kind=CALL
./buildconf -f; ./configure; make
```
About 230 test cases failed for tracing JIT under CALL+GRV mode on both
x86 and arm64 machines.
For CALL+GRV mode, the condition to determine whether the execution of
an oparray is finished, is "opline == NULL". See function execute_ex()
around line "if (UNEXPECTED(!OPLINE)) {".
However, such cleanup operation is missing for the JIT wrapper
zend_jit_trace_counter_helper(), and the trace_halt stub function.
Tests:
1. test cases: all .phpt test cases under "Zend/tests/ tests/
ext/opcache/tests/jit/".
2. both JIT/x86 and JIT/arm64: function JIT, tracing JIT and tracing JIT
with "--repeat 3"
3. execution modes: NTS/ZTS, HYBRID/CALL+GRV/CALL+noGRV
In my local test, these test cases passed under all JIT configrations.
We'd have usually converted it into a PRE_INC if there is no use,
but that's not guaranteed. If there is no use at this point, make
sure we don't try to use the sentinel value.
zend_jit_long_math_helper() implicitly assumes that the operands
MAY_BE_LONG (but can also have additional types). It will normally
only be called if this is guaranteed. However, for compound
array/object assignment ops this was not check. Generalize the
existing check for assign_op to apply to these as well.
Of course, we could also make the code support this correctly,
but I don't think it makes sense to JIT these if the type we're
specializing for is not present.
Closes GH-7481.