diff --git a/Zend/zend.c b/Zend/zend.c index 2e37bdb285271..9bfd9178f52b2 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -94,10 +94,6 @@ void (*zend_on_timeout)(int seconds); static void (*zend_message_dispatcher_p)(zend_long message, const void *data); static zval *(*zend_get_configuration_directive_p)(zend_string *name); -#if ZEND_RC_DEBUG -ZEND_API bool zend_rc_debug = 0; -#endif - static ZEND_INI_MH(OnUpdateErrorReporting) /* {{{ */ { if (!new_value) { diff --git a/Zend/zend.h b/Zend/zend.h index 3eaf62ace1157..a0c0fc2126d3b 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -39,6 +39,7 @@ #include "zend_smart_str_public.h" #include "zend_smart_string_public.h" #include "zend_signal.h" +#include "zend_type_code.h" #define zend_sprintf sprintf diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 2f5f2a751ae3c..9ebabbf652698 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -32,6 +32,7 @@ #include "zend_ini.h" #include "zend_enum.h" #include "zend_observer.h" +#include "zend_rc_debug.h" #include diff --git a/Zend/zend_API.h b/Zend/zend_API.h index ca33e96656bca..8341febd6ac7a 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -22,13 +22,14 @@ #ifndef ZEND_API_H #define ZEND_API_H +#include "zend_char.h" #include "zend_modules.h" #include "zend_list.h" #include "zend_operators.h" #include "zend_variables.h" #include "zend_execute.h" #include "zend_type_info.h" - +#include "zend_type_code.h" BEGIN_EXTERN_C() diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h index 95581cf2814c1..30fea71e2efaf 100644 --- a/Zend/zend_alloc.h +++ b/Zend/zend_alloc.h @@ -21,12 +21,12 @@ #ifndef ZEND_ALLOC_H #define ZEND_ALLOC_H +#include "zend_portability.h" #include "zend_result.h" #include #include "../TSRM/TSRM.h" -#include "zend.h" #ifndef ZEND_MM_ALIGNMENT # error "ZEND_MM_ALIGNMENT was not defined during configure" diff --git a/Zend/zend_char.h b/Zend/zend_char.h new file mode 100644 index 0000000000000..0a4af72baa1ff --- /dev/null +++ b/Zend/zend_char.h @@ -0,0 +1,22 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#ifndef ZEND_CHAR_H +#define ZEND_CHAR_H + +typedef unsigned char zend_uchar; + +#endif /* ZEND_CHAR_H */ diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 2370c3045fc67..db6bdaff86f63 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -24,6 +24,7 @@ #include "zend_compile.h" #include "zend_hash.h" #include "zend_operators.h" +#include "zend_type_code.h" #include "zend_variables.h" #include diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index d9210d073182f..dfcf9c0c8b508 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -23,6 +23,7 @@ #include "zend.h" #include "zend_sort.h" +#include "zend_type_code.h" #define HASH_KEY_IS_STRING 1 #define HASH_KEY_IS_LONG 2 diff --git a/Zend/zend_rc_debug.c b/Zend/zend_rc_debug.c new file mode 100644 index 0000000000000..3efd60c0f665d --- /dev/null +++ b/Zend/zend_rc_debug.c @@ -0,0 +1,42 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#include "zend_rc_debug.h" + +#if ZEND_RC_DEBUG + +#include "zend_types.h" + +ZEND_API bool zend_rc_debug = false; + +ZEND_API void ZEND_RC_MOD_CHECK(const zend_refcounted_h *p) +{ + if (!zend_rc_debug) { + return; + } + + uint8_t type = zval_gc_type(p->u.type_info); + + /* Skip checks for OBJECT/NULL type to avoid interpreting the flag incorrectly. */ + if (type != IS_OBJECT && type != IS_NULL) { + ZEND_ASSERT(!(zval_gc_flags(p->u.type_info) & GC_IMMUTABLE)); + + /* The GC_PERSISTENT flag is reused for IS_OBJ_WEAKLY_REFERENCED on objects. */ + ZEND_ASSERT((zval_gc_flags(p->u.type_info) & (GC_PERSISTENT|GC_PERSISTENT_LOCAL)) != GC_PERSISTENT); + } +} + +#endif diff --git a/Zend/zend_rc_debug.h b/Zend/zend_rc_debug.h new file mode 100644 index 0000000000000..345b67b1f9380 --- /dev/null +++ b/Zend/zend_rc_debug.h @@ -0,0 +1,52 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#ifndef ZEND_RC_DEBUG_H +#define ZEND_RC_DEBUG_H + +#ifndef ZEND_RC_DEBUG +# define ZEND_RC_DEBUG 0 +#endif + +#if ZEND_RC_DEBUG + +#ifdef PHP_WIN32 +# include "zend_config.w32.h" +#else +# include "zend_config.h" +#endif + +#include +#include + +#include "zend_portability.h" + +typedef struct _zend_refcounted_h zend_refcounted_h; + +extern ZEND_API bool zend_rc_debug; + +BEGIN_EXTERN_C() + +ZEND_API void ZEND_RC_MOD_CHECK(const zend_refcounted_h *p); + +END_EXTERN_C() + +#else +# define ZEND_RC_MOD_CHECK(p) \ + do { } while (0) +#endif + +#endif /* ZEND_RC_DEBUG_H */ diff --git a/Zend/zend_refcounted.h b/Zend/zend_refcounted.h new file mode 100644 index 0000000000000..e4ffc99568530 --- /dev/null +++ b/Zend/zend_refcounted.h @@ -0,0 +1,137 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#ifndef ZEND_REFCOUNTED_H +#define ZEND_REFCOUNTED_H + +#include "zend_portability.h" +#include "zend_rc_debug.h" +#include "zend_type_code.h" + +#include + +#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 + +/* zval_gc_flags(zval.value->gc.u.type_info) (common flags) */ +#define GC_NOT_COLLECTABLE (1<<4) +#define GC_PROTECTED (1<<5) /* used for recursion detection */ +#define GC_IMMUTABLE (1<<6) /* can't be changed in place */ +#define GC_PERSISTENT (1<<7) /* allocated using malloc */ +#define GC_PERSISTENT_LOCAL (1<<8) /* persistent, but thread-local */ + +#define GC_TYPE_INFO(p) (p)->gc.u.type_info +#define GC_TYPE(p) zval_gc_type(GC_TYPE_INFO(p)) +#define GC_FLAGS(p) zval_gc_flags(GC_TYPE_INFO(p)) +#define GC_INFO(p) zval_gc_info(GC_TYPE_INFO(p)) + +#define GC_ADD_FLAGS(p, flags) do { \ + GC_TYPE_INFO(p) |= (flags) << GC_FLAGS_SHIFT; \ + } while (0) +#define GC_DEL_FLAGS(p, flags) do { \ + GC_TYPE_INFO(p) &= ~((flags) << GC_FLAGS_SHIFT); \ + } while (0) + +#define GC_REFCOUNT(p) zend_gc_refcount(&(p)->gc) +#define GC_SET_REFCOUNT(p, rc) zend_gc_set_refcount(&(p)->gc, rc) +#define GC_ADDREF(p) zend_gc_addref(&(p)->gc) +#define GC_DELREF(p) zend_gc_delref(&(p)->gc) +#define GC_ADDREF_EX(p, rc) zend_gc_addref_ex(&(p)->gc, rc) +#define GC_DELREF_EX(p, rc) zend_gc_delref_ex(&(p)->gc, rc) +#define GC_TRY_ADDREF(p) zend_gc_try_addref(&(p)->gc) +#define GC_TRY_DELREF(p) zend_gc_try_delref(&(p)->gc) + +#define GC_NULL (IS_NULL | (GC_NOT_COLLECTABLE << GC_FLAGS_SHIFT)) +#define GC_STRING (IS_STRING | (GC_NOT_COLLECTABLE << GC_FLAGS_SHIFT)) +#define GC_ARRAY IS_ARRAY +#define GC_OBJECT IS_OBJECT +#define GC_RESOURCE (IS_RESOURCE | (GC_NOT_COLLECTABLE << GC_FLAGS_SHIFT)) +#define GC_REFERENCE (IS_REFERENCE | (GC_NOT_COLLECTABLE << GC_FLAGS_SHIFT)) +#define GC_CONSTANT_AST (IS_CONSTANT_AST | (GC_NOT_COLLECTABLE << GC_FLAGS_SHIFT)) + +typedef struct _zend_refcounted_h { + uint32_t refcount; /* reference counter 32-bit */ + union { + uint32_t type_info; + } u; +} zend_refcounted_h; + +typedef struct _zend_refcounted { + zend_refcounted_h gc; +} zend_refcounted; + +static zend_always_inline uint8_t zval_gc_type(uint32_t gc_type_info) { + return (gc_type_info & GC_TYPE_MASK); +} + +static zend_always_inline uint32_t zval_gc_flags(uint32_t gc_type_info) { + return (gc_type_info >> GC_FLAGS_SHIFT) & (GC_FLAGS_MASK >> GC_FLAGS_SHIFT); +} + +static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) { + return (gc_type_info >> GC_INFO_SHIFT); +} + +static zend_always_inline uint32_t zend_gc_refcount(const zend_refcounted_h *p) { + return p->refcount; +} + +static zend_always_inline uint32_t zend_gc_set_refcount(zend_refcounted_h *p, uint32_t rc) { + p->refcount = rc; + return p->refcount; +} + +static zend_always_inline uint32_t zend_gc_addref(zend_refcounted_h *p) { + ZEND_RC_MOD_CHECK(p); + return ++(p->refcount); +} + +static zend_always_inline void zend_gc_try_addref(zend_refcounted_h *p) { + if (!(p->u.type_info & GC_IMMUTABLE)) { + ZEND_RC_MOD_CHECK(p); + ++p->refcount; + } +} + +static zend_always_inline void zend_gc_try_delref(zend_refcounted_h *p) { + if (!(p->u.type_info & GC_IMMUTABLE)) { + ZEND_RC_MOD_CHECK(p); + --p->refcount; + } +} + +static zend_always_inline uint32_t zend_gc_delref(zend_refcounted_h *p) { + ZEND_ASSERT(p->refcount > 0); + ZEND_RC_MOD_CHECK(p); + return --(p->refcount); +} + +static zend_always_inline uint32_t zend_gc_addref_ex(zend_refcounted_h *p, uint32_t rc) { + ZEND_RC_MOD_CHECK(p); + p->refcount += rc; + return p->refcount; +} + +static zend_always_inline uint32_t zend_gc_delref_ex(zend_refcounted_h *p, uint32_t rc) { + ZEND_RC_MOD_CHECK(p); + p->refcount -= rc; + return p->refcount; +} + +#endif /* ZEND_REFCOUNTED_H */ diff --git a/Zend/zend_string.c b/Zend/zend_string.c index d65101e778c14..a0f379556d05e 100644 --- a/Zend/zend_string.c +++ b/Zend/zend_string.c @@ -16,8 +16,10 @@ +----------------------------------------------------------------------+ */ +#include "zend_string.h" #include "zend.h" #include "zend_globals.h" +#include "zend_rc_debug.h" #ifdef HAVE_VALGRIND # include "valgrind/callgrind.h" diff --git a/Zend/zend_string.h b/Zend/zend_string.h index 3eca7343a008b..cc4f0751bec63 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -19,7 +19,26 @@ #ifndef ZEND_STRING_H #define ZEND_STRING_H -#include "zend.h" +#include "zend_alloc.h" +#include "zend_char.h" +#include "zend_portability.h" +#include "zend_refcounted.h" + +/* string flags (zval.value->gc.u.flags) */ +#define IS_STR_CLASS_NAME_MAP_PTR GC_PROTECTED /* refcount is a map_ptr offset of class_entry */ +#define IS_STR_INTERNED GC_IMMUTABLE /* interned string */ +#define IS_STR_PERSISTENT GC_PERSISTENT /* allocated using malloc */ +#define IS_STR_PERMANENT (1<<8) /* relives request boundary */ +#define IS_STR_VALID_UTF8 (1<<9) /* valid UTF-8 according to PCRE */ + +typedef struct _zend_string zend_string; + +struct _zend_string { + zend_refcounted_h gc; + zend_ulong h; /* hash value */ + size_t len; + char val[1]; +}; BEGIN_EXTERN_C() diff --git a/Zend/zend_type_code.h b/Zend/zend_type_code.h new file mode 100644 index 0000000000000..6ed86ab76313b --- /dev/null +++ b/Zend/zend_type_code.h @@ -0,0 +1,60 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ +*/ + +#ifndef ZEND_TYPE_CODE_H +#define ZEND_TYPE_CODE_H + +enum { + /* Regular data types: Must be in sync with zend_variables.c. */ + IS_UNDEF = 0, + IS_NULL = 1, + IS_FALSE = 2, + IS_TRUE = 3, + IS_LONG = 4, + IS_DOUBLE = 5, + IS_STRING = 6, + IS_ARRAY = 7, + IS_OBJECT = 8, + IS_RESOURCE = 9, + IS_REFERENCE = 10, + IS_CONSTANT_AST = 11, /* Constant expressions */ + + /* Fake types used only for type hinting. + * These are allowed to overlap with the types below. */ + IS_CALLABLE = 12, + IS_ITERABLE = 13, + IS_VOID = 14, + IS_STATIC = 15, + IS_MIXED = 16, + IS_NEVER = 17, + + /* internal types */ + IS_INDIRECT = 12, + IS_PTR = 13, + IS_ALIAS_PTR = 14, + _IS_ERROR = 15, + + /* used for casts */ + _IS_BOOL = 18, + _IS_NUMBER = 19, +}; + +#define ZEND_SAME_FAKE_TYPE(faketype, realtype) ( \ + (faketype) == (realtype) \ + || ((faketype) == _IS_BOOL && ((realtype) == IS_TRUE || (realtype) == IS_FALSE)) \ +) + +#endif /* ZEND_TYPE_CODE_H */ diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 7ba5f8625c1b2..3d900226e54e5 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -24,7 +24,10 @@ #include "zend_portability.h" #include "zend_long.h" +#include "zend_rc_debug.h" +#include "zend_refcounted.h" #include "zend_result.h" +#include "zend_type_code.h" #include #include @@ -50,8 +53,6 @@ # define ZEND_ENDIAN_LOHI_C_4(a, b, c, d) a, b, c, d #endif -typedef unsigned char zend_uchar; - #ifdef ZEND_ENABLE_ZVAL_LONG64 # ifdef ZEND_WIN32 # define ZEND_SIZE_MAX _UI64_MAX @@ -81,7 +82,6 @@ typedef struct _zend_execute_data zend_execute_data; typedef struct _zval_struct zval; -typedef struct _zend_refcounted zend_refcounted; typedef struct _zend_string zend_string; typedef struct _zend_array zend_array; typedef struct _zend_object zend_object; @@ -331,24 +331,6 @@ struct _zval_struct { } u2; }; -typedef struct _zend_refcounted_h { - uint32_t refcount; /* reference counter 32-bit */ - union { - uint32_t type_info; - } u; -} zend_refcounted_h; - -struct _zend_refcounted { - zend_refcounted_h gc; -}; - -struct _zend_string { - zend_refcounted_h gc; - zend_ulong h; /* hash value */ - size_t len; - char val[1]; -}; - typedef struct _Bucket { zval val; zend_ulong h; /* hash value (or numeric index) */ @@ -537,48 +519,10 @@ struct _zend_ast_ref { /*zend_ast ast; zend_ast follows the zend_ast_ref structure */ }; -/* Regular data types: Must be in sync with zend_variables.c. */ -#define IS_UNDEF 0 -#define IS_NULL 1 -#define IS_FALSE 2 -#define IS_TRUE 3 -#define IS_LONG 4 -#define IS_DOUBLE 5 -#define IS_STRING 6 -#define IS_ARRAY 7 -#define IS_OBJECT 8 -#define IS_RESOURCE 9 -#define IS_REFERENCE 10 -#define IS_CONSTANT_AST 11 /* Constant expressions */ - -/* Fake types used only for type hinting. - * These are allowed to overlap with the types below. */ -#define IS_CALLABLE 12 -#define IS_ITERABLE 13 -#define IS_VOID 14 -#define IS_STATIC 15 -#define IS_MIXED 16 -#define IS_NEVER 17 - -/* internal types */ -#define IS_INDIRECT 12 -#define IS_PTR 13 -#define IS_ALIAS_PTR 14 -#define _IS_ERROR 15 - -/* used for casts */ -#define _IS_BOOL 18 -#define _IS_NUMBER 19 - static zend_always_inline uint8_t zval_get_type(const zval* pz) { return pz->u1.v.type; } -#define ZEND_SAME_FAKE_TYPE(faketype, realtype) ( \ - (faketype) == (realtype) \ - || ((faketype) == _IS_BOOL && ((realtype) == IS_TRUE || (realtype) == IS_FALSE)) \ -) - /* we should never set just Z_TYPE, we should set Z_TYPE_INFO */ #define Z_TYPE(zval) zval_get_type(&(zval)) #define Z_TYPE_P(zval_p) Z_TYPE(*(zval_p)) @@ -624,33 +568,12 @@ static zend_always_inline uint8_t zval_get_type(const zval* pz) { #define Z_TYPE_FLAGS_SHIFT 8 -#define GC_REFCOUNT(p) zend_gc_refcount(&(p)->gc) -#define GC_SET_REFCOUNT(p, rc) zend_gc_set_refcount(&(p)->gc, rc) -#define GC_ADDREF(p) zend_gc_addref(&(p)->gc) -#define GC_DELREF(p) zend_gc_delref(&(p)->gc) -#define GC_ADDREF_EX(p, rc) zend_gc_addref_ex(&(p)->gc, rc) -#define GC_DELREF_EX(p, rc) zend_gc_delref_ex(&(p)->gc, rc) -#define GC_TRY_ADDREF(p) zend_gc_try_addref(&(p)->gc) -#define GC_TRY_DELREF(p) zend_gc_try_delref(&(p)->gc) - #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 -static zend_always_inline uint8_t zval_gc_type(uint32_t gc_type_info) { - return (gc_type_info & GC_TYPE_MASK); -} - -static zend_always_inline uint32_t zval_gc_flags(uint32_t gc_type_info) { - return (gc_type_info >> GC_FLAGS_SHIFT) & (GC_FLAGS_MASK >> GC_FLAGS_SHIFT); -} - -static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) { - return (gc_type_info >> GC_INFO_SHIFT); -} - #define GC_TYPE_INFO(p) (p)->gc.u.type_info #define GC_TYPE(p) zval_gc_type(GC_TYPE_INFO(p)) #define GC_FLAGS(p) zval_gc_flags(GC_TYPE_INFO(p)) @@ -674,21 +597,6 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) { #define Z_GC_TYPE_INFO(zval) GC_TYPE_INFO(Z_COUNTED(zval)) #define Z_GC_TYPE_INFO_P(zval_p) Z_GC_TYPE_INFO(*(zval_p)) -/* zval_gc_flags(zval.value->gc.u.type_info) (common flags) */ -#define GC_NOT_COLLECTABLE (1<<4) -#define GC_PROTECTED (1<<5) /* used for recursion detection */ -#define GC_IMMUTABLE (1<<6) /* can't be changed in place */ -#define GC_PERSISTENT (1<<7) /* allocated using malloc */ -#define GC_PERSISTENT_LOCAL (1<<8) /* persistent, but thread-local */ - -#define GC_NULL (IS_NULL | (GC_NOT_COLLECTABLE << GC_FLAGS_SHIFT)) -#define GC_STRING (IS_STRING | (GC_NOT_COLLECTABLE << GC_FLAGS_SHIFT)) -#define GC_ARRAY IS_ARRAY -#define GC_OBJECT IS_OBJECT -#define GC_RESOURCE (IS_RESOURCE | (GC_NOT_COLLECTABLE << GC_FLAGS_SHIFT)) -#define GC_REFERENCE (IS_REFERENCE | (GC_NOT_COLLECTABLE << GC_FLAGS_SHIFT)) -#define GC_CONSTANT_AST (IS_CONSTANT_AST | (GC_NOT_COLLECTABLE << GC_FLAGS_SHIFT)) - /* zval.u1.v.type_flags */ #define IS_TYPE_REFCOUNTED (1<<0) #define IS_TYPE_COLLECTABLE (1<<1) @@ -712,13 +620,6 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) { #define IS_CONSTANT_AST_EX (IS_CONSTANT_AST | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) -/* string flags (zval.value->gc.u.flags) */ -#define IS_STR_CLASS_NAME_MAP_PTR GC_PROTECTED /* refcount is a map_ptr offset of class_entry */ -#define IS_STR_INTERNED GC_IMMUTABLE /* interned string */ -#define IS_STR_PERSISTENT GC_PERSISTENT /* allocated using malloc */ -#define IS_STR_PERMANENT (1<<8) /* relives request boundary */ -#define IS_STR_VALID_UTF8 (1<<9) /* valid UTF-8 according to PCRE */ - /* array flags */ #define IS_ARRAY_IMMUTABLE GC_IMMUTABLE #define IS_ARRAY_PERSISTENT GC_PERSISTENT @@ -1161,79 +1062,15 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) { #define Z_TRY_ADDREF(z) Z_TRY_ADDREF_P(&(z)) #define Z_TRY_DELREF(z) Z_TRY_DELREF_P(&(z)) -#ifndef ZEND_RC_DEBUG -# define ZEND_RC_DEBUG 0 -#endif - #if ZEND_RC_DEBUG -extern ZEND_API bool zend_rc_debug; -/* The GC_PERSISTENT flag is reused for IS_OBJ_WEAKLY_REFERENCED on objects. - * Skip checks for OBJECT/NULL type to avoid interpreting the flag incorrectly. */ -# define ZEND_RC_MOD_CHECK(p) do { \ - if (zend_rc_debug) { \ - uint8_t type = zval_gc_type((p)->u.type_info); \ - if (type != IS_OBJECT && type != IS_NULL) { \ - ZEND_ASSERT(!(zval_gc_flags((p)->u.type_info) & GC_IMMUTABLE)); \ - ZEND_ASSERT((zval_gc_flags((p)->u.type_info) & (GC_PERSISTENT|GC_PERSISTENT_LOCAL)) != GC_PERSISTENT); \ - } \ - } \ - } while (0) # define GC_MAKE_PERSISTENT_LOCAL(p) do { \ GC_ADD_FLAGS(p, GC_PERSISTENT_LOCAL); \ } while (0) #else -# define ZEND_RC_MOD_CHECK(p) \ - do { } while (0) # define GC_MAKE_PERSISTENT_LOCAL(p) \ do { } while (0) #endif -static zend_always_inline uint32_t zend_gc_refcount(const zend_refcounted_h *p) { - return p->refcount; -} - -static zend_always_inline uint32_t zend_gc_set_refcount(zend_refcounted_h *p, uint32_t rc) { - p->refcount = rc; - return p->refcount; -} - -static zend_always_inline uint32_t zend_gc_addref(zend_refcounted_h *p) { - ZEND_RC_MOD_CHECK(p); - return ++(p->refcount); -} - -static zend_always_inline void zend_gc_try_addref(zend_refcounted_h *p) { - if (!(p->u.type_info & GC_IMMUTABLE)) { - ZEND_RC_MOD_CHECK(p); - ++p->refcount; - } -} - -static zend_always_inline void zend_gc_try_delref(zend_refcounted_h *p) { - if (!(p->u.type_info & GC_IMMUTABLE)) { - ZEND_RC_MOD_CHECK(p); - --p->refcount; - } -} - -static zend_always_inline uint32_t zend_gc_delref(zend_refcounted_h *p) { - ZEND_ASSERT(p->refcount > 0); - ZEND_RC_MOD_CHECK(p); - return --(p->refcount); -} - -static zend_always_inline uint32_t zend_gc_addref_ex(zend_refcounted_h *p, uint32_t rc) { - ZEND_RC_MOD_CHECK(p); - p->refcount += rc; - return p->refcount; -} - -static zend_always_inline uint32_t zend_gc_delref_ex(zend_refcounted_h *p, uint32_t rc) { - ZEND_RC_MOD_CHECK(p); - p->refcount -= rc; - return p->refcount; -} - static zend_always_inline uint32_t zval_refcount_p(const zval* pz) { #if ZEND_DEBUG ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_TYPE_P(pz) == IS_ARRAY); diff --git a/configure.ac b/configure.ac index 3970d6d77bd38..3ac52ef98a552 100644 --- a/configure.ac +++ b/configure.ac @@ -1722,6 +1722,7 @@ PHP_ADD_SOURCES(Zend, \ zend_virtual_cwd.c zend_ast.c zend_objects.c zend_object_handlers.c zend_objects_API.c \ zend_default_classes.c zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_gdb.c \ zend_observer.c zend_system_id.c zend_enum.c zend_fibers.c zend_atomic.c \ + zend_rc_debug.c \ Optimizer/zend_optimizer.c \ Optimizer/pass1.c \ Optimizer/pass3.c \ diff --git a/main/main.c b/main/main.c index c0a71b2afa9bd..8e09f4cd4c0b2 100644 --- a/main/main.c +++ b/main/main.c @@ -71,6 +71,7 @@ #include "zend_ini.h" #include "zend_dtrace.h" #include "zend_observer.h" +#include "zend_rc_debug.h" #include "zend_system_id.h" #include "php_content_types.h" diff --git a/main/php.h b/main/php.h index 3385fb799927e..c3d139059c48f 100644 --- a/main/php.h +++ b/main/php.h @@ -29,6 +29,7 @@ #include "php_version.h" #include "zend.h" +#include "zend_rc_debug.h" #include "zend_sort.h" #include "php_compat.h" diff --git a/main/php_ini.c b/main/php_ini.c index 82420fd0bc600..68304f42c5da4 100644 --- a/main/php_ini.c +++ b/main/php_ini.c @@ -22,6 +22,7 @@ #include "ext/standard/dl.h" #include "zend_extensions.h" #include "zend_highlight.h" +#include "zend_rc_debug.h" #include "SAPI.h" #include "php_main.h" #include "php_scandir.h" diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index 5ba629b395fcb..5f47dd8efcc22 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -27,6 +27,7 @@ #include "php.h" #include "zend_ini_scanner.h" #include "zend_globals.h" +#include "zend_rc_debug.h" #include "zend_stream.h" #include "SAPI.h"