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

Refactor: gc flags and friends #16153

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions Zend/zend_gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,16 @@
#endif

/* GC_INFO layout */
#define GC_ADDRESS 0x0fffffu
#define GC_COLOR 0x300000u
#define GC_COLOR_BITS 2
#define GC_ADDRESS_BITS (GC_INFO_BITS - GC_COLOR_BITS)

#define GC_BLACK 0x000000u /* must be zero */
#define GC_WHITE 0x100000u
#define GC_GREY 0x200000u
#define GC_PURPLE 0x300000u
#define GC_ADDRESS ((1 << GC_ADDRESS_BITS) - 1)
#define GC_COLOR (((1 << (GC_COLOR_BITS + GC_ADDRESS_BITS)) - 1) & (~GC_ADDRESS))

#define GC_BLACK (0U << GC_ADDRESS_BITS) // 0x000000 (black)
#define GC_WHITE (1U << GC_ADDRESS_BITS) // 0x100000 (white)
#define GC_GREY (2U << GC_ADDRESS_BITS) // 0x200000 (grey)
#define GC_PURPLE (3U << GC_ADDRESS_BITS) // 0x300000 (purple)

/* Debug tracing */
#if ZEND_GC_DEBUG > 1
Expand Down
33 changes: 28 additions & 5 deletions Zend/zend_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -733,11 +733,34 @@ static zend_always_inline uint8_t zval_get_type(const zval* pz) {
} \
} while (0)

#define GC_TYPE_MASK 0x0000000f
#define GC_FLAGS_MASK 0x000003f0
#define GC_INFO_MASK 0xfffffc00
#define GC_FLAGS_SHIFT 0
#define GC_INFO_SHIFT 10
/// GC is controlled through a data structure that is front-loaded onto zvals. This structure is 32-bits wide and follows
/// the following layout (from MSB to LSB):
/// - 4 bits for the type
/// - these are IS_UNDEF, IS_NULL, IS_ARRAY, etc.
/// - 8 bits for the flags
withinboredom marked this conversation as resolved.
Show resolved Hide resolved
/// - special flags for GC such as GC_IMMUTABLE, GC_PERSISTENT, etc.
/// - other custom flags such as IS_STR_INTERNED, IS_ARRAY_IMMUTABLE, etc.
/// - GC lifecycle flags such as IS_OBJ_DESTRUCTOR_CALLED and IS_OBJ_FREE_CALLED
/// - 22 bits for the info
/// - 20 bits for GC_ADDRESS: the address for GC ref-counting
/// - 2 bits for GC_COLOR: the current color during GC cycles
/// Updating the *_BITS flags below will automatically restructure this layout, sacrificing GC_ADDRESS bits. Please keep
/// this in mind when adding a new flag.

// Define the bit sizes for each field based on the original layout
#define GC_TYPE_BITS 4 // Number of bits for the type field
#define GC_FLAGS_BITS 6 // Number of bits for the flags field
#define GC_INFO_BITS 22 // Number of bits for the info field

// Calculate the dynamic shifts based on the bit sizes
#define GC_TYPE_SHIFT 0 // Type starts at bit 0
#define GC_FLAGS_SHIFT 0 // For legacy reasons, flags start at bit 0
#define GC_INFO_SHIFT (GC_TYPE_BITS + GC_FLAGS_BITS) // Info starts after the flags field (bit 10)

// Define the masks (shifted into place), cast to unsigned and avoid negative shifts
#define GC_TYPE_MASK (((1 << GC_TYPE_BITS) - 1) << GC_TYPE_SHIFT) // 0x0000000F
#define GC_FLAGS_MASK (((1 << GC_FLAGS_BITS) - 1) << (GC_FLAGS_SHIFT + GC_TYPE_BITS)) // 0x000003F0
#define GC_INFO_MASK ((~((1 << GC_INFO_SHIFT) - 1)) & 0xFFFFFFFF) // 0xFFFFFC00

static zend_always_inline uint8_t zval_gc_type(uint32_t gc_type_info) {
return (gc_type_info & GC_TYPE_MASK);
Expand Down
Loading