php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
zend_gc.c File Reference
#include "zend.h"
#include "zend_API.h"
#include "zend_compile.h"
#include "zend_errors.h"
#include "zend_fibers.h"
#include "zend_hrtime.h"
#include "zend_portability.h"
#include "zend_types.h"
#include "zend_weakrefs.h"
#include "zend_string.h"

Go to the source code of this file.

Data Structures

struct  _gc_root_buffer
 
struct  _zend_gc_globals
 
struct  _gc_stack
 

Macros

#define ZEND_GC_DEBUG   0
 
#define GC_ADDRESS   0x0fffffu
 
#define GC_COLOR   0x300000u
 
#define GC_BLACK   0x000000u /* must be zero */
 
#define GC_WHITE   0x100000u
 
#define GC_GREY   0x200000u
 
#define GC_PURPLE   0x300000u
 
#define GC_TRACE_REF(ref, format, ...)
 
#define GC_TRACE_SET_COLOR(ref, new_color)
 
#define GC_TRACE(str)
 
#define GC_REF_ADDRESS(ref)
 
#define GC_REF_COLOR(ref)
 
#define GC_REF_CHECK_COLOR(ref, color)
 
#define GC_REF_SET_INFO(ref, info)
 
#define GC_REF_SET_COLOR(ref, c)
 
#define GC_REF_SET_BLACK(ref)
 
#define GC_REF_SET_PURPLE(ref)
 
#define GC_BITS   0x3
 
#define GC_ROOT   0x0 /* possible root of circular garbage */
 
#define GC_UNUSED   0x1 /* part of linked list of unused buffers */
 
#define GC_GARBAGE   0x2 /* garbage to delete */
 
#define GC_DTOR_GARBAGE   0x3 /* garbage on which only the dtor should be invoked */
 
#define GC_GET_PTR(ptr)
 
#define GC_IS_ROOT(ptr)
 
#define GC_IS_UNUSED(ptr)
 
#define GC_IS_GARBAGE(ptr)
 
#define GC_IS_DTOR_GARBAGE(ptr)
 
#define GC_MAKE_GARBAGE(ptr)
 
#define GC_MAKE_DTOR_GARBAGE(ptr)
 
#define GC_IDX2PTR(idx)
 
#define GC_PTR2IDX(ptr)
 
#define GC_IDX2LIST(idx)
 
#define GC_LIST2IDX(list)
 
#define GC_INVALID   0
 
#define GC_FIRST_ROOT   1
 
#define GC_DEFAULT_BUF_SIZE   (16 * 1024)
 
#define GC_BUF_GROW_STEP   (128 * 1024)
 
#define GC_MAX_UNCOMPRESSED   (512 * 1024)
 
#define GC_MAX_BUF_SIZE   0x40000000
 
#define GC_THRESHOLD_DEFAULT   (10000 + GC_FIRST_ROOT)
 
#define GC_THRESHOLD_STEP   10000
 
#define GC_THRESHOLD_MAX   1000000000
 
#define GC_THRESHOLD_TRIGGER   100
 
#define GC_HAS_DESTRUCTORS   (1<<0)
 
#define Z_FROM_WEAKMAP_KEY   (1<<0)
 
#define Z_FROM_WEAKMAP   (1<<1)
 
#define GC_FROM_WEAKMAP_KEY(zv)
 
#define GC_SET_FROM_WEAKMAP_KEY(zv)
 
#define GC_UNSET_FROM_WEAKMAP_KEY(zv)
 
#define GC_FROM_WEAKMAP(zv)
 
#define GC_SET_FROM_WEAKMAP(zv)
 
#define GC_UNSET_FROM_WEAKMAP(zv)
 
#define GC_HAS_UNUSED()
 
#define GC_FETCH_UNUSED()
 
#define GC_LINK_UNUSED(root)
 
#define GC_HAS_NEXT_UNUSED_UNDER_THRESHOLD()
 
#define GC_HAS_NEXT_UNUSED()
 
#define GC_FETCH_NEXT_UNUSED()
 
#define GC_G(v)
 
#define GC_BENCH_INC(counter)
 
#define GC_BENCH_DEC(counter)
 
#define GC_BENCH_PEAK(peak, counter)
 
#define GC_STACK_SEGMENT_SIZE   (((4096 - ZEND_MM_OVERHEAD) / sizeof(void*)) - 2)
 
#define GC_STACK_DCL(init)
 
#define GC_STACK_PUSH(ref)
 
#define GC_STACK_POP()
 

Typedefs

typedef struct _gc_root_buffer gc_root_buffer
 
typedef struct _zend_gc_globals zend_gc_globals
 
typedef struct _gc_stack gc_stack
 

Functions

void gc_globals_ctor (void)
 
void gc_globals_dtor (void)
 
void gc_reset (void)
 
ZEND_API bool gc_enable (bool enable)
 
ZEND_API bool gc_enabled (void)
 
ZEND_API bool gc_protect (bool protect)
 
ZEND_API bool gc_protected (void)
 
ZEND_API void ZEND_FASTCALL gc_possible_root (zend_refcounted *ref)
 
ZEND_API void ZEND_FASTCALL gc_remove_from_buffer (zend_refcounted *ref)
 
ZEND_API int zend_gc_collect_cycles (void)
 
ZEND_API void zend_gc_get_status (zend_gc_status *status)
 
ZEND_API zend_get_gc_bufferzend_get_gc_buffer_create (void)
 
ZEND_API void zend_get_gc_buffer_grow (zend_get_gc_buffer *gc_buffer)
 
void gc_init (void)
 

Variables

ZEND_API int(* gc_collect_cycles )(void)
 

Macro Definition Documentation

◆ GC_ADDRESS

#define GC_ADDRESS   0x0fffffu

Definition at line 89 of file zend_gc.c.

◆ GC_BENCH_DEC

#define GC_BENCH_DEC ( counter)

Definition at line 307 of file zend_gc.c.

◆ GC_BENCH_INC

#define GC_BENCH_INC ( counter)

Definition at line 306 of file zend_gc.c.

◆ GC_BENCH_PEAK

#define GC_BENCH_PEAK ( peak,
counter )

Definition at line 308 of file zend_gc.c.

◆ GC_BITS

#define GC_BITS   0x3

Definition at line 147 of file zend_gc.c.

◆ GC_BLACK

#define GC_BLACK   0x000000u /* must be zero */

Definition at line 92 of file zend_gc.c.

◆ GC_BUF_GROW_STEP

#define GC_BUF_GROW_STEP   (128 * 1024)

Definition at line 183 of file zend_gc.c.

◆ GC_COLOR

#define GC_COLOR   0x300000u

Definition at line 90 of file zend_gc.c.

◆ GC_DEFAULT_BUF_SIZE

#define GC_DEFAULT_BUF_SIZE   (16 * 1024)

Definition at line 182 of file zend_gc.c.

◆ GC_DTOR_GARBAGE

#define GC_DTOR_GARBAGE   0x3 /* garbage on which only the dtor should be invoked */

Definition at line 152 of file zend_gc.c.

◆ GC_FETCH_NEXT_UNUSED

#define GC_FETCH_NEXT_UNUSED ( )
Value:
gc_fetch_next_unused()

Definition at line 242 of file zend_gc.c.

◆ GC_FETCH_UNUSED

#define GC_FETCH_UNUSED ( )
Value:
gc_fetch_unused()

Definition at line 233 of file zend_gc.c.

◆ GC_FIRST_ROOT

#define GC_FIRST_ROOT   1

Definition at line 180 of file zend_gc.c.

◆ GC_FROM_WEAKMAP

#define GC_FROM_WEAKMAP ( zv)
Value:
zval * zv
Definition ffi.c:3975
#define Z_FROM_WEAKMAP
Definition zend_gc.c:198
#define Z_TYPE_INFO_P(zval_p)
Definition zend_types.h:669
#define Z_TYPE_INFO_EXTRA_SHIFT
Definition zend_types.h:705

