Skip to content

Commit d7e4fc7

Browse files
authored
zend_types: Move zend_gc_*() functions above the wrapper macros (#21956)
That allows reliable usage of the `GC_*()` macros in (inline) functions in zend_types.h.
1 parent a59f6ec commit d7e4fc7

1 file changed

Lines changed: 110 additions & 110 deletions

File tree

Zend/zend_types.h

Lines changed: 110 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,116 @@ static zend_always_inline uint8_t zval_get_type(const zval* pz) {
713713
#define Z_TYPE_FLAGS_SHIFT 8
714714
#define Z_TYPE_INFO_EXTRA_SHIFT 16
715715

716+
/* zval_gc_flags(zval.value->gc.u.type_info) (common flags) */
717+
#define GC_NOT_COLLECTABLE (1<<4)
718+
#define GC_PROTECTED (1<<5) /* used for recursion detection */
719+
#define GC_IMMUTABLE (1<<6) /* can't be changed in place */
720+
#define GC_PERSISTENT (1<<7) /* allocated using malloc */
721+
#define GC_PERSISTENT_LOCAL (1<<8) /* persistent, but thread-local */
722+
723+
#define GC_TYPE_MASK 0x0000000f
724+
#define GC_FLAGS_MASK 0x000003f0
725+
#define GC_INFO_MASK 0xfffffc00
726+
#define GC_FLAGS_SHIFT 0
727+
#define GC_INFO_SHIFT 10
728+
729+
static zend_always_inline uint8_t zval_gc_type(uint32_t gc_type_info) {
730+
return (gc_type_info & GC_TYPE_MASK);
731+
}
732+
733+
static zend_always_inline uint32_t zval_gc_flags(uint32_t gc_type_info) {
734+
return (gc_type_info >> GC_FLAGS_SHIFT) & (GC_FLAGS_MASK >> GC_FLAGS_SHIFT);
735+
}
736+
737+
static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
738+
return (gc_type_info >> GC_INFO_SHIFT);
739+
}
740+
741+
#define GC_TYPE_INFO(p) (p)->gc.u.type_info
742+
#define GC_TYPE(p) zval_gc_type(GC_TYPE_INFO(p))
743+
#define GC_FLAGS(p) zval_gc_flags(GC_TYPE_INFO(p))
744+
#define GC_INFO(p) zval_gc_info(GC_TYPE_INFO(p))
745+
746+
#define GC_ADD_FLAGS(p, flags) do { \
747+
GC_TYPE_INFO(p) |= (flags) << GC_FLAGS_SHIFT; \
748+
} while (0)
749+
#define GC_DEL_FLAGS(p, flags) do { \
750+
GC_TYPE_INFO(p) &= ~((flags) << GC_FLAGS_SHIFT); \
751+
} while (0)
752+
753+
#ifndef ZEND_RC_DEBUG
754+
# define ZEND_RC_DEBUG 0
755+
#endif
756+
757+
#if ZEND_RC_DEBUG
758+
extern ZEND_API bool zend_rc_debug;
759+
/* The GC_PERSISTENT flag is reused for IS_OBJ_WEAKLY_REFERENCED on objects.
760+
* Skip checks for OBJECT/NULL type to avoid interpreting the flag incorrectly. */
761+
# define ZEND_RC_MOD_CHECK(p) do { \
762+
if (zend_rc_debug) { \
763+
uint8_t type = zval_gc_type((p)->u.type_info); \
764+
if (type != IS_OBJECT && type != IS_NULL) { \
765+
ZEND_ASSERT(!(zval_gc_flags((p)->u.type_info) & GC_IMMUTABLE)); \
766+
ZEND_ASSERT((zval_gc_flags((p)->u.type_info) & (GC_PERSISTENT|GC_PERSISTENT_LOCAL)) != GC_PERSISTENT); \
767+
} \
768+
} \
769+
} while (0)
770+
# define GC_MAKE_PERSISTENT_LOCAL(p) do { \
771+
GC_ADD_FLAGS(p, GC_PERSISTENT_LOCAL); \
772+
} while (0)
773+
#else
774+
# define ZEND_RC_MOD_CHECK(p) \
775+
do { } while (0)
776+
# define GC_MAKE_PERSISTENT_LOCAL(p) \
777+
do { } while (0)
778+
#endif
779+
780+
static zend_always_inline uint32_t zend_gc_refcount(const zend_refcounted_h *p) {
781+
return p->refcount;
782+
}
783+
784+
static zend_always_inline uint32_t zend_gc_set_refcount(zend_refcounted_h *p, uint32_t rc) {
785+
p->refcount = rc;
786+
return p->refcount;
787+
}
788+
789+
static zend_always_inline uint32_t zend_gc_addref(zend_refcounted_h *p) {
790+
ZEND_RC_MOD_CHECK(p);
791+
return ++(p->refcount);
792+
}
793+
794+
static zend_always_inline void zend_gc_try_addref(zend_refcounted_h *p) {
795+
if (!(p->u.type_info & GC_IMMUTABLE)) {
796+
ZEND_RC_MOD_CHECK(p);
797+
++p->refcount;
798+
}
799+
}
800+
801+
static zend_always_inline void zend_gc_try_delref(zend_refcounted_h *p) {
802+
if (!(p->u.type_info & GC_IMMUTABLE)) {
803+
ZEND_RC_MOD_CHECK(p);
804+
--p->refcount;
805+
}
806+
}
807+
808+
static zend_always_inline uint32_t zend_gc_delref(zend_refcounted_h *p) {
809+
ZEND_ASSERT(p->refcount > 0);
810+
ZEND_RC_MOD_CHECK(p);
811+
return --(p->refcount);
812+
}
813+
814+
static zend_always_inline uint32_t zend_gc_addref_ex(zend_refcounted_h *p, uint32_t rc) {
815+
ZEND_RC_MOD_CHECK(p);
816+
p->refcount += rc;
817+
return p->refcount;
818+
}
819+
820+
static zend_always_inline uint32_t zend_gc_delref_ex(zend_refcounted_h *p, uint32_t rc) {
821+
ZEND_RC_MOD_CHECK(p);
822+
p->refcount -= rc;
823+
return p->refcount;
824+
}
825+
716826
#define GC_REFCOUNT(p) zend_gc_refcount(&(p)->gc)
717827
#define GC_SET_REFCOUNT(p, rc) zend_gc_set_refcount(&(p)->gc, rc)
718828
#define GC_ADDREF(p) zend_gc_addref(&(p)->gc)
@@ -754,36 +864,6 @@ static zend_always_inline uint8_t zval_get_type(const zval* pz) {
754864
} \
755865
} while (0)
756866

757-
#define GC_TYPE_MASK 0x0000000f
758-
#define GC_FLAGS_MASK 0x000003f0
759-
#define GC_INFO_MASK 0xfffffc00
760-
#define GC_FLAGS_SHIFT 0
761-
#define GC_INFO_SHIFT 10
762-
763-
static zend_always_inline uint8_t zval_gc_type(uint32_t gc_type_info) {
764-
return (gc_type_info & GC_TYPE_MASK);
765-
}
766-
767-
static zend_always_inline uint32_t zval_gc_flags(uint32_t gc_type_info) {
768-
return (gc_type_info >> GC_FLAGS_SHIFT) & (GC_FLAGS_MASK >> GC_FLAGS_SHIFT);
769-
}
770-
771-
static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
772-
return (gc_type_info >> GC_INFO_SHIFT);
773-
}
774-
775-
#define GC_TYPE_INFO(p) (p)->gc.u.type_info
776-
#define GC_TYPE(p) zval_gc_type(GC_TYPE_INFO(p))
777-
#define GC_FLAGS(p) zval_gc_flags(GC_TYPE_INFO(p))
778-
#define GC_INFO(p) zval_gc_info(GC_TYPE_INFO(p))
779-
780-
#define GC_ADD_FLAGS(p, flags) do { \
781-
GC_TYPE_INFO(p) |= (flags) << GC_FLAGS_SHIFT; \
782-
} while (0)
783-
#define GC_DEL_FLAGS(p, flags) do { \
784-
GC_TYPE_INFO(p) &= ~((flags) << GC_FLAGS_SHIFT); \
785-
} while (0)
786-
787867
#define Z_GC_TYPE(zval) GC_TYPE(Z_COUNTED(zval))
788868
#define Z_GC_TYPE_P(zval_p) Z_GC_TYPE(*(zval_p))
789869

@@ -795,13 +875,6 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
795875
#define Z_GC_TYPE_INFO(zval) GC_TYPE_INFO(Z_COUNTED(zval))
796876
#define Z_GC_TYPE_INFO_P(zval_p) Z_GC_TYPE_INFO(*(zval_p))
797877

