static void zend_hash_persist_calc(HashTable *ht, void (*pPersistElement)(zval *pElement)) { uint idx; Bucket *p; if (!(ht->u.flags & HASH_FLAG_INITIALIZED)) { return; } ADD_SIZE(HT_USED_SIZE(ht)); for (idx = 0; idx < ht->nNumUsed; idx++) { p = ht->arData + idx; if (Z_TYPE(p->val) == IS_UNDEF) continue; /* persist bucket and key */ if (p->key) { zend_uchar flags = GC_FLAGS(p->key) & ~ (IS_STR_PERSISTENT | IS_STR_INTERNED | IS_STR_PERMANENT); ADD_INTERNED_STRING(p->key, 1); GC_FLAGS(p->key) |= flags; } pPersistElement(&p->val); } }
static void zend_hash_persist(HashTable *ht, zend_persist_func_t pPersistElement TSRMLS_DC) { uint idx; Bucket *p; if (!ht->nTableMask) { ht->arHash = (uint32_t*)&uninitialized_bucket; return; } if (ht->u.flags & HASH_FLAG_PACKED) { zend_accel_store(ht->arData, sizeof(Bucket) * ht->nNumUsed); ht->arHash = (uint32_t*)&uninitialized_bucket; } else { Bucket *d = (Bucket*)ZCG(mem); uint32_t *h = (uint32_t*)(d + ht->nNumUsed); ZCG(mem) = (void*)(h + ht->nTableSize); memcpy(d, ht->arData, sizeof(Bucket) * ht->nNumUsed); memcpy(h, ht->arHash, sizeof(uint32_t) * ht->nTableSize); efree(ht->arData); ht->arData = d; ht->arHash = h; } for (idx = 0; idx < ht->nNumUsed; idx++) { p = ht->arData + idx; if (Z_TYPE(p->val) == IS_UNDEF) continue; /* persist bucket and key */ if (p->key) { zend_accel_store_interned_string(p->key); } /* persist the data itself */ pPersistElement(&p->val TSRMLS_CC); } }