You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## Introduction
This implements a more generic version of the in-place modification I
first tried in phpGH-11060. We decided to limit that PR to RC1
optimisations of some array functions only, and not do the in-place
$variable optimisation in that way because of issues.
This patch overcomes those issues and builds on the previous one.
With this patch, any internal function that supports RC1 optimisations
automatically gets the optimisation for in-place variable modifications.
Contrary to the previous approach, this is compatible with exceptions.
Furthermore, this approach also allows userland functions to benefit
from this optimisation.
e.g. the following code will not take a copy of the array with this
patch:
```
function foo($array) {
$array[1] = 1;
}
function bar() {
$array = ...;
$array = foo($array);
}
```
Right now the impact on the benchmark suite isn't that high. The reason
is that only a handful of functions within PHP optimise for RC1 cases, and
the array sizes for those cases are fairly small.
When more support for these cases are added, the benefit from this patch
will increase.
I've added a micro benchmark for array operations that shows the effect
of this optimisation.
## Implementation
The optimiser already tracks which SSA variables have a value that
doesn't matter with the no_val field. By changing ZEND_SEND_VAR to
redefine op1, we automatically know if the variable will ever be used
again without being overwritten by looking at the no_val field.
If the no_val field is set, the variable may hold a string/array and the
refcount may be 1, we set a flag on the ZEND_SEND_VAR(_EX) opline to
indicate that it may avoid a copy. The flag is stored in extended_value.
There are two new VM type spec handlers for this that check for the
flag: one for ZEND_SEND_VAR and one for ZEND_SEND_VAR_EX.
## Limitations
* The optimisation isn't performed on arguments. This is because the
optimisation would be externally visible, which is undesirable.
Unfortunately, this is also the case where a lot of optimisation
opportunity lies. Nonetheless, even with this limitation it seems like
it can help a lot.
* The optimisation does not apply to functions using indirect variable
access (e.g. variable-variables, compact()) and vararg functions.
ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SEND_VAR, op->extended_value/* extended_value implies here OP2 UNUSED and OP1 not UNDEF or REF */, ZEND_SEND_VAR_SIMPLE_EXT, CV, NUM)
ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SEND_VAR_EX, op->extended_value&&op->op2.num <= MAX_ARG_FLAG_NUM/* extended_value implies here OP2 UNUSED and OP1 not UNDEF or REF */, ZEND_SEND_VAR_EX_SIMPLE_EXT, CV, UNUSED|NUM)
9957
+
{
9958
+
USE_OPLINE
9959
+
zval*varptr, *arg;
9960
+
uint32_targ_num=opline->op2.num;
9961
+
9962
+
if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
0 commit comments