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
Non recursive cyclic garbage collector #3889
Non recursive cyclic garbage collector #3889
Conversation
… linked list stack
but without removing last element logic # Conflicts: # Zend/zend_gc.c
…fore adding to stack
tail call optimizations looks good, even if it makes the code a bit harder to maintain
Also, I thought about removing tail call optimization that were of higher importance when functions were recursive. This would simplify the code. |
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.
Thanks for working on this. From the implementation side I think the main thing that needs to be improved is a different vector-backed stack implementation, as the current one is going to hurt GC performance a lot, due to the large amount of allocation it requires.
I'm also a bit concerned that this is going to add the same ref multiple times onto the stack, though I'm not sure what the best way to avoid this is. One possibility (taking black marking as an example) would be to mark the node black before adding it to the stack and only performing the examination of its children afterwards.
I think it would make sense to focus on the PHP 7.3 version of this, as I doubt we're going to land this on 7.2. Introducing major changes to GC this late in the release cycle would be quite adventurous. |
…ng will do nothing so we can avoid stack push pop
…e that many changes on return types of the changed functions improved the stack altering functions so that we can migrate to a different type of stack with minimal changes
The only thing to be done is to use an array-based stack.
When I started to investigate on the fix I had the same question whether the change is big and if I should do it for PHP-7.4 or PHP-7.2. As it's not a big effort for me in terms of merges, I'll keep the changes on PHP-7.2 branch. |
… to allocate/free memory
…ne for every root scan there will be 4 maximum stacks created during a gc_collect_cycles run
@nikic, I think I implemented all the problems and suggestions you mentioned except the one about the concern that a ref could be added multiple times to the stack. To not add the same ref more than once to the stack, we could have a hashset that we can use to remember if the ref is in the stack, so we have something like a unique_stack :). Because I'm used at my job to always have two code review approvals for any change, I'm going to ping also @dstogov for reviewing this PR as he is the top contributor for this file. |
…f color before processing it
I managed to implement not adding the same ref multiple times: What I changed was that the color changed before calling the function first, before tail recursion and before adding it to stack and not during processing. Unfortunately, there are quite several white-space changes as some if branches needed to disappear. If you're ok with that I can push it here already. |
@drealecs thanks for taking look into the problem. |
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 already looks much better from a perf perspective :) Your mechanism to prevent duplicate ref additions also makes sense to me.
Right. I think due to the size and potential risk of the change, it should only go into PHP-7.4. I mainly suggested PHP-7.3 because the GC implementation changed a lot relative to PHP-7.2 and it's become more likely to run into these kind of problems (simply because GC gets to deal with a lot more objects now). |
@dstogov, thank you. If you need any help, please let me know. |
…rk_grey, gc_scan and gc_collect_white also stack_black used for gc_scan_black is defined on stack instead of heap gc_refcounted_stack_init will not create a stack but just initialize internal array gc_refcounted_stack_destroy will not destroy a stack but just destroy internal array
As @nikic had a look at it, I also pushed here the change that avoids adding same ref to a stack multiple times. As I mentioned, I made all changes on this PR still pointing PHP-7.2 branch while maintaining 3 more branches for PHP-7.3, PHP-7.4 and master:
and then we compare the diffs in a graphic editor.
no change
change was already fixed in commit da3316f, present in PHP7.4
We have here many changes, almost all of them related to Also, the PR changes are not very complex so I still feel confident with this bug targeting PHP-7.2. Maybe we can merge the PHP-7.4 branch and after few weeks in, we can consider merging it for PHP-7.3 and PHP-7.2 if that feels safer for you. It's your call anyway :) |
Also, another topic of higher interest maybe: @nikic, could you make some benchmark tests as well, if you still have the scripts you used here?: #3165 (review) |
…n the stack, it can be skipped useful for white scanning after marking when the item might have been marked as black in the meantime and also to reduce whitespaces changes
For reference, PR for 7.3: #3923 |
As this was merged in 7.3, I'm going to close this PR for 7.2 |
This fixes https://bugs.php.net/bug.php?id=77345
Replace recursive calls in
gc_mark_grey
,gc_scan
,gc_scan_black
andgc_collect_white
logic with using a simple stack.Target version is 7.2.
So far it seems to work pretty well.
I'll wait for review.
I'll investigate what tests I can write. If you have something in mind different than the bug case (or a similar one), please share it.
Because with PHP 7.3 there are some changes in garbage collector, I maintained also a merged branch for it so that it will be easier when merging PHP-7.2 into PHP-7.3 and also to make sure it works: PHP-7.3...drealecs:non_recursive_cyclic_garbage_collector-7.3