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

Non recursive cyclic garbage collector 7.3 #3923

Closed

Conversation

dstogov
Copy link
Member

@dstogov dstogov commented Mar 6, 2019

No description provided.

but without removing last element logic

# Conflicts:
#	Zend/zend_gc.c
…cursive_cyclic_garbage_collector-7.3

# Conflicts:
#	Zend/zend_gc.c
tail call optimizations looks good, even if it makes the code a bit harder to maintain
…cursive_cyclic_garbage_collector-7.3

# Conflicts:
#	Zend/zend_gc.c
…ng will do nothing so we can avoid stack push pop
…cursive_cyclic_garbage_collector-7.3

# Conflicts:
#	Zend/zend_gc.c
…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
…cursive_cyclic_garbage_collector-7.3

# Conflicts:
#	Zend/zend_gc.c
…ne for every root scan

there will be 4 maximum stacks created during a gc_collect_cycles run
…cursive_cyclic_garbage_collector-7.3

# Conflicts:
#	Zend/zend_gc.c
…cursive_cyclic_garbage_collector-7.3

# Conflicts:
#	Zend/zend_gc.c
…cursive_cyclic_garbage_collector-7.3

# Conflicts:
#	Zend/zend_gc.c
…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
…cursive_cyclic_garbage_collector-7.3

# Conflicts:
#	Zend/zend_gc.c
…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
…cursive_cyclic_garbage_collector-7.3

# Conflicts:
#	Zend/zend_gc.c
@dstogov
Copy link
Member Author

dstogov commented Mar 6, 2019

@drealecs, @nikic I've made few improvements to the patch for PHP-7.3
If you don't see any problems, I may take care about merging this into 7.3 and above.

Zend/zend_gc.c Outdated Show resolved Hide resolved
return NULL;
} else {
(*stack) = (*stack)->prev;
(*top) = GC_STACK_SEGMENT_SIZE - 1;
Copy link

Choose a reason for hiding this comment

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

I guess you can assign (*top) = GC_STACK_SEGMENT_SIZE and remove return statement and inline else return block.
Following this you can inline the first else block as well as the if contained a return.
Apparently, code is easier to read without elses.

: _stack->data[--_top])
gc_stack_pop(&_stack, &_top)

static zend_never_inline gc_stack* gc_stack_next(gc_stack *stack)
Copy link

Choose a reason for hiding this comment

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

why is this zend_never_inline? It's used in only one place so it could have been manually inlined there so I imagine it could be inlined automatically also.

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 used in only one place, but that place is an always-inline function. We want to inline the fast-path of stack pushing to each use, but we don't want to inline the rarely called reallocation code.

Copy link
Member Author

Choose a reason for hiding this comment

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

right. It's not inlined on purpose, to reduce code size and improve register allocation on fast path.

Copy link
Member

@nikic nikic left a comment

Choose a reason for hiding this comment

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

Looks good. For the future we might want to consider if we can't make get_gc directly write to the stack. The way get_gc currently works is very inconvenient because non-trivial cases require the object to allocate (and keep around forever) a separate gc buffer. If we could just push to the stack in get_gc things would be simpler.

Zend/zend_gc.c Outdated Show resolved Hide resolved
tail_call:
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
ht = NULL;
do {
Copy link
Member

Choose a reason for hiding this comment

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

What's the reason for the switch from tail_call to do-while in this function?

Copy link
Member Author

Choose a reason for hiding this comment

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

I prefer to avoid "goto", if possible. I kept them in other places to minimize the patch.
Probably I'll re-factor the code in PHP-7.4 and master after merging this.

Zend/zend_gc.c Outdated Show resolved Hide resolved
@dstogov
Copy link
Member Author

dstogov commented Mar 7, 2019

Looks good. For the future we might want to consider if we can't make get_gc directly write to the stack. The way get_gc currently works is very inconvenient because non-trivial cases require the object to allocate (and keep around forever) a separate gc buffer. If we could just push to the stack in get_gc things would be simpler.

I agree about get_gc(), but this is for PHP-8 only, and probably, should be considered together with FE_FETCH improvements.

@nikic
Copy link
Member

nikic commented Mar 7, 2019

I agree about get_gc(), but this is for PHP-8 only, and probably, should be considered together with FE_FETCH improvements.

Yes, definitely for PHP 8 only. What improvements for FE_FETCH do you have in mind?

@dstogov
Copy link
Member Author

dstogov commented Mar 7, 2019

Yes, definitely for PHP 8 only. What improvements for FE_FETCH do you have in mind?

Avoid HashTable construction.

@dstogov
Copy link
Member Author

dstogov commented Mar 7, 2019

Merged into PHP-7.3 and above.

@dstogov dstogov closed this Mar 7, 2019
@drealecs
Copy link

drealecs commented Mar 7, 2019

Thank you for helping with everything, I'm happy with it being merged.

As with my previous benchmarks, I mentioned some performance improvements. I was wondering if we could measure the performance improvement for real applications and if anything changed there.

@dstogov
Copy link
Member Author

dstogov commented Mar 7, 2019

In my benchmarks on PHP-Parser, the number of executed GC instructions (measured by callgrind) was reduced from 137M to 132.5M. So, 3% GC improvement in term of executed instructions, but this is not directly related to CPU cycles and time.

@dstogov dstogov deleted the non_recursive_cyclic_garbage_collector-7.3 branch October 14, 2019 20:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants