]> granicus.if.org Git - php/commitdiff
Introduce mcros to access HashTable iterators counter
authorDmitry Stogov <dmitry@zend.com>
Mon, 22 Jan 2018 11:14:35 +0000 (14:14 +0300)
committerDmitry Stogov <dmitry@zend.com>
Mon, 22 Jan 2018 11:14:35 +0000 (14:14 +0300)
Zend/zend_hash.c
Zend/zend_hash.h
ext/standard/array.c

index 85e7004966702ad711038dbc661ba55ad5fb8ba0..129898c88c8b6a23478c769931446c146715e37d 100644 (file)
@@ -319,8 +319,8 @@ ZEND_API uint32_t ZEND_FASTCALL zend_hash_iterator_add(HashTable *ht, HashPositi
        HashTableIterator *end  = iter + EG(ht_iterators_count);
        uint32_t idx;
 
-       if (EXPECTED(ht->u.v.nIteratorsCount != 255)) {
-               ht->u.v.nIteratorsCount++;
+       if (EXPECTED(!HT_ITERATORS_OVERFLOW(ht))) {
+               HT_INC_ITERATORS_COUNT(ht);
        }
        while (iter != end) {
                if (iter->ht == NULL) {
@@ -359,11 +359,11 @@ ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterator_pos(uint32_t idx, HashTab
                return HT_INVALID_IDX;
        } else if (UNEXPECTED(iter->ht != ht)) {
                if (EXPECTED(iter->ht) && EXPECTED(iter->ht != HT_POISONED_PTR)
-                               && EXPECTED(iter->ht->u.v.nIteratorsCount != 255)) {
-                       iter->ht->u.v.nIteratorsCount--;
+                               && EXPECTED(!HT_ITERATORS_OVERFLOW(iter->ht))) {
+                       HT_DEC_ITERATORS_COUNT(iter->ht);
                }
-               if (EXPECTED(ht->u.v.nIteratorsCount != 255)) {
-                       ht->u.v.nIteratorsCount++;
+               if (EXPECTED(!HT_ITERATORS_OVERFLOW(ht))) {
+                       HT_INC_ITERATORS_COUNT(ht);
                }
                iter->ht = ht;
                iter->pos = ht->nInternalPointer;
@@ -381,13 +381,13 @@ ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterator_pos_ex(uint32_t idx, zval
                return HT_INVALID_IDX;
        } else if (UNEXPECTED(iter->ht != ht)) {
                if (EXPECTED(iter->ht) && EXPECTED(iter->ht != HT_POISONED_PTR)
-                               && EXPECTED(iter->ht->u.v.nIteratorsCount != 255)) {
-                       iter->ht->u.v.nIteratorsCount--;
+                               && EXPECTED(!HT_ITERATORS_OVERFLOW(ht))) {
+                       HT_DEC_ITERATORS_COUNT(iter->ht);
                }
                SEPARATE_ARRAY(array);
                ht = Z_ARRVAL_P(array);
-               if (EXPECTED(ht->u.v.nIteratorsCount != 255)) {
-                       ht->u.v.nIteratorsCount++;
+               if (EXPECTED(!HT_ITERATORS_OVERFLOW(ht))) {
+                       HT_INC_ITERATORS_COUNT(ht);
                }
                iter->ht = ht;
                iter->pos = ht->nInternalPointer;
@@ -402,8 +402,8 @@ ZEND_API void ZEND_FASTCALL zend_hash_iterator_del(uint32_t idx)
        ZEND_ASSERT(idx != (uint32_t)-1);
 
        if (EXPECTED(iter->ht) && EXPECTED(iter->ht != HT_POISONED_PTR)
-                       && EXPECTED(iter->ht->u.v.nIteratorsCount != 255)) {
-               iter->ht->u.v.nIteratorsCount--;
+                       && EXPECTED(!HT_ITERATORS_OVERFLOW(iter->ht))) {
+               HT_DEC_ITERATORS_COUNT(iter->ht);
        }
        iter->ht = NULL;
 
@@ -430,7 +430,7 @@ static zend_never_inline void ZEND_FASTCALL _zend_hash_iterators_remove(HashTabl
 
 static zend_always_inline void zend_hash_iterators_remove(HashTable *ht)
 {
-       if (UNEXPECTED(ht->u.v.nIteratorsCount)) {
+       if (UNEXPECTED(HT_HAS_ITERATORS(ht))) {
                _zend_hash_iterators_remove(ht);
        }
 }
@@ -978,7 +978,7 @@ ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht)
                                uint32_t j = i;
                                Bucket *q = p;
 
-                               if (EXPECTED(ht->u.v.nIteratorsCount == 0)) {
+                               if (EXPECTED(!HT_HAS_ITERATORS(ht))) {
                                        while (++i < ht->nNumUsed) {
                                                p++;
                                                if (EXPECTED(Z_TYPE_INFO(p->val) != IS_UNDEF)) {
@@ -1046,7 +1046,7 @@ static zend_always_inline void _zend_hash_del_el_ex(HashTable *ht, uint32_t idx,
                } while (ht->nNumUsed > 0 && (UNEXPECTED(Z_TYPE(ht->arData[ht->nNumUsed-1].val) == IS_UNDEF)));
        }
        ht->nNumOfElements--;
-       if (HT_IDX_TO_HASH(ht->nInternalPointer) == idx || UNEXPECTED(ht->u.v.nIteratorsCount)) {
+       if (HT_IDX_TO_HASH(ht->nInternalPointer) == idx || UNEXPECTED(HT_HAS_ITERATORS(ht))) {
                uint32_t new_idx;
 
                new_idx = idx = HT_HASH_TO_IDX(idx);
index 7e0fb61ae6bbd55dd835b5d7ea0f166142af92ad..d48e47f0e213e3ab08a120bb3337a42b6478b42e 100644 (file)
 # define HT_ALLOW_COW_VIOLATION(ht)
 #endif
 
+#define HT_ITERATORS_COUNT(ht) (ht)->u.v.nIteratorsCount
+#define HT_ITERATORS_OVERFLOW(ht) (HT_ITERATORS_COUNT(ht) == 0xff)
+#define HT_HAS_ITERATORS(ht) (HT_ITERATORS_COUNT(ht) != 0)
+
+#define HT_SET_ITERATORS_COUNT(ht, iters) \
+       do { HT_ITERATORS_COUNT(ht) = (iters); } while (0)
+#define HT_INC_ITERATORS_COUNT(ht) \
+       HT_SET_ITERATORS_COUNT(ht, HT_ITERATORS_COUNT(ht) + 1)
+#define HT_DEC_ITERATORS_COUNT(ht) \
+       HT_SET_ITERATORS_COUNT(ht, HT_ITERATORS_COUNT(ht) - 1)
+
 extern ZEND_API const HashTable zend_empty_array;
 
 #define ZVAL_EMPTY_ARRAY(z) do {                                               \
@@ -295,7 +306,7 @@ ZEND_API void         ZEND_FASTCALL _zend_hash_iterators_update(HashTable *ht, H
 
 static zend_always_inline void zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to)
 {
-       if (UNEXPECTED(ht->u.v.nIteratorsCount)) {
+       if (UNEXPECTED(HT_HAS_ITERATORS(ht))) {
                _zend_hash_iterators_update(ht, from, to);
        }
 }
index d6832856b831aac281be92948801cbd7f9e2ae81..3ebf073d1134c7959f1a3b4056d42842f84981c0 100644 (file)
@@ -2989,7 +2989,7 @@ static void php_array_data_shuffle(zval *array) /* {{{ */
        hash = Z_ARRVAL_P(array);
        n_left = n_elems;
 
-       if (EXPECTED(hash->u.v.nIteratorsCount == 0)) {
+       if (EXPECTED(!HT_HAS_ITERATORS(hash))) {
                if (hash->nNumUsed != hash->nNumOfElements) {
                        for (j = 0, idx = 0; idx < hash->nNumUsed; idx++) {
                                p = hash->arData + idx;
@@ -3190,7 +3190,7 @@ static void php_splice(HashTable *in_hash, zend_long offset, zend_long length, H
        }
 
        /* replace HashTable data */
-       in_hash->u.v.nIteratorsCount = 0;
+       HT_SET_ITERATORS_COUNT(in_hash, 0);
        in_hash->pDestructor = NULL;
        zend_hash_destroy(in_hash);
 
@@ -3345,7 +3345,7 @@ PHP_FUNCTION(array_shift)
        if (HT_FLAGS(Z_ARRVAL_P(stack)) & HASH_FLAG_PACKED) {
                uint32_t k = 0;
 
-               if (EXPECTED(Z_ARRVAL_P(stack)->u.v.nIteratorsCount == 0)) {
+               if (EXPECTED(!HT_HAS_ITERATORS(Z_ARRVAL_P(stack)))) {
                        for (idx = 0; idx < Z_ARRVAL_P(stack)->nNumUsed; idx++) {
                                p = Z_ARRVAL_P(stack)->arData + idx;
                                if (Z_TYPE(p->val) == IS_UNDEF) continue;
@@ -3428,7 +3428,7 @@ PHP_FUNCTION(array_unshift)
                Z_TRY_ADDREF(args[i]);
                zend_hash_next_index_insert_new(&new_hash, &args[i]);
        }
-       if (EXPECTED(Z_ARRVAL_P(stack)->u.v.nIteratorsCount == 0)) {
+       if (EXPECTED(!HT_HAS_ITERATORS(Z_ARRVAL_P(stack)))) {
                ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(stack), key, value) {
                        if (key) {
                                zend_hash_add_new(&new_hash, key, value);
@@ -3457,7 +3457,7 @@ PHP_FUNCTION(array_unshift)
        }
 
        /* replace HashTable data */
-       Z_ARRVAL_P(stack)->u.v.nIteratorsCount = 0;
+       HT_SET_ITERATORS_COUNT(Z_ARRVAL_P(stack), 0);
        Z_ARRVAL_P(stack)->pDestructor = NULL;
        zend_hash_destroy(Z_ARRVAL_P(stack));