-
Notifications
You must be signed in to change notification settings - Fork 7.8k
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
Fix circumvented added hooks in JIT #17870
Open
iluuu1994
wants to merge
4
commits into
php:PHP-8.4
Choose a base branch
from
iluuu1994:gh-17376-alt-2
base: PHP-8.4
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
+189
−16
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
iluuu1994
commented
Feb 20, 2025
nielsdos
reviewed
Feb 20, 2025
iluuu1994
commented
Feb 21, 2025
The following code poses a problem in the JIT: ```php class A { public $prop = 1; } class B extends A { public $prop = 1 { get => parent::$prop::get() * 2; } } function test(A $a) { var_dump($a->prop); } test(new B); ``` The JIT would assume A::$prop in test() could be accessed directly through OBJ_PROP_NUM(). However, since child classes can add new hooks to existing properties, this assumption no longer holds. To avoid introducing more JIT checks, a hooked property that overrides a unhooked property now results in a separate zval slot that is used instead of the parent slot. This causes the JIT to pick the slow path due to an IS_UNDEF value in the parent slot. zend_class_entry.properties_info_table poses a problem in that zend_get_property_info_for_slot() and friends will be called using the child slot, which does not store its property info, since the parent slot already does. In this case, zend_get_property_info_for_slot() now provides a fallback that will iterate all property infos to find the correct one. This also uncovered a bug (see Zend/tests/property_hooks/dump.phpt) where the default value of a parent property would accidentally be inherited by the child property. Fixes phpGH-17376
4cf0f0e
to
add3e2b
Compare
I have no clue what this Windows failure is about. 😞 I can't reproduce on Linux with asan/msan/valgrind, w/wo opcache, nts/zts, etc. @cmb69 Can you help? I don't have a VM... |
It's a JIT issue. Running ext\random\tests\02_engine\all_serialize_user.phpt under ASan/tracing JIT:
Does that help? |
Thank you very much! It might, I'll have a look very soon. |
Z_PROP_TABLE_OFFSET already gives us an index into a void* array. Thus, we only need to multiply by sizeof(void*).
Looks good. :) |
@cmb69 Indeed, it did help 😊 Thanks again! |
iluuu1994
commented
Feb 24, 2025
21ec227
to
060a409
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The following code poses a problem in the JIT:
The JIT would assume A::$prop in test() could be accessed directly through OBJ_PROP_NUM(). However, since child classes can add new hooks to existing properties, this assumption no longer holds.
To avoid introducing more JIT checks, a hooked property that overrides a unhooked property now results in a separate zval slot that is used instead of the parent slot. This causes the JIT to pick the slow path due to an IS_UNDEF value in the parent slot.
zend_class_entry.properties_info_table poses a problem in that zend_get_property_info_for_slot() and friends will be called using the child slot, which does not store its property info, since the parent slot already does. In this case, zend_get_property_info_for_slot() now provides a fallback that will iterate all property infos to find the correct one.
This also uncovered a bug (see Zend/tests/property_hooks/dump.phpt) where the default value of a parent property would accidentally be inherited by the child property.
Fixes GH-17376