6868 */
6969#include "zend.h"
7070#include "zend_API.h"
71+ #include "zend_atomic.h"
7172#include "zend_compile.h"
7273#include "zend_errors.h"
7374#include "zend_fibers.h"
@@ -687,7 +688,19 @@ static void gc_adjust_threshold(int count)
687688 }
688689}
689690
690- /* Perform a GC run and then add a node as a possible root. */
691+ static void gc_request_run (void )
692+ {
693+ zend_atomic_bool_store_ex (& EG (gc_requested ), true);
694+ zend_atomic_bool_store_ex (& EG (vm_interrupt ), true);
695+ }
696+
697+ void gc_handle_requested_run (void )
698+ {
699+ zend_atomic_bool_store_ex (& EG (gc_requested ), false);
700+ gc_adjust_threshold (gc_collect_cycles ());
701+ }
702+
703+ /* Add a node as a possible root and request a GC run. */
691704static zend_never_inline void ZEND_FASTCALL gc_possible_root_when_full (zend_refcounted * ref )
692705{
693706 uint32_t idx ;
@@ -696,20 +709,8 @@ static zend_never_inline void ZEND_FASTCALL gc_possible_root_when_full(zend_refc
696709 ZEND_ASSERT (GC_TYPE (ref ) == IS_ARRAY || GC_TYPE (ref ) == IS_OBJECT );
697710 ZEND_ASSERT (GC_INFO (ref ) == 0 );
698711
699- if (GC_G (gc_enabled ) && !GC_G (gc_active )) {
700- GC_ADDREF (ref );
701- gc_adjust_threshold (gc_collect_cycles ());
702- if (UNEXPECTED (GC_DELREF (ref ) == 0 )) {
703- rc_dtor_func (ref );
704- return ;
705- } else if (UNEXPECTED (GC_INFO (ref ))) {
706- return ;
707- }
708- }
709-
710- if (GC_HAS_UNUSED ()) {
711- idx = GC_FETCH_UNUSED ();
712- } else if (EXPECTED (GC_HAS_NEXT_UNUSED ())) {
712+ ZEND_ASSERT (!GC_HAS_UNUSED ());
713+ if (EXPECTED (GC_HAS_NEXT_UNUSED ())) {
713714 idx = GC_FETCH_NEXT_UNUSED ();
714715 } else {
715716 gc_grow_root_buffer ();
@@ -730,6 +731,10 @@ static zend_never_inline void ZEND_FASTCALL gc_possible_root_when_full(zend_refc
730731 GC_BENCH_INC (zval_buffered );
731732 GC_BENCH_INC (root_buf_length );
732733 GC_BENCH_PEAK (root_buf_peak , root_buf_length );
734+
735+ if (GC_G (gc_enabled ) && !GC_G (gc_active )) {
736+ gc_request_run ();
737+ }
733738}
734739
735740/* Add a possible root node to the buffer.
0 commit comments