-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Test array argument in-place optimization #11167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
9de56dd
to
1c7b61f
Compare
bool(true) | ||
bool(true) | ||
bool(true) | ||
bool(false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is zend_get_zval_ptr
implemented correctly? It seems $ptrAfter === $ptrBefore
is always true, which is not expected here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to be aware of how zvals and arrays work behind the scenes.
A zval contains some data and some type information. For arrays this type is IS_ARRAY, and its data is a pointer to the array. When I do $a = $b
, a and b are two different zvals, but if b is an array, then a will point to the same array because the pointer is copied (and the array refcount is increased by one).
Similarly if you have:
$a = [];
$a = [1];
$a = [1, 2];
then the zend_get_zval_ptr
for $a will always return the same pointer for all three lines, because you're always asking the pointer for the container variable a. What you actually want to ask the engine is the pointer to the array (e.g. Z_ARRVAL_P(zval_pointer_for_a_here)`. Then you'll see that each line will have a different array pointer, while having the same zval pointer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that #11060 only introduces the optimisation for RC1 temporaries, not CVs. #11166 enables the optimisation for CVs.
@nielsdos $listInt
in the test should have RC = 1 (excl. in the foreach test), but still the results are very different vs. what I would expect, can you please give me an example of php code where variable is "RC1 temporaries" and where "CV"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mvorisek CVs are never RC1 when passed to a function. #11166 will change this but only work with opcache (and optimizations) enabled. TMP/VAR will be RC1 if allocated within a function and then returned, of when a new value is generated from a temporary expression (e.g. [0 => 1] + [1 => 2]
). range
is another way to generate a temporary array with RC1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So array_merge
function in $listInt = array_merge($listInt, []);
expr, when $listInt
had RC1 originally, will not be optimized, as array_merge
will receive RC2? If yes, then can the testing using the before/after PTR be done before #11166 is landed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So array_merge function in $listInt = array_merge($listInt, []); expr, when $listInt had RC1 originally, will not be optimized, as array_merge will receive RC2?
Right
If yes, then can the testing using the before/after PTR be done before #11166 is landed?
Sure, but that will only work in a limited context. E.g. pseudo main (root of the file) won't work, so you'll need to wrap it in a separate function. And as mentioned above, it will only work when opcache is enabled, as the optimizer otherwise doesn't run.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's wait until that PR is merged and keep this one separate. Otherwise it will be a back and forth between us two which is a lot of overhead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is factors longer than the original implementation. A simple test seems sensible, but I don't think we need all of these variations.
d138d35
to
749f32a
Compare
749f32a
to
7236263
Compare
can be reopened if #11166 is merged |
assert the in-place optimilizations introduced in #11060 by a test