Skip to content

Commit 4b4d634

Browse files
author
Yiduo (David) Wang
committed
MFH: Added macros for managing zval refcounts and is_ref statuses
1 parent ca4c55a commit 4b4d634

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+924
-864
lines changed

Zend/zend.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_cop
236236
if (!Z_OBJ_HANDLER_P(expr, cast_object) && Z_OBJ_HANDLER_P(expr, get)) {
237237
zval *z = Z_OBJ_HANDLER_P(expr, get)(expr TSRMLS_CC);
238238

239-
z->refcount++;
239+
Z_ADDREF_P(z);
240240
if(Z_TYPE_P(z) != IS_OBJECT) {
241241
zend_make_printable_zval(z, expr_copy, use_copy);
242242
if (*use_copy) {
@@ -629,8 +629,8 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions, i
629629

630630

631631
/* This zval can be used to initialize allocate zval's to an uninit'ed value */
632-
zval_used_for_init.is_ref = 0;
633-
zval_used_for_init.refcount = 1;
632+
Z_UNSET_ISREF(zval_used_for_init);
633+
Z_SET_REFCOUNT(zval_used_for_init, 1);
634634
zval_used_for_init.type = IS_NULL;
635635

636636
#ifdef ZTS

Zend/zend.h

Lines changed: 85 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -295,12 +295,77 @@ typedef union _zvalue_value {
295295
struct _zval_struct {
296296
/* Variable information */
297297
zvalue_value value; /* value */
298-
zend_uint refcount;
298+
zend_uint refcount__gc;
299299
zend_uchar type; /* active type */
300-
zend_uchar is_ref;
300+
zend_uchar is_ref__gc;
301301
zend_uchar idx_type; /* type of element's index in constant array */
302302
};
303303

304+
#define Z_REFCOUNT_PP(ppz) Z_REFCOUNT_P(*(ppz))
305+
#define Z_SET_REFCOUNT_PP(ppz, rc) Z_SET_REFCOUNT_P(*(ppz), rc)
306+
#define Z_ADDREF_PP(ppz) Z_ADDREF_P(*(ppz))
307+
#define Z_DELREF_PP(ppz) Z_DELREF_P(*(ppz))
308+
#define Z_ISREF_PP(ppz) Z_ISREF_P(*(ppz))
309+
#define Z_SET_ISREF_PP(ppz) Z_SET_ISREF_P(*(ppz))
310+
#define Z_UNSET_ISREF_PP(ppz) Z_UNSET_ISREF_P(*(ppz))
311+
#define Z_SET_ISREF_TO_PP(ppz, isref) Z_SET_ISREF_TO_P(*(ppz), isref)
312+
313+
#define Z_REFCOUNT_P(pz) zval_refcount_p(pz)
314+
#define Z_SET_REFCOUNT_P(pz, rc) zval_set_refcount_p(pz, rc)
315+
#define Z_ADDREF_P(pz) zval_addref_p(pz)
316+
#define Z_DELREF_P(pz) zval_delref_p(pz)
317+
#define Z_ISREF_P(pz) zval_isref_p(pz)
318+
#define Z_SET_ISREF_P(pz) zval_set_isref_p(pz)
319+
#define Z_UNSET_ISREF_P(pz) zval_unset_isref_p(pz)
320+
#define Z_SET_ISREF_TO_P(pz, isref) zval_set_isref_to_p(pz, isref)
321+
322+
#define Z_REFCOUNT(z) Z_REFCOUNT_P(&(z))
323+
#define Z_SET_REFCOUNT(z, rc) Z_SET_REFCOUNT_P(&(z), rc)
324+
#define Z_ADDREF(z) Z_ADDREF_P(&(z))
325+
#define Z_DELREF(z) Z_DELREF_P(&(z))
326+
#define Z_ISREF(z) Z_ISREF_P(&(z))
327+
#define Z_SET_ISREF(z) Z_SET_ISREF_P(&(z))
328+
#define Z_UNSET_ISREF(z) Z_UNSET_ISREF_P(&(z))
329+
#define Z_SET_ISREF_TO(z, isref) Z_SET_ISREF_TO_P(&(z), isref)
330+
331+
#if defined(__GNUC__)
332+
#define always_inline inline __attribute__((always_inline))
333+
#elif defined(_MSC_VER)
334+
#define always_inline __forceinline
335+
#else
336+
#define always_inline inline
337+
#endif
338+
339+
static always_inline zend_uint zval_refcount_p(zval* pz) {
340+
return pz->refcount__gc;
341+
}
342+
343+
static always_inline zend_uint zval_set_refcount_p(zval* pz, zend_uint rc) {
344+
return pz->refcount__gc = rc;
345+
}
346+
347+
static always_inline zend_uint zval_addref_p(zval* pz) {
348+
return ++pz->refcount__gc;
349+
}
350+
351+
static always_inline zend_uint zval_delref_p(zval* pz) {
352+
return --pz->refcount__gc;
353+
}
354+
355+
static always_inline zend_bool zval_isref_p(zval* pz) {
356+
return pz->is_ref__gc;
357+
}
358+
359+
static always_inline zend_bool zval_set_isref_p(zval* pz) {
360+
return pz->is_ref__gc = 1;
361+
}
362+
363+
static always_inline zend_bool zval_unset_isref_p(zval* pz) {
364+
return pz->is_ref__gc = 0;
365+
}
366+
static always_inline zend_bool zval_set_isref_to_p(zval* pz, zend_bool isref) {
367+
return pz->is_ref__gc = isref;
368+
}
304369

305370
/* excpt.h on Digital Unix 4.0 defines function_table */
306371
#undef function_table
@@ -561,14 +626,9 @@ END_EXTERN_C()
561626
#define ZMSG_LOG_SCRIPT_NAME 6L
562627
#define ZMSG_MEMORY_LEAKS_GRAND_TOTAL 7L
563628

564-
565-
#define ZVAL_ADDREF(pz) (++(pz)->refcount)
566-
#define ZVAL_DELREF(pz) (--(pz)->refcount)
567-
#define ZVAL_REFCOUNT(pz) ((pz)->refcount)
568-
569629
#define INIT_PZVAL(z) \
570-
(z)->refcount = 1; \
571-
(z)->is_ref = 0;
630+
(z)->refcount__gc = 1; \
631+
(z)->is_ref__gc = 0;
572632

573633
#define INIT_ZVAL(z) z = zval_used_for_init;
574634

@@ -580,19 +640,19 @@ END_EXTERN_C()
580640
ALLOC_ZVAL(zv); \
581641
INIT_PZVAL(zv);
582642

583-
#define PZVAL_IS_REF(z) ((z)->is_ref)
643+
#define PZVAL_IS_REF(z) Z_ISREF_P(z)
584644

585645
#define SEPARATE_ZVAL(ppzv) \
586646
{ \
587647
zval *orig_ptr = *(ppzv); \
588648
\
589-
if (orig_ptr->refcount>1) { \
590-
orig_ptr->refcount--; \
649+
if (Z_REFCOUNT_P(orig_ptr)>1) { \
650+
Z_DELREF_P(orig_ptr); \
591651
ALLOC_ZVAL(*(ppzv)); \
592652
**(ppzv) = *orig_ptr; \
593653
zval_copy_ctor(*(ppzv)); \
594-
(*(ppzv))->refcount=1; \
595-
(*(ppzv))->is_ref = 0; \
654+
Z_SET_REFCOUNT_PP(ppzv, 1); \
655+
Z_UNSET_ISREF_PP(ppzv); \
596656
} \
597657
}
598658

@@ -604,14 +664,14 @@ END_EXTERN_C()
604664
#define SEPARATE_ZVAL_TO_MAKE_IS_REF(ppzv) \
605665
if (!PZVAL_IS_REF(*ppzv)) { \
606666
SEPARATE_ZVAL(ppzv); \
607-
(*(ppzv))->is_ref = 1; \
667+
Z_SET_ISREF_PP(ppzv); \
608668
}
609669

610670
#define COPY_PZVAL_TO_ZVAL(zv, pzv) \
611671
(zv) = *(pzv); \
612-
if ((pzv)->refcount>1) { \
672+
if (Z_REFCOUNT_P(pzv)>1) { \
613673
zval_copy_ctor(&(zv)); \
614-
(pzv)->refcount--; \
674+
Z_DELREF_P(pzv); \
615675
} else { \
616676
FREE_ZVAL(pzv); \
617677
} \
@@ -621,15 +681,15 @@ END_EXTERN_C()
621681
int is_ref, refcount; \
622682
\
623683
SEPARATE_ZVAL_IF_NOT_REF(ppzv_dest); \
624-
is_ref = (*ppzv_dest)->is_ref; \
625-
refcount = (*ppzv_dest)->refcount; \
684+
is_ref = Z_ISREF_PP(ppzv_dest); \
685+
refcount = Z_REFCOUNT_PP(ppzv_dest); \
626686
zval_dtor(*ppzv_dest); \
627687
**ppzv_dest = *pzv_src; \
628688
if (copy) { \
629689
zval_copy_ctor(*ppzv_dest); \
630690
} \
631-
(*ppzv_dest)->is_ref = is_ref; \
632-
(*ppzv_dest)->refcount = refcount; \
691+
Z_SET_ISREF_TO_PP(ppzv_dest, is_ref); \
692+
Z_SET_REFCOUNT_PP(ppzv_dest, refcount); \
633693
}
634694

635695
#define SEPARATE_ARG_IF_REF(varptr) \
@@ -638,15 +698,15 @@ END_EXTERN_C()
638698
ALLOC_ZVAL(varptr); \
639699
varptr->value = original_var->value; \
640700
varptr->type = original_var->type; \
641-
varptr->is_ref = 0; \
642-
varptr->refcount = 1; \
701+
Z_UNSET_ISREF_P(varptr); \
702+
Z_SET_REFCOUNT_P(varptr, 1); \
643703
zval_copy_ctor(varptr); \
644704
} else { \
645-
varptr->refcount++; \
705+
Z_ADDREF_P(varptr); \
646706
}
647707

648708
#define READY_TO_DESTROY(zv) \
649-
((zv)->refcount == 1 && \
709+
(Z_REFCOUNT_P(zv) == 1 && \
650710
(Z_TYPE_P(zv) != IS_OBJECT || \
651711
zend_objects_store_get_refcount(zv TSRMLS_CC) == 1))
652712

0 commit comments

Comments
 (0)