summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-12-09 18:07:39 +0300
committerDmitry Stogov <dmitry@zend.com>2014-12-09 18:07:39 +0300
commit2f3c79b4bf30c8257dd5259280e90149df538736 (patch)
treef4b8f6dcadb00e4da7df41fc32425b775379d6df
parent29b9105beb292eefc0dd6642f2e2fdcbd259df00 (diff)
downloadphp-git-2f3c79b4bf30c8257dd5259280e90149df538736.tar.gz
Improved basic zval copying primitives: ZVAL_COPY_VALUE(), ZVAL_COPY(), ZVAL_DUP()
-rw-r--r--Zend/zend_types.h61
1 files changed, 50 insertions, 11 deletions
diff --git a/Zend/zend_types.h b/Zend/zend_types.h
index 77c914b209..c7591d6414 100644
--- a/Zend/zend_types.h
+++ b/Zend/zend_types.h
@@ -102,6 +102,11 @@ typedef union _zend_value {
void *ptr;
zend_class_entry *ce;
zend_function *func;
+ struct {
+ ZEND_ENDIAN_LOHI(
+ uint32_t w1,
+ uint32_t w2)
+ } ww;
} zend_value;
struct _zval_struct {
@@ -695,30 +700,64 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) {
return --GC_REFCOUNT(Z_COUNTED_P(pz));
}
+#if SIZEOF_ZEND_LONG == 4
+# define ZVAL_COPY_VALUE_EX(z, v, gc, t) \
+ do { \
+ uint32_t _w2; \
+ gc = v->value.counted; \
+ _w2 = v->value.ww.w2; \
+ t = Z_TYPE_INFO_P(v); \
+ z->value.counted = gc; \
+ z->value.ww.w2 = _w2; \
+ Z_TYPE_INFO_P(z) = t; \
+ } while (0)
+#elif SIZEOF_ZEND_LONG == 8
+# define ZVAL_COPY_VALUE_EX(z, v, gc, t) \
+ do { \
+ gc = v->value.counted; \
+ t = Z_TYPE_INFO_P(v); \
+ z->value.counted = gc; \
+ Z_TYPE_INFO_P(z) = t; \
+ } while (0)
+#else
+# error "Unknbown SIZEOF_ZEND_LONG"
+#endif
+
#define ZVAL_COPY_VALUE(z, v) \
do { \
zval *_z1 = (z); \
const zval *_z2 = (v); \
- (_z1)->value = (_z2)->value; \
- Z_TYPE_INFO_P(_z1) = Z_TYPE_INFO_P(_z2); \
+ zend_refcounted *_gc; \
+ uint32_t _t; \
+ ZVAL_COPY_VALUE_EX(_z1, _z2, _gc, _t); \
} while (0)
#define ZVAL_COPY(z, v) \
do { \
- zval *__z1 = (z); \
- const zval *__z2 = (v); \
- ZVAL_COPY_VALUE(__z1, __z2); \
- if (Z_OPT_REFCOUNTED_P(__z1)) { \
- Z_ADDREF_P(__z1); \
+ zval *_z1 = (z); \
+ const zval *_z2 = (v); \
+ zend_refcounted *_gc; \
+ uint32_t _t; \
+ ZVAL_COPY_VALUE_EX(_z1, _z2, _gc, _t); \
+ if ((_t & (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) != 0) { \
+ GC_REFCOUNT(_gc)++; \
} \
} while (0)
#define ZVAL_DUP(z, v) \
do { \
- zval *__z1 = (z); \
- const zval *__z2 = (v); \
- ZVAL_COPY_VALUE(__z1, __z2); \
- zval_opt_copy_ctor(__z1); \
+ zval *_z1 = (z); \
+ const zval *_z2 = (v); \
+ zend_refcounted *_gc; \
+ uint32_t _t; \
+ ZVAL_COPY_VALUE_EX(_z1, _z2, _gc, _t); \
+ if ((_t & ((IS_TYPE_REFCOUNTED|IS_TYPE_IMMUTABLE) << Z_TYPE_FLAGS_SHIFT)) != 0) { \
+ if ((_t & ((IS_TYPE_COPYABLE|IS_TYPE_IMMUTABLE) << Z_TYPE_FLAGS_SHIFT)) != 0) { \
+ _zval_copy_ctor_func(_z1 ZEND_FILE_LINE_CC); \
+ } else { \
+ GC_REFCOUNT(_gc)++; \
+ } \
+ } \
} while (0)
#define ZVAL_DEREF(z) do { \