-
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
Reduce gc stack usage for strings (and resources) #17194
Conversation
Adding strings to the worklist is useless, because they never contribute to cycles. The assembly size on x86_64 does not change. This significantly improves performance in this synthetic benchmark by 33%. function test($a) {} $a = new stdClass(); $a->self = $a; $a->prop1 = str_repeat('a', 10); $a->prop2 = str_repeat('a', 10); $a->prop3 = str_repeat('a', 10); $a->prop4 = str_repeat('a', 10); $a->prop5 = str_repeat('a', 10); $a->prop6 = str_repeat('a', 10); $a->prop7 = str_repeat('a', 10); $a->prop8 = str_repeat('a', 10); $a->prop9 = str_repeat('a', 10); $a->prop10 = str_repeat('a', 10); for ($i = 0; $i < 10_000_000; $i++) { test($a); gc_collect_cycles(); }
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.
Nice!
This looks good to me. @dstogov what do you think?
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 looks great!
Only one question: does this work properly with non-COLLECTABLE objects?
Can you clarify? I believe for objects, |
Right. I ask, can't this make problems for "acyclic objects"? Now GC collects all the garbage objects then call their destructors and then destroy them. With this patch "acyclic objects" are not going to be recognized as garbage (they will become "children" of the garbage). Therefore they are going to be destructed a bit differently. |
@dstogov Ah, I see. Yes, you are correct that the destruction is potentially different if acyclic objects are not part of the GC buffer, in that the objects will be destroyed through |
Adding strings to the worklist is useless, because they never contribute to cycles. The assembly size on x86_64 does not change. This significantly improves performance in this synthetic benchmark by 33%.
This requires adding
IS_TYPE_COLLECTABLE
toIS_REFERENCE_EX
to ensure these values continue to be pushed onto the stack. Luckily,IS_TYPE_COLLECTABLE
is currently only used ingc_check_possible_root()
, where the checked value cannot be a reference.Note that this changes the output of
gc_collect_cycles()
. Non-cyclic, refcounted values no longer count towards the total reported values collected.Also, there is some obvious overlap with GH-17130. This change should be good nonetheless, especially if we can remove the
GC_COLLECTABLE(Z_COUNTED_P(zv))
condition in PHP 9 and rely onZ_COLLECTABLE_P()
exclusively, given we can assume an object doesn't become cyclic at runtime anymore.