Skip to content
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

Use zend_std_build_properties() to access zend_object.properties #14996

Closed
wants to merge 1 commit into from

Conversation

arnaud-lb
Copy link
Member

@arnaud-lb arnaud-lb commented Jul 17, 2024

The zend_object.properties HashTable needs to be built just in time by calling rebuild_object_properties() on the object before accessing it. Normally this is done automatically in zend_std_get_properties(), but we do it manually in a few places, like this:

php-src/Zend/zend_API.c

Lines 1782 to 1785 in 7d99a9c

if (!object->properties) {
rebuild_object_properties(object);
}
prop = zend_hash_index_update(object->properties, h, prop);

In this PR I refactor these places to use zend_std_get_properties() instead. I also make rebuild_object_properties() static to enforce usage of zend_std_get_properties().

This refactoring will be useful in the context of the lazy objects RFC, as the zend_std_get_properties() function becomes a single entry point for zend_object.properties where we can initialize a lazy object.

cc @TimWolla

Copy link
Member

@Girgias Girgias left a comment

Choose a reason for hiding this comment

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

ACK for SPL and PDO.

This also makes the API simpler and clearer, which is good IMHO

Copy link
Contributor

@zeriyoshi zeriyoshi left a comment

Choose a reason for hiding this comment

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

LGTM ext-random!

Copy link
Member

@SakiTakamachi SakiTakamachi left a comment

Choose a reason for hiding this comment

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

I looked at everything except zend_vm. Looks good :)

Copy link
Member

@TimWolla TimWolla left a comment

Choose a reason for hiding this comment

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

We've talked about this before. Thank you, this LGTM.

One question though: I suggested moving zend_std_get_properties() into the header and making it static inline, because the implementation is trivial. This would require making rebuild_object_properties non-static again. Do you still intend to do that?

ext/date/php_date.c Outdated Show resolved Hide resolved
@@ -62,7 +62,7 @@
called, we cal __call handler.
*/

ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */
static void rebuild_object_properties(zend_object *zobj) /* {{{ */
Copy link
Contributor

Choose a reason for hiding this comment

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

since something no-longer is ZEND_API which was before, does this need to be noted in some changelog/releasenotes ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed. I usually update the UPGRADING files separately, as our merge strategy for those tends to lose the changes.

@arnaud-lb
Copy link
Member Author

@TimWolla

One question though: I suggested moving zend_std_get_properties() into the header and making it static inline, because the implementation is trivial. This would require making rebuild_object_properties non-static again. Do you still intend to do that?

I forgot about this part of your suggestion.

I've now inlined the zend_std_get_properties calls, but in a slightly different way: Introduced zend_std_get_properties_ex(), which is an inlined version of zend_std_get_properties(). This is similar to what we do in zend_atomics (but for different reasons). I didn't inline zend_std_get_properties() directly because we take the address of this function, and there are a few places where we compare its address like here.

An alternative would have been to introduce a non-handler function with a name like zend_get_properties, like we have for zend_get_properties_for, but I feel that code using rebuild_object_properties() want to specifically rely on the behavior of zend_std_get_properties(). Also, zend_get_properties would have used object->handlers->get_properties which defeats inlining.

Copy link
Member

@TimWolla TimWolla left a comment

Choose a reason for hiding this comment

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

LGTM, maybe add a short note to UPGRADING.INTERNALS.

The zend_object.properties HashTable needs to be built just in time by calling
rebuild_object_properties() on the object before accessing it. Normally this is
done automatically in zend_std_get_properties(), but we do it manually in a few
places.

In this change I introduce an inline variant of zend_std_build_properties(), and
refactor these places to use it instead of calling rebuild_object_properties()
manually.

rebuild_object_properties() is made static to enforce usage of
zend_std_get_properties() or zend_std_build_properties_ex().
@arnaud-lb
Copy link
Member Author

I figured that calling rebuild_object_properties(), which is un-exported by this change, from an inline function may be problematic. So I've re-exported it, and renamed it to force external code to notice the change.

Copy link
Member

@TimWolla TimWolla left a comment

Choose a reason for hiding this comment

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

Still LGTM

@arnaud-lb arnaud-lb closed this in 1fbb666 Jul 18, 2024
Comment on lines 63 to +65
*/

ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */
ZEND_API void rebuild_object_properties_internal(zend_object *zobj) /* {{{ */
Copy link
Member

Choose a reason for hiding this comment

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

As the API is changed anyway, it makes sense to return HashTable and avoid extra load of zobj->properties in zend_std_get_properties[_ex].

/* Use zend_std_get_properties_ex() */
ZEND_API void rebuild_object_properties_internal(zend_object *zobj);

static inline HashTable *zend_std_get_properties_ex(zend_object *object)
Copy link
Member

Choose a reason for hiding this comment

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

It's better to use zend_always_inline

arnaud-lb added a commit to arnaud-lb/php-src that referenced this pull request Jul 22, 2024
@arnaud-lb arnaud-lb mentioned this pull request Jul 22, 2024
arnaud-lb added a commit that referenced this pull request Jul 22, 2024
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.

7 participants