Definition at line 217 of file zend_gc.c.

◆ GC_FROM_WEAKMAP_KEY

#define GC_FROM_WEAKMAP_KEY ( zv)
Value:

Definition at line 202 of file zend_gc.c.

◆ GC_G

#define GC_G ( v)
Value:
(gc_globals.v)

Definition at line 293 of file zend_gc.c.

◆ GC_GARBAGE

#define GC_GARBAGE   0x2 /* garbage to delete */

Definition at line 151 of file zend_gc.c.

◆ GC_GET_PTR

#define GC_GET_PTR ( ptr)
Value:
((void*)(((uintptr_t)(ptr)) & ~GC_BITS))
void * ptr
Definition ffi.c:3814
#define GC_BITS
Definition zend_gc.c:147

Definition at line 154 of file zend_gc.c.

◆ GC_GREY

#define GC_GREY   0x200000u

Definition at line 94 of file zend_gc.c.

◆ GC_HAS_DESTRUCTORS

#define GC_HAS_DESTRUCTORS   (1<<0)

Definition at line 194 of file zend_gc.c.

◆ GC_HAS_NEXT_UNUSED

#define GC_HAS_NEXT_UNUSED ( )
Value:
(GC_G(first_unused) != GC_G(buf_size))
#define GC_G(v)
Definition zend_gc.c:293

Definition at line 240 of file zend_gc.c.

◆ GC_HAS_NEXT_UNUSED_UNDER_THRESHOLD

#define GC_HAS_NEXT_UNUSED_UNDER_THRESHOLD ( )
Value:
(GC_G(first_unused) < GC_G(gc_threshold))

Definition at line 238 of file zend_gc.c.

◆ GC_HAS_UNUSED

#define GC_HAS_UNUSED ( )
Value:
(GC_G(unused) != GC_INVALID)
#define GC_INVALID
Definition zend_gc.c:179

Definition at line 231 of file zend_gc.c.

◆ GC_IDX2LIST

#define GC_IDX2LIST ( idx)
Value:
((void*)(uintptr_t)(((idx) * sizeof(void*)) | GC_UNUSED))
#define GC_UNUSED
Definition zend_gc.c:150

Definition at line 175 of file zend_gc.c.

◆ GC_IDX2PTR

#define GC_IDX2PTR ( idx)
Value:
(GC_G(buf) + (idx))
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685

Definition at line 172 of file zend_gc.c.

◆ GC_INVALID

#define GC_INVALID   0

Definition at line 179 of file zend_gc.c.

◆ GC_IS_DTOR_GARBAGE

#define GC_IS_DTOR_GARBAGE ( ptr)
Value:
((((uintptr_t)(ptr)) & GC_BITS) == GC_DTOR_GARBAGE)
#define GC_DTOR_GARBAGE
Definition zend_gc.c:152

Definition at line 163 of file zend_gc.c.

◆ GC_IS_GARBAGE

#define GC_IS_GARBAGE ( ptr)
Value:
((((uintptr_t)(ptr)) & GC_BITS) == GC_GARBAGE)
#define GC_GARBAGE
Definition zend_gc.c:151

Definition at line 161 of file zend_gc.c.

◆ GC_IS_ROOT

#define GC_IS_ROOT ( ptr)
Value:
((((uintptr_t)(ptr)) & GC_BITS) == GC_ROOT)
#define GC_ROOT
Definition zend_gc.c:149

Definition at line 157 of file zend_gc.c.

◆ GC_IS_UNUSED

#define GC_IS_UNUSED ( ptr)
Value:
((((uintptr_t)(ptr)) & GC_BITS) == GC_UNUSED)

Definition at line 159 of file zend_gc.c.

◆ GC_LINK_UNUSED

#define GC_LINK_UNUSED ( root)
Value:
gc_link_unused(root)

Definition at line 235 of file zend_gc.c.

◆ GC_LIST2IDX

#define GC_LIST2IDX ( list)
Value:
(((uint32_t)(uintptr_t)(list)) / sizeof(void*))

Definition at line 176 of file zend_gc.c.

◆ GC_MAKE_DTOR_GARBAGE

#define GC_MAKE_DTOR_GARBAGE ( ptr)
Value:
((void*)(((uintptr_t)(ptr)) | GC_DTOR_GARBAGE))

Definition at line 168 of file zend_gc.c.

◆ GC_MAKE_GARBAGE

#define GC_MAKE_GARBAGE ( ptr)
Value:
((void*)(((uintptr_t)(ptr)) | GC_GARBAGE))

Definition at line 166 of file zend_gc.c.

◆ GC_MAX_BUF_SIZE

#define GC_MAX_BUF_SIZE   0x40000000

Definition at line 186 of file zend_gc.c.

◆ GC_MAX_UNCOMPRESSED

#define GC_MAX_UNCOMPRESSED   (512 * 1024)

Definition at line 185 of file zend_gc.c.

◆ GC_PTR2IDX

#define GC_PTR2IDX ( ptr)
Value:
((ptr) - GC_G(buf))

Definition at line 173 of file zend_gc.c.

◆ GC_PURPLE

#define GC_PURPLE   0x300000u

Definition at line 95 of file zend_gc.c.

◆ GC_REF_ADDRESS

#define GC_REF_ADDRESS ( ref)
Value:
#define GC_ADDRESS
Definition zend_gc.c:89
#define GC_INFO_SHIFT
Definition zend_types.h:740
#define GC_TYPE_INFO(p)
Definition zend_types.h:754

Definition at line 114 of file zend_gc.c.

◆ GC_REF_CHECK_COLOR

#define GC_REF_CHECK_COLOR ( ref,
color )
Value:
short color
#define GC_COLOR
Definition zend_gc.c:90

Definition at line 120 of file zend_gc.c.

◆ GC_REF_COLOR

#define GC_REF_COLOR ( ref)
Value:

Definition at line 117 of file zend_gc.c.

◆ GC_REF_SET_BLACK

#define GC_REF_SET_BLACK ( ref)
Value:
do { \
GC_TRACE_SET_COLOR(ref, GC_BLACK); \
GC_TYPE_INFO(ref) &= ~(GC_COLOR << GC_INFO_SHIFT); \
} while (0)
#define GC_BLACK
Definition zend_gc.c:92

Definition at line 136 of file zend_gc.c.

◆ GC_REF_SET_COLOR

#define GC_REF_SET_COLOR ( ref,
c )
Value:
do { \
GC_TRACE_SET_COLOR(ref, c); \
GC_TYPE_INFO(ref) = \
(GC_TYPE_INFO(ref) & ~(GC_COLOR << GC_INFO_SHIFT)) | \
((c) << GC_INFO_SHIFT); \
} while (0)

Definition at line 129 of file zend_gc.c.

◆ GC_REF_SET_INFO

#define GC_REF_SET_INFO ( ref,
info )
Value:
do { \
GC_TYPE_INFO(ref) = \
((info) << GC_INFO_SHIFT); \
} while (0)
#define GC_FLAGS_MASK
Definition zend_types.h:737
#define GC_TYPE_MASK
Definition zend_types.h:736

Definition at line 123 of file zend_gc.c.

◆ GC_REF_SET_PURPLE

#define GC_REF_SET_PURPLE ( ref)
Value:
do { \
GC_TRACE_SET_COLOR(ref, GC_PURPLE); \
GC_TYPE_INFO(ref) |= (GC_COLOR << GC_INFO_SHIFT); \
} while (0)
#define GC_PURPLE
Definition zend_gc.c:95

Definition at line 141 of file zend_gc.c.

◆ GC_ROOT

#define GC_ROOT   0x0 /* possible root of circular garbage */

Definition at line 149 of file zend_gc.c.

◆ GC_SET_FROM_WEAKMAP

#define GC_SET_FROM_WEAKMAP ( zv)
Value:
do { \
zval *_z = (zv); \
Z_TYPE_INFO_P(_z) = Z_TYPE_INFO_P(_z) | (Z_FROM_WEAKMAP << Z_TYPE_INFO_EXTRA_SHIFT); \
} while (0)
struct _zval_struct zval

Definition at line 220 of file zend_gc.c.

◆ GC_SET_FROM_WEAKMAP_KEY

#define GC_SET_FROM_WEAKMAP_KEY ( zv)
Value:
do { \
zval *_z = (zv); \
Z_TYPE_INFO_P(_z) = Z_TYPE_INFO_P(_z) | (Z_FROM_WEAKMAP_KEY << Z_TYPE_INFO_EXTRA_SHIFT); \
} while (0)

Definition at line 205 of file zend_gc.c.

◆ GC_STACK_DCL

#define GC_STACK_DCL ( init)
Value:
gc_stack *_stack = init; \
size_t _top = 0;
struct _gc_stack gc_stack
Definition zend_gc.c:314

Definition at line 322 of file zend_gc.c.

◆ GC_STACK_POP

#define GC_STACK_POP ( )
Value:
gc_stack_pop(&_stack, &_top)

Definition at line 329 of file zend_gc.c.

◆ GC_STACK_PUSH

#define GC_STACK_PUSH ( ref)
Value:
gc_stack_push(&_stack, &_top, ref);

Definition at line 326 of file zend_gc.c.

◆ GC_STACK_SEGMENT_SIZE

#define GC_STACK_SEGMENT_SIZE   (((4096 - ZEND_MM_OVERHEAD) / sizeof(void*)) - 2)

Definition at line 312 of file zend_gc.c.

◆ GC_THRESHOLD_DEFAULT

#define GC_THRESHOLD_DEFAULT   (10000 + GC_FIRST_ROOT)

Definition at line 188 of file zend_gc.c.

◆ GC_THRESHOLD_MAX

#define GC_THRESHOLD_MAX   1000000000

Definition at line 190 of file zend_gc.c.

◆ GC_THRESHOLD_STEP

#define GC_THRESHOLD_STEP   10000

Definition at line 189 of file zend_gc.c.

◆ GC_THRESHOLD_TRIGGER

#define GC_THRESHOLD_TRIGGER   100

Definition at line 191 of file zend_gc.c.

◆ GC_TRACE

#define GC_TRACE ( str)

Definition at line 110 of file zend_gc.c.

◆ GC_TRACE_REF

#define GC_TRACE_REF ( ref,
format,
... )

Definition at line 108 of file zend_gc.c.

◆ GC_TRACE_SET_COLOR

#define GC_TRACE_SET_COLOR ( ref,
new_color )

Definition at line 109 of file zend_gc.c.

◆ GC_UNSET_FROM_WEAKMAP

#define GC_UNSET_FROM_WEAKMAP ( zv)
Value:
do { \
zval *_z = (zv); \
Z_TYPE_INFO_P(_z) = Z_TYPE_INFO_P(_z) & ~(Z_FROM_WEAKMAP << Z_TYPE_INFO_EXTRA_SHIFT); \
} while (0)

Definition at line 225 of file zend_gc.c.

◆ GC_UNSET_FROM_WEAKMAP_KEY

#define GC_UNSET_FROM_WEAKMAP_KEY ( zv)
Value:
do { \
zval *_z = (zv); \
Z_TYPE_INFO_P(_z) = Z_TYPE_INFO_P(_z) & ~(Z_FROM_WEAKMAP_KEY << Z_TYPE_INFO_EXTRA_SHIFT); \
} while (0)

Definition at line 210 of file zend_gc.c.

◆ GC_UNUSED

#define GC_UNUSED   0x1 /* part of linked list of unused buffers */

Definition at line 150 of file zend_gc.c.

◆ GC_WHITE

#define GC_WHITE   0x100000u

Definition at line 93 of file zend_gc.c.

◆ Z_FROM_WEAKMAP

#define Z_FROM_WEAKMAP   (1<<1)

Definition at line 198 of file zend_gc.c.

