Skip to content

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

Closed
wants to merge 1 commit into from

Conversation

mvorisek
Copy link
Contributor

assert the in-place optimilizations introduced in #11060 by a test

@mvorisek mvorisek force-pushed the test_array_merge_optimization branch from 9de56dd to 1c7b61f Compare April 30, 2023 16:26
@mvorisek mvorisek changed the title Test array argument in-place optimization (when the refcount is 1) Test array argument in-place optimization Apr 30, 2023
@nielsdos
Copy link
Member

Note that #11060 only introduces the optimisation for RC1 temporaries, not CVs. #11166 enables the optimisation for CVs.

bool(true)
bool(true)
bool(true)
bool(false)
Copy link
Contributor Author

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.

Copy link
Member

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.

Copy link
Contributor Author

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"?

Copy link
Member

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.

Copy link
Contributor Author

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?

Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nielsdos would you be ok to add this test to your #11166 directly?

Copy link
Member

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.

Copy link
Member

@iluuu1994 iluuu1994 left a 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.

@mvorisek mvorisek force-pushed the test_array_merge_optimization branch 2 times, most recently from d138d35 to 749f32a Compare April 30, 2023 17:17
@mvorisek mvorisek force-pushed the test_array_merge_optimization branch from 749f32a to 7236263 Compare April 30, 2023 18:28
@mvorisek
Copy link
Contributor Author

can be reopened if #11166 is merged

@mvorisek mvorisek closed this Aug 12, 2023
@mvorisek mvorisek deleted the test_array_merge_optimization branch August 12, 2023 10:37
@mvorisek mvorisek restored the test_array_merge_optimization branch October 16, 2023 11:27
@mvorisek mvorisek deleted the test_array_merge_optimization branch October 16, 2023 11:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants