252252
253253ZEND_API int (* gc_collect_cycles )(void );
254254
255+ /*
256+ * The type of a root buffer entry.
257+ *
258+ * The lower two bits are used for flags and need to be masked out to
259+ * reconstruct a pointer.
260+ *
261+ * When a node in the root buffer is removed, the non-flag bits of the
262+ * unused entry are used to store the index of the next entry in the unused
263+ * list. */
255264typedef struct _gc_root_buffer {
256265 zend_refcounted * ref ;
257266} gc_root_buffer ;
@@ -260,14 +269,7 @@ typedef struct _zend_gc_globals {
260269 /*
261270 * The root buffer, which stores possible roots of reference cycles. It is
262271 * also used to store garbage to be collected at the end of a run.
263- * A single array which is reallocated as necessary.
264- *
265- * The lower two bits in each entry are used for flags and need to be masked
266- * out to reconstruct a pointer.
267- *
268- * When an object in the root buffer is removed, the non-flag bits of the
269- * unused entry are used to store the index of the next entry in the unused
270- * list. */
272+ * A single array which is reallocated as necessary. */
271273 gc_root_buffer * buf ;
272274
273275 bool gc_enabled ;
@@ -282,12 +284,12 @@ typedef struct _zend_gc_globals {
282284 uint32_t num_roots ; /* number of roots in GC buffer */
283285
284286 uint32_t gc_runs ; /* number of GC runs since reset */
285- uint32_t collected ; /* number of collected objects since reset */
287+ uint32_t collected ; /* number of collected nodes since reset */
286288
287289 zend_hrtime_t activated_at ; /* the timestamp of the last reset */
288290 zend_hrtime_t collector_time ; /* time spent running GC (ns) */
289291 zend_hrtime_t dtor_time ; /* time spent calling destructors (ns) */
290- zend_hrtime_t free_time ; /* time spent destroying objects and freeing memory (ns) */
292+ zend_hrtime_t free_time ; /* time spent destroying nodes and freeing memory (ns) */
291293
292294 uint32_t dtor_idx ; /* root buffer index */
293295 uint32_t dtor_end ;
@@ -400,8 +402,8 @@ static void gc_stack_free(gc_stack *stack)
400402 * Map a full index to a compressed index.
401403 *
402404 * The root buffer can have up to 2^30 entries, but we only have 20 bits to
403- * store the index. So we use the 1<<19 as a compression flag and use the other
404- * 19 bits to store the index modulo 2^19. */
405+ * store the index. So we use the 1<<19 bit as a compression flag and use the
406+ * other 19 bits to store the index modulo 2^19. */
405407static zend_always_inline uint32_t gc_compress (uint32_t idx )
406408{
407409 if (EXPECTED (idx < GC_MAX_UNCOMPRESSED )) {
@@ -506,7 +508,6 @@ static zend_always_inline void gc_remove_from_roots(gc_root_buffer *root)
506508 GC_BENCH_DEC (root_buf_length );
507509}
508510
509- /* Destroy the root buffer */
510511static void root_buffer_dtor (zend_gc_globals * gc_globals )
511512{
512513 if (gc_globals -> buf ) {
@@ -636,7 +637,6 @@ ZEND_API bool gc_protected(void)
636637 return GC_G (gc_protected );
637638}
638639
639- /* Reallocate the GC root buffer */
640640static void gc_grow_root_buffer (void )
641641{
642642 size_t new_size ;
@@ -662,7 +662,7 @@ static void gc_grow_root_buffer(void)
662662 GC_G (buf_size ) = new_size ;
663663}
664664
665- /* Adjust the GC activation threshold given the number of objects collected by the last run */
665+ /* Adjust the GC activation threshold given the number of nodes collected by the last run */
666666static void gc_adjust_threshold (int count )
667667{
668668 uint32_t new_threshold ;
@@ -693,7 +693,7 @@ static void gc_adjust_threshold(int count)
693693 }
694694}
695695
696- /* Add an object as a possible root, and perform a GC run unless one is active already . */
696+ /* Perform a GC run and then add a node as a possible root . */
697697static zend_never_inline void ZEND_FASTCALL gc_possible_root_when_full (zend_refcounted * ref )
698698{
699699 uint32_t idx ;
@@ -738,7 +738,7 @@ static zend_never_inline void ZEND_FASTCALL gc_possible_root_when_full(zend_refc
738738 GC_BENCH_PEAK (root_buf_peak , root_buf_length );
739739}
740740
741- /* Add a possible root object to the buffer.
741+ /* Add a possible root node to the buffer.
742742 * Maybe perform a GC run. */
743743ZEND_API void ZEND_FASTCALL gc_possible_root (zend_refcounted * ref )
744744{
@@ -810,14 +810,13 @@ static void ZEND_FASTCALL gc_extra_root(zend_refcounted *ref)
810810 GC_BENCH_PEAK (root_buf_peak , root_buf_length );
811811}
812812
813- /* Remove an object from the root buffer given its compressed index */
813+ /* Remove a node from the root buffer given its compressed index */
814814static zend_never_inline void ZEND_FASTCALL gc_remove_compressed (zend_refcounted * ref , uint32_t idx )
815815{
816816 gc_root_buffer * root = gc_decompress (ref , idx );
817817 gc_remove_from_roots (root );
818818}
819819
820- /* Remove an object from the root buffer */
821820ZEND_API void ZEND_FASTCALL gc_remove_from_buffer (zend_refcounted * ref )
822821{
823822 gc_root_buffer * root ;
@@ -841,10 +840,10 @@ ZEND_API void ZEND_FASTCALL gc_remove_from_buffer(zend_refcounted *ref)
841840 gc_remove_from_roots (root );
842841}
843842
844- /* Traverse the graph of objects referred to by ref. Change grey objects back
845- * to black, and restore their reference counts . See ScanBlack() in Bacon & Rajan.
846- * To implement a depth-first search, discovered objects are added to a stack which
847- * is processed iteratively. */
843+ /* Mark all nodes reachable from ref as black (live). Restore the reference
844+ * counts decremented by gc_mark_grey() . See ScanBlack() in Bacon & Rajan.
845+ * To implement a depth-first search, discovered nodes are added to a stack
846+ * which is processed iteratively. */
848847static void gc_scan_black (zend_refcounted * ref , gc_stack * stack )
849848{
850849 HashTable * ht ;
@@ -1044,8 +1043,8 @@ static void gc_scan_black(zend_refcounted *ref, gc_stack *stack)
10441043 }
10451044}
10461045
1047- /* Traverse the graph of objects referred to by ref. Decrement the reference
1048- * counts and mark visited objects grey. See MarkGray() in Bacon & Rajan. */
1046+ /* Traverse the graph of nodes referred to by ref. Decrement the reference
1047+ * counts and mark visited nodes grey. See MarkGray() in Bacon & Rajan. */
10491048static void gc_mark_grey (zend_refcounted * ref , gc_stack * stack )
10501049{
10511050 HashTable * ht ;
@@ -1258,8 +1257,9 @@ static void gc_compact(void)
12581257 }
12591258}
12601259
1261- /* For all roots marked purple, traverse the graph, marking referred objects grey.
1262- * See MarkRoots() in Bacon & Rajan. */
1260+ /* For all roots marked purple, traverse the graph, decrementing the reference
1261+ * count of visited nodes. Mark visited nodes grey so that their reference
1262+ * counts will only be decremented once. See MarkRoots() in Bacon & Rajan. */
12631263static void gc_mark_roots (gc_stack * stack )
12641264{
12651265 gc_root_buffer * current , * last ;
@@ -1470,7 +1470,7 @@ static void gc_scan_roots(gc_stack *stack)
14701470 }
14711471}
14721472
1473- /* Add an object to the buffer with the garbage flag, so that it will be
1473+ /* Add a node to the buffer with the garbage flag, so that it will be
14741474 * destroyed and freed when the scan is complete. */
14751475static void gc_add_garbage (zend_refcounted * ref )
14761476{
@@ -1497,7 +1497,7 @@ static void gc_add_garbage(zend_refcounted *ref)
14971497 GC_G (num_roots )++ ;
14981498}
14991499
1500- /* Traverse the reference graph from ref, marking any white objects as garbage. */
1500+ /* Traverse the reference graph from ref, marking any white nodes as garbage. */
15011501static int gc_collect_white (zend_refcounted * ref , uint32_t * flags , gc_stack * stack )
15021502{
15031503 int count = 0 ;
0 commit comments