◆ Z_FROM_WEAKMAP_KEY

#define Z_FROM_WEAKMAP_KEY   (1<<0)

Definition at line 197 of file zend_gc.c.

◆ ZEND_GC_DEBUG

#define ZEND_GC_DEBUG   0

zend_gc_collect_cycles

Colors and its meaning

BLACK (GC_BLACK) - In use or free. GREY (GC_GREY) - Possible member of cycle. WHITE (GC_WHITE) - Member of garbage cycle. PURPLE (GC_PURPLE) - Possible root of cycle.

Colors described in the paper but not used

GREEN - Acyclic RED - Candidate cycle undergoing ORANGE - Candidate cycle awaiting epoch boundary.

Flow

The garbage collect cycle starts from 'gc_mark_roots', which traverses the possible roots, and calls mark_grey for roots are marked purple with depth-first traverse.

After all possible roots are traversed and marked, gc_scan_roots will be called, and each root will be called with gc_scan(root->ref)

gc_scan checks the colors of possible members.

If the node is marked as grey and the refcount > 0 gc_scan_black will be called on that node to scan it's subgraph. otherwise (refcount == 0), it marks the node white.

A node MAY be added to possible roots when ZEND_UNSET_VAR happens or zend_assign_to_variable is called only when possible garbage node is produced. gc_possible_root() will be called to add the nodes to possible roots.

For objects, we call their get_gc handler (by default 'zend_std_get_gc') to get the object properties to scan.

See also
http://researcher.watson.ibm.com/researcher/files/us-bacon/Bacon01Concurrent.pdf

Definition at line 85 of file zend_gc.c.

Typedef Documentation

◆ gc_root_buffer

◆ gc_stack

typedef struct _gc_stack gc_stack

Definition at line 314 of file zend_gc.c.

◆ zend_gc_globals

Function Documentation

◆ gc_enable()

ZEND_API bool gc_enable ( bool enable)

Definition at line 568 of file zend_gc.c.

◆ gc_enabled()

ZEND_API bool gc_enabled ( void )

Definition at line 582 of file zend_gc.c.

◆ gc_globals_ctor()

void gc_globals_ctor ( void )

Definition at line 517 of file zend_gc.c.

◆ gc_globals_dtor()

void gc_globals_dtor ( void )

Definition at line 526 of file zend_gc.c.

◆ gc_init()

void gc_init ( void )

Definition at line 2280 of file zend_gc.c.

◆ gc_possible_root()

ZEND_API void ZEND_FASTCALL gc_possible_root ( zend_refcounted * ref)

Definition at line 698 of file zend_gc.c.

◆ gc_protect()

ZEND_API bool gc_protect ( bool protect)

Definition at line 587 of file zend_gc.c.

◆ gc_protected()

ZEND_API bool gc_protected ( void )

Definition at line 594 of file zend_gc.c.

◆ gc_remove_from_buffer()

ZEND_API void ZEND_FASTCALL gc_remove_from_buffer ( zend_refcounted * ref)

Definition at line 773 of file zend_gc.c.

◆ gc_reset()

void gc_reset ( void )

Definition at line 533 of file zend_gc.c.

◆ zend_gc_collect_cycles()

ZEND_API int zend_gc_collect_cycles ( void )

Definition at line 1913 of file zend_gc.c.

◆ zend_gc_get_status()

ZEND_API void zend_gc_get_status ( zend_gc_status * status)

Definition at line 2114 of file zend_gc.c.

◆ zend_get_gc_buffer_create()

ZEND_API zend_get_gc_buffer * zend_get_gc_buffer_create ( void )

Definition at line 2130 of file zend_gc.c.

◆ zend_get_gc_buffer_grow()

ZEND_API void zend_get_gc_buffer_grow ( zend_get_gc_buffer * gc_buffer)

Definition at line 2138 of file zend_gc.c.

Variable Documentation

◆ gc_collect_cycles

ZEND_API int(* gc_collect_cycles) (void) ( void )

Definition at line 245 of file zend_gc.c.