]> granicus.if.org Git - php/commitdiff
Allow reference-counting on "thread-local" persistent zvals
authorDmitry Stogov <dmitry@zend.com>
Wed, 1 Nov 2017 12:11:52 +0000 (15:11 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 1 Nov 2017 12:11:52 +0000 (15:11 +0300)
Zend/zend_types.h

index 341b1fe8c9ef1118d21fd778504239ca4d58fb99..fcd5da281726174b8e6dd1e578b43424187b393d 100644 (file)
@@ -463,6 +463,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 #define GC_PROTECTED                (1<<1) /* used for recursion detection */
 #define GC_IMMUTABLE                (1<<2) /* can't be canged in place */
 #define GC_PERSISTENT               (1<<3) /* allocated using malloc */
+#define GC_PERSISTENT_LOCAL         (1<<4) /* persistent, but thread-local */
 
 #define GC_ARRAY                                       (IS_ARRAY          | (GC_COLLECTABLE << GC_FLAGS_SHIFT))
 #define GC_OBJECT                                      (IS_OBJECT         | (GC_COLLECTABLE << GC_FLAGS_SHIFT))
@@ -490,7 +491,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 /* string flags (zval.value->gc.u.flags) */
 #define IS_STR_INTERNED                                GC_IMMUTABLE  /* interned string */
 #define IS_STR_PERSISTENT                      GC_PERSISTENT /* allocated using malloc */
-#define IS_STR_PERMANENT               (1<<4)        /* relives request boundary */
+#define IS_STR_PERMANENT               (1<<5)        /* relives request boundary */
 
 /* array flags */
 #define IS_ARRAY_IMMUTABLE                     GC_IMMUTABLE
@@ -879,12 +880,20 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 
 #if ZEND_RC_DEBUG
 extern ZEND_API zend_bool zend_rc_debug;
-# define ZEND_RC_MOD_CHECK(p) \
-       ZEND_ASSERT(!zend_rc_debug || \
-               ((p)->u.v.flags & (GC_IMMUTABLE | GC_PERSISTENT)) == 0)
+# define ZEND_RC_MOD_CHECK(p) do { \
+               if (zend_rc_debug) { \
+                       ZEND_ASSERT(!((p)->u.v.flags & GC_IMMUTABLE)); \
+                       ZEND_ASSERT(((p)->u.v.flags & (GC_PERSISTENT|GC_PERSISTENT_LOCAL)) != GC_PERSISTENT); \
+               } \
+       } while (0)
+# define GC_MAKE_PERSISTENT_LOCAL(p) do { \
+               GC_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) {