798-
/* zval_gc_flags(zval.value->gc.u.type_info) (common flags) */
799-
#define GC_NOT_COLLECTABLE (1<<4)
800-
#define GC_PROTECTED (1<<5) /* used for recursion detection */
801-
#define GC_IMMUTABLE (1<<6) /* can't be changed in place */
802-
#define GC_PERSISTENT (1<<7) /* allocated using malloc */
803-
#define GC_PERSISTENT_LOCAL (1<<8) /* persistent, but thread-local */
804-
805878
#define GC_NULL (IS_NULL | (GC_NOT_COLLECTABLE << GC_FLAGS_SHIFT))
806879
#define GC_STRING (IS_STRING | (GC_NOT_COLLECTABLE << GC_FLAGS_SHIFT))
807880
#define GC_ARRAY IS_ARRAY
@@ -1299,79 +1372,6 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
12991372
#define Z_TRY_ADDREF(z) Z_TRY_ADDREF_P(&(z))
13001373
#define Z_TRY_DELREF(z) Z_TRY_DELREF_P(&(z))
13011374

1302-
#ifndef ZEND_RC_DEBUG
1303-
# define ZEND_RC_DEBUG 0
1304-
#endif
1305-
1306-
#if ZEND_RC_DEBUG
1307-
extern ZEND_API bool zend_rc_debug;
1308-
/* The GC_PERSISTENT flag is reused for IS_OBJ_WEAKLY_REFERENCED on objects.
1309-
* Skip checks for OBJECT/NULL type to avoid interpreting the flag incorrectly. */
1310-
# define ZEND_RC_MOD_CHECK(p) do { \
1311-
if (zend_rc_debug) { \
1312-
uint8_t type = zval_gc_type((p)->u.type_info); \
1313-
if (type != IS_OBJECT && type != IS_NULL) { \
1314-
ZEND_ASSERT(!(zval_gc_flags((p)->u.type_info) & GC_IMMUTABLE)); \
1315-
ZEND_ASSERT((zval_gc_flags((p)->u.type_info) & (GC_PERSISTENT|GC_PERSISTENT_LOCAL)) != GC_PERSISTENT); \
1316-
} \
1317-
} \
1318-
} while (0)
1319-
# define GC_MAKE_PERSISTENT_LOCAL(p) do { \
1320-
GC_ADD_FLAGS(p, GC_PERSISTENT_LOCAL); \
1321-
} while (0)
1322-
#else
1323-
# define ZEND_RC_MOD_CHECK(p) \
1324-
do { } while (0)
1325-
# define GC_MAKE_PERSISTENT_LOCAL(p) \
1326-
do { } while (0)
1327-
#endif
1328-
1329-
static zend_always_inline uint32_t zend_gc_refcount(const zend_refcounted_h *p) {
1330-
return p->refcount;
1331-
}
1332-
1333-
static zend_always_inline uint32_t zend_gc_set_refcount(zend_refcounted_h *p, uint32_t rc) {
1334-
p->refcount = rc;
1335-
return p->refcount;
1336-
}
1337-
1338-
static zend_always_inline uint32_t zend_gc_addref(zend_refcounted_h *p) {
1339-
ZEND_RC_MOD_CHECK(p);
1340-
return ++(p->refcount);
1341-
}
1342-
1343-
static zend_always_inline void zend_gc_try_addref(zend_refcounted_h *p) {
1344-
if (!(p->u.type_info & GC_IMMUTABLE)) {
1345-
ZEND_RC_MOD_CHECK(p);
1346-
++p->refcount;
1347-
}
1348-
}
1349-
1350-
static zend_always_inline void zend_gc_try_delref(zend_refcounted_h *p) {
1351-
if (!(p->u.type_info & GC_IMMUTABLE)) {
1352-
ZEND_RC_MOD_CHECK(p);
1353-
--p->refcount;
1354-
}
1355-
}
1356-
1357-
static zend_always_inline uint32_t zend_gc_delref(zend_refcounted_h *p) {
1358-
ZEND_ASSERT(p->refcount > 0);
1359-
ZEND_RC_MOD_CHECK(p);
1360-
return --(p->refcount);
1361-
}
1362-
1363-
static zend_always_inline uint32_t zend_gc_addref_ex(zend_refcounted_h *p, uint32_t rc) {
1364-
ZEND_RC_MOD_CHECK(p);
1365-
p->refcount += rc;
1366-
return p->refcount;
1367-
}
1368-
1369-
static zend_always_inline uint32_t zend_gc_delref_ex(zend_refcounted_h *p, uint32_t rc) {
1370-
ZEND_RC_MOD_CHECK(p);
1371-
p->refcount -= rc;
1372-
return p->refcount;
1373-
}
1374-
13751375
static zend_always_inline uint32_t zval_refcount_p(const zval* pz) {
13761376
#if ZEND_DEBUG
13771377
ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_TYPE_P(pz) == IS_ARRAY);

0 commit comments

Comments
 (0)