ndossche · GitHub

@ndossche

## 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, whereas previously it would due to the copy-on-write
characteristic of arrays:
```
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 passed to other
  functions. This is because the optimisation would be externally
  visible through backtraces, which is undesirable.
  Unfortunately, this is also the case where a lot of optimisation
  opportunity lies. Nonetheless, even with this limitation it seems like
  the optimisation can help a lot.
* The optimisation does not apply to functions using indirect variable
  access (e.g. variable-variables, compact()) and vararg functions.

Read the original on github.com ↗