From: Dmitry Stogov Date: Tue, 30 Apr 2019 11:50:01 +0000 (+0300) Subject: Use ZEND_HASH_FOREACH with direct callback, instead of callbacks X-Git-Tag: php-7.4.0alpha1~378 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ec5f7df73283ec14cfea5f8a8378238726a71a59;p=php Use ZEND_HASH_FOREACH with direct callback, instead of callbacks --- diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index ed05872993..f32644f4c6 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -79,7 +79,7 @@ static void zend_persist_zval(zval *z); static const uint32_t uninitialized_bucket[-HT_MIN_MASK] = {HT_INVALID_IDX, HT_INVALID_IDX}; -static void zend_hash_persist(HashTable *ht, zend_persist_func_t pPersistElement) +static void zend_hash_persist(HashTable *ht) { uint32_t idx, nIndex; Bucket *p; @@ -111,19 +111,15 @@ static void zend_hash_persist(HashTable *ht, zend_persist_func_t pPersistElement void *data = HT_GET_DATA_ADDR(ht); data = zend_shared_memdup_free(data, HT_USED_SIZE(ht)); HT_SET_DATA_ADDR(ht, data); - } else if (ht->nNumUsed < (uint32_t)(-(int32_t)ht->nTableMask) / 4) { + } else if (ht->nNumUsed > HT_MIN_SIZE && ht->nNumUsed < (uint32_t)(-(int32_t)ht->nTableMask) / 4) { /* compact table */ void *old_data = HT_GET_DATA_ADDR(ht); Bucket *old_buckets = ht->arData; uint32_t hash_size; - if (ht->nNumUsed <= HT_MIN_SIZE) { - hash_size = HT_MIN_SIZE * 2; - } else { - hash_size = (uint32_t)(-(int32_t)ht->nTableMask); - while (hash_size >> 2 > ht->nNumUsed) { - hash_size >>= 1; - } + hash_size = (uint32_t)(-(int32_t)ht->nTableMask); + while (hash_size >> 2 > ht->nNumUsed) { + hash_size >>= 1; } ht->nTableMask = (uint32_t)(-(int32_t)hash_size); ZEND_ASSERT(((zend_uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */ @@ -133,23 +129,14 @@ static void zend_hash_persist(HashTable *ht, zend_persist_func_t pPersistElement memcpy(ht->arData, old_buckets, ht->nNumUsed * sizeof(Bucket)); efree(old_data); + /* rehash */ 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); - nIndex = p->h | ht->nTableMask; Z_NEXT(p->val) = HT_HASH(ht, nIndex); HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(idx); } - return; } else { void *data = ZCG(mem); void *old_data = HT_GET_DATA_ADDR(ht); @@ -160,107 +147,6 @@ static void zend_hash_persist(HashTable *ht, zend_persist_func_t pPersistElement efree(old_data); HT_SET_DATA_ADDR(ht, data); } - - 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); - } -} - -static void zend_hash_persist_immutable(HashTable *ht) -{ - uint32_t idx, nIndex; - Bucket *p; - - HT_FLAGS(ht) |= HASH_FLAG_STATIC_KEYS; - ht->pDestructor = NULL; - - if (HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) { - if (EXPECTED(!ZCG(current_persistent_script)->corrupted)) { - HT_SET_DATA_ADDR(ht, &ZCSG(uninitialized_bucket)); - } else { - HT_SET_DATA_ADDR(ht, &uninitialized_bucket); - } - return; - } - if (ht->nNumUsed == 0) { - efree(HT_GET_DATA_ADDR(ht)); - ht->nTableMask = HT_MIN_MASK; - if (EXPECTED(!ZCG(current_persistent_script)->corrupted)) { - HT_SET_DATA_ADDR(ht, &ZCSG(uninitialized_bucket)); - } else { - HT_SET_DATA_ADDR(ht, &uninitialized_bucket); - } - HT_FLAGS(ht) |= HASH_FLAG_UNINITIALIZED; - return; - } - if (HT_FLAGS(ht) & HASH_FLAG_PACKED) { - HT_SET_DATA_ADDR(ht, zend_shared_memdup(HT_GET_DATA_ADDR(ht), HT_USED_SIZE(ht))); - } else if (ht->nNumUsed < (uint32_t)(-(int32_t)ht->nTableMask) / 4) { - /* compact table */ - Bucket *old_buckets = ht->arData; - uint32_t hash_size; - - if (ht->nNumUsed <= HT_MIN_SIZE) { - hash_size = HT_MIN_SIZE * 2; - } else { - hash_size = (uint32_t)(-(int32_t)ht->nTableMask); - while (hash_size >> 2 > ht->nNumUsed) { - hash_size >>= 1; - } - } - ht->nTableMask = (uint32_t)(-(int32_t)hash_size); - ZEND_ASSERT(((zend_uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */ - HT_SET_DATA_ADDR(ht, ZCG(mem)); - ZCG(mem) = (void*)((char*)ZCG(mem) + (hash_size * sizeof(uint32_t)) + (ht->nNumUsed * sizeof(Bucket))); - HT_HASH_RESET(ht); - memcpy(ht->arData, old_buckets, ht->nNumUsed * sizeof(Bucket)); - - 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_memdup_interned_string(p->key); - } - - /* persist the data itself */ - zend_persist_zval(&p->val); - - nIndex = p->h | ht->nTableMask; - Z_NEXT(p->val) = HT_HASH(ht, nIndex); - HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(idx); - } - return; - } else { - void *data = ZCG(mem); - - ZEND_ASSERT(((zend_uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */ - ZCG(mem) = (void*)((char*)data + ZEND_ALIGNED_SIZE(HT_USED_SIZE(ht))); - memcpy(data, HT_GET_DATA_ADDR(ht), HT_USED_SIZE(ht)); - HT_SET_DATA_ADDR(ht, data); - } - 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_memdup_interned_string(p->key); - } - - /* persist the data itself */ - zend_persist_zval(&p->val); - } } static zend_ast *zend_persist_ast(zend_ast *ast) @@ -310,13 +196,27 @@ static void zend_persist_zval(zval *z) Z_ARR_P(z) = new_ptr; Z_TYPE_FLAGS_P(z) = 0; } else { + Bucket *p; + if (!Z_REFCOUNTED_P(z)) { Z_ARR_P(z) = zend_shared_memdup_put(Z_ARR_P(z), sizeof(zend_array)); - zend_hash_persist_immutable(Z_ARRVAL_P(z)); + zend_hash_persist(Z_ARRVAL_P(z)); + ZEND_HASH_FOREACH_BUCKET(Z_ARRVAL_P(z), p) { + if (p->key) { + zend_accel_memdup_interned_string(p->key); + } + zend_persist_zval(&p->val); + } ZEND_HASH_FOREACH_END(); } else { GC_REMOVE_FROM_BUFFER(Z_ARR_P(z)); Z_ARR_P(z) = zend_shared_memdup_put_free(Z_ARR_P(z), sizeof(zend_array)); - zend_hash_persist(Z_ARRVAL_P(z), zend_persist_zval); + zend_hash_persist(Z_ARRVAL_P(z)); + ZEND_HASH_FOREACH_BUCKET(Z_ARRVAL_P(z), p) { + if (p->key) { + zend_accel_store_interned_string(p->key); + } + zend_persist_zval(&p->val); + } ZEND_HASH_FOREACH_END(); /* make immutable array */ Z_TYPE_FLAGS_P(z) = 0; GC_SET_REFCOUNT(Z_COUNTED_P(z), 2); @@ -374,21 +274,6 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc EG(current_execute_data) = orig_execute_data; } - if (op_array->static_variables) { - HashTable *stored = zend_shared_alloc_get_xlat_entry(op_array->static_variables); - - if (stored) { - op_array->static_variables = stored; - } else { - zend_hash_persist(op_array->static_variables, zend_persist_zval); - op_array->static_variables = zend_shared_memdup_put_free(op_array->static_variables, sizeof(HashTable)); - /* make immutable array */ - GC_SET_REFCOUNT(op_array->static_variables, 2); - GC_TYPE_INFO(op_array->static_variables) = IS_ARRAY | (IS_ARRAY_IMMUTABLE << GC_FLAGS_SHIFT); - } - } - ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables); - if (op_array->scope) { zend_class_entry *scope = zend_shared_alloc_get_xlat_entry(op_array->scope); @@ -402,61 +287,82 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc op_array->prototype = ptr; } } - } else { - /* "prototype" may be undefined if "scope" isn't set */ - op_array->prototype = NULL; - } - persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->opcodes); - if (persist_ptr) { - op_array->opcodes = persist_ptr; - if (op_array->literals) { - op_array->literals = zend_shared_alloc_get_xlat_entry(op_array->literals); - ZEND_ASSERT(op_array->literals != NULL); - } - if (op_array->function_name && !IS_ACCEL_INTERNED(op_array->function_name)) { - op_array->function_name = zend_shared_alloc_get_xlat_entry(op_array->function_name); - ZEND_ASSERT(op_array->function_name != NULL); - } - if (op_array->filename) { - op_array->filename = zend_shared_alloc_get_xlat_entry(op_array->filename); - ZEND_ASSERT(op_array->filename != NULL); - } - if (op_array->arg_info) { - zend_arg_info *arg_info = op_array->arg_info; - if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { - arg_info--; + persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->opcodes); + if (persist_ptr) { + op_array->opcodes = persist_ptr; + if (op_array->static_variables) { + op_array->static_variables = zend_shared_alloc_get_xlat_entry(op_array->static_variables); + ZEND_ASSERT(op_array->static_variables != NULL); } - arg_info = zend_shared_alloc_get_xlat_entry(arg_info); - ZEND_ASSERT(arg_info != NULL); - if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { - arg_info++; + ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables); + if (op_array->literals) { + op_array->literals = zend_shared_alloc_get_xlat_entry(op_array->literals); + ZEND_ASSERT(op_array->literals != NULL); } - op_array->arg_info = arg_info; - } - if (op_array->live_range) { - op_array->live_range = zend_shared_alloc_get_xlat_entry(op_array->live_range); - ZEND_ASSERT(op_array->live_range != NULL); - } - if (op_array->doc_comment) { - if (ZCG(accel_directives).save_comments) { - op_array->doc_comment = zend_shared_alloc_get_xlat_entry(op_array->doc_comment); - ZEND_ASSERT(op_array->doc_comment != NULL); - } else { - op_array->doc_comment = NULL; + if (op_array->function_name && !IS_ACCEL_INTERNED(op_array->function_name)) { + op_array->function_name = zend_shared_alloc_get_xlat_entry(op_array->function_name); + ZEND_ASSERT(op_array->function_name != NULL); } + if (op_array->filename) { + op_array->filename = zend_shared_alloc_get_xlat_entry(op_array->filename); + ZEND_ASSERT(op_array->filename != NULL); + } + if (op_array->arg_info) { + zend_arg_info *arg_info = op_array->arg_info; + if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { + arg_info--; + } + arg_info = zend_shared_alloc_get_xlat_entry(arg_info); + ZEND_ASSERT(arg_info != NULL); + if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { + arg_info++; + } + op_array->arg_info = arg_info; + } + if (op_array->live_range) { + op_array->live_range = zend_shared_alloc_get_xlat_entry(op_array->live_range); + ZEND_ASSERT(op_array->live_range != NULL); + } + if (op_array->doc_comment) { + if (ZCG(accel_directives).save_comments) { + op_array->doc_comment = zend_shared_alloc_get_xlat_entry(op_array->doc_comment); + ZEND_ASSERT(op_array->doc_comment != NULL); + } else { + op_array->doc_comment = NULL; + } + } + if (op_array->try_catch_array) { + op_array->try_catch_array = zend_shared_alloc_get_xlat_entry(op_array->try_catch_array); + ZEND_ASSERT(op_array->try_catch_array != NULL); + } + if (op_array->vars) { + op_array->vars = zend_shared_alloc_get_xlat_entry(op_array->vars); + ZEND_ASSERT(op_array->vars != NULL); + } + ZCG(mem) = (void*)((char*)ZCG(mem) + ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist(op_array, ZCG(mem)))); + return; } - if (op_array->try_catch_array) { - op_array->try_catch_array = zend_shared_alloc_get_xlat_entry(op_array->try_catch_array); - ZEND_ASSERT(op_array->try_catch_array != NULL); - } - if (op_array->vars) { - op_array->vars = zend_shared_alloc_get_xlat_entry(op_array->vars); - ZEND_ASSERT(op_array->vars != NULL); - } - ZCG(mem) = (void*)((char*)ZCG(mem) + ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist(op_array, ZCG(mem)))); - return; + } else { + /* "prototype" may be undefined if "scope" isn't set */ + op_array->prototype = NULL; + } + + if (op_array->static_variables) { + Bucket *p; + + zend_hash_persist(op_array->static_variables); + ZEND_HASH_FOREACH_BUCKET(op_array->static_variables, p) { + ZEND_ASSERT(p->key != NULL); + zend_accel_store_interned_string(p->key); + zend_persist_zval(&p->val); + } ZEND_HASH_FOREACH_END(); + op_array->static_variables = zend_shared_memdup_put_free(op_array->static_variables, sizeof(HashTable)); + /* make immutable array */ + GC_SET_REFCOUNT(op_array->static_variables, 2); + GC_TYPE_INFO(op_array->static_variables) = IS_ARRAY | (IS_ARRAY_IMMUTABLE << GC_FLAGS_SHIFT); } + ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables); if (op_array->literals) { zval *p, *end; @@ -788,6 +694,7 @@ static void zend_persist_class_constant(zval *zv) static void zend_persist_class_entry(zval *zv) { + Bucket *p; zend_class_entry *ce = Z_PTR_P(zv); if (ce->type == ZEND_USER_CLASS) { @@ -806,7 +713,12 @@ static void zend_persist_class_entry(zval *zv) if (ce->parent_name && !(ce->ce_flags & ZEND_ACC_LINKED)) { zend_accel_store_interned_string(ce->parent_name); } - zend_hash_persist(&ce->function_table, zend_persist_class_method); + zend_hash_persist(&ce->function_table); + ZEND_HASH_FOREACH_BUCKET(&ce->function_table, p) { + ZEND_ASSERT(p->key != NULL); + zend_accel_store_interned_string(p->key); + zend_persist_class_method(&p->val); + } ZEND_HASH_FOREACH_END(); HT_FLAGS(&ce->function_table) &= (HASH_FLAG_UNINITIALIZED | HASH_FLAG_STATIC_KEYS); if (ce->default_properties_table) { int i; @@ -835,7 +747,12 @@ static void zend_persist_class_entry(zval *zv) ZEND_MAP_PTR_INIT(ce->static_members_table, &ce->default_static_members_table); } - zend_hash_persist(&ce->constants_table, zend_persist_class_constant); + zend_hash_persist(&ce->constants_table); + ZEND_HASH_FOREACH_BUCKET(&ce->constants_table, p) { + ZEND_ASSERT(p->key != NULL); + zend_accel_store_interned_string(p->key); + zend_persist_class_constant(&p->val); + } ZEND_HASH_FOREACH_END(); HT_FLAGS(&ce->constants_table) &= (HASH_FLAG_UNINITIALIZED | HASH_FLAG_STATIC_KEYS); if (ce->info.user.filename) { @@ -853,7 +770,12 @@ static void zend_persist_class_entry(zval *zv) ce->info.user.doc_comment = NULL; } } - zend_hash_persist(&ce->properties_info, zend_persist_property_info); + zend_hash_persist(&ce->properties_info); + ZEND_HASH_FOREACH_BUCKET(&ce->properties_info, p) { + ZEND_ASSERT(p->key != NULL); + zend_accel_store_interned_string(p->key); + zend_persist_property_info(&p->val); + } ZEND_HASH_FOREACH_END(); HT_FLAGS(&ce->properties_info) &= (HASH_FLAG_UNINITIALIZED | HASH_FLAG_STATIC_KEYS); if (ce->properties_info_table) { @@ -1097,9 +1019,15 @@ static void zend_update_parent_ce(zend_class_entry *ce) static void zend_accel_persist_class_table(HashTable *class_table) { + Bucket *p; zend_class_entry *ce; - zend_hash_persist(class_table, zend_persist_class_entry); + zend_hash_persist(class_table); + ZEND_HASH_FOREACH_BUCKET(class_table, p) { + ZEND_ASSERT(p->key != NULL); + zend_accel_store_interned_string(p->key); + zend_persist_class_entry(&p->val); + } ZEND_HASH_FOREACH_END(); ZEND_HASH_FOREACH_PTR(class_table, ce) { zend_update_parent_ce(ce); } ZEND_HASH_FOREACH_END(); @@ -1107,6 +1035,8 @@ static void zend_accel_persist_class_table(HashTable *class_table) zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, const char **key, unsigned int key_length, int for_shm) { + Bucket *p; + script->mem = ZCG(mem); ZEND_ASSERT(((zend_uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */ @@ -1139,7 +1069,12 @@ zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script zend_map_ptr_extend(ZCSG(map_ptr_last)); zend_accel_persist_class_table(&script->script.class_table); - zend_hash_persist(&script->script.function_table, zend_persist_op_array); + zend_hash_persist(&script->script.function_table); + ZEND_HASH_FOREACH_BUCKET(&script->script.function_table, p) { + ZEND_ASSERT(p->key != NULL); + zend_accel_store_interned_string(p->key); + zend_persist_op_array(&p->val); + } ZEND_HASH_FOREACH_END(); zend_persist_op_array_ex(&script->script.main_op_array, script); ZCSG(map_ptr_last) = CG(map_ptr_last); diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c index 774f42185f..ca96da7ffa 100644 --- a/ext/opcache/zend_persist_calc.c +++ b/ext/opcache/zend_persist_calc.c @@ -55,43 +55,24 @@ static void zend_persist_zval_calc(zval *z); -static void zend_hash_persist_calc(HashTable *ht, void (*pPersistElement)(zval *pElement)) +static void zend_hash_persist_calc(HashTable *ht) { - uint32_t idx; - Bucket *p; - if ((HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) || ht->nNumUsed == 0) { return; } - if (!(HT_FLAGS(ht) & HASH_FLAG_PACKED) && ht->nNumUsed < (uint32_t)(-(int32_t)ht->nTableMask) / 4) { + if (!(HT_FLAGS(ht) & HASH_FLAG_PACKED) && ht->nNumUsed > HT_MIN_SIZE && ht->nNumUsed < (uint32_t)(-(int32_t)ht->nTableMask) / 4) { /* compact table */ uint32_t hash_size; - if (ht->nNumUsed <= HT_MIN_SIZE) { - hash_size = HT_MIN_SIZE * 2; - } else { - hash_size = (uint32_t)(-(int32_t)ht->nTableMask); - while (hash_size >> 2 > ht->nNumUsed) { - hash_size >>= 1; - } + hash_size = (uint32_t)(-(int32_t)ht->nTableMask); + while (hash_size >> 2 > ht->nNumUsed) { + hash_size >>= 1; } ADD_SIZE(hash_size * sizeof(uint32_t) + ht->nNumUsed * sizeof(Bucket)); } else { 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) { - ADD_INTERNED_STRING(p->key); - } - - pPersistElement(&p->val); - } } static void zend_persist_ast_calc(zend_ast *ast) @@ -134,8 +115,16 @@ static void zend_persist_zval_calc(zval *z) case IS_ARRAY: size = zend_shared_memdup_size(Z_ARR_P(z), sizeof(zend_array)); if (size) { + Bucket *p; + ADD_SIZE(size); - zend_hash_persist_calc(Z_ARRVAL_P(z), zend_persist_zval_calc); + zend_hash_persist_calc(Z_ARRVAL_P(z)); + ZEND_HASH_FOREACH_BUCKET(Z_ARRVAL_P(z), p) { + if (p->key) { + ADD_INTERNED_STRING(p->key); + } + zend_persist_zval_calc(&p->val); + } ZEND_HASH_FOREACH_END(); } break; case IS_REFERENCE: @@ -157,15 +146,7 @@ static void zend_persist_zval_calc(zval *z) static void zend_persist_op_array_calc_ex(zend_op_array *op_array) { - if (op_array->static_variables) { - if (!zend_shared_alloc_get_xlat_entry(op_array->static_variables)) { - zend_shared_alloc_register_xlat_entry(op_array->static_variables, op_array->static_variables); - ADD_SIZE(sizeof(HashTable)); - zend_hash_persist_calc(op_array->static_variables, zend_persist_zval_calc); - } - } - - if (zend_shared_alloc_get_xlat_entry(op_array->opcodes)) { + if (op_array->scope && zend_shared_alloc_get_xlat_entry(op_array->opcodes)) { /* already stored */ if (op_array->function_name) { zend_string *new_name = zend_shared_alloc_get_xlat_entry(op_array->function_name); @@ -177,6 +158,21 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array) return; } + if (op_array->static_variables) { + if (!zend_shared_alloc_get_xlat_entry(op_array->static_variables)) { + Bucket *p; + + zend_shared_alloc_register_xlat_entry(op_array->static_variables, op_array->static_variables); + ADD_SIZE(sizeof(HashTable)); + zend_hash_persist_calc(op_array->static_variables); + ZEND_HASH_FOREACH_BUCKET(op_array->static_variables, p) { + ZEND_ASSERT(p->key != NULL); + ADD_INTERNED_STRING(p->key); + zend_persist_zval_calc(&p->val); + } ZEND_HASH_FOREACH_END(); + } + } + if (op_array->literals) { zval *p = op_array->literals; zval *end = p + op_array->last_literal; @@ -351,6 +347,7 @@ static void check_property_type_resolution(zend_class_entry *ce) { static void zend_persist_class_entry_calc(zval *zv) { zend_class_entry *ce = Z_PTR_P(zv); + Bucket *p; if (ce->type == ZEND_USER_CLASS) { check_property_type_resolution(ce); @@ -366,7 +363,12 @@ static void zend_persist_class_entry_calc(zval *zv) if (ce->parent_name && !(ce->ce_flags & ZEND_ACC_LINKED)) { ADD_INTERNED_STRING(ce->parent_name); } - zend_hash_persist_calc(&ce->function_table, zend_persist_class_method_calc); + zend_hash_persist_calc(&ce->function_table); + ZEND_HASH_FOREACH_BUCKET(&ce->function_table, p) { + ZEND_ASSERT(p->key != NULL); + ADD_INTERNED_STRING(p->key); + zend_persist_class_method_calc(&p->val); + } ZEND_HASH_FOREACH_END(); if (ce->default_properties_table) { int i; @@ -385,7 +387,12 @@ static void zend_persist_class_entry_calc(zval *zv) } } } - zend_hash_persist_calc(&ce->constants_table, zend_persist_class_constant_calc); + zend_hash_persist_calc(&ce->constants_table); + ZEND_HASH_FOREACH_BUCKET(&ce->constants_table, p) { + ZEND_ASSERT(p->key != NULL); + ADD_INTERNED_STRING(p->key); + zend_persist_class_constant_calc(&p->val); + } ZEND_HASH_FOREACH_END(); if (ce->info.user.filename) { ADD_STRING(ce->info.user.filename); @@ -394,7 +401,12 @@ static void zend_persist_class_entry_calc(zval *zv) ADD_STRING(ce->info.user.doc_comment); } - zend_hash_persist_calc(&ce->properties_info, zend_persist_property_info_calc); + zend_hash_persist_calc(&ce->properties_info); + ZEND_HASH_FOREACH_BUCKET(&ce->properties_info, p) { + ZEND_ASSERT(p->key != NULL); + ADD_INTERNED_STRING(p->key); + zend_persist_property_info_calc(&p->val); + } ZEND_HASH_FOREACH_END(); if (ce->properties_info_table) { ADD_SIZE_EX(sizeof(zend_property_info *) * ce->default_properties_count); @@ -468,11 +480,20 @@ static void zend_persist_class_entry_calc(zval *zv) static void zend_accel_persist_class_table_calc(HashTable *class_table) { - zend_hash_persist_calc(class_table, zend_persist_class_entry_calc); + Bucket *p; + + zend_hash_persist_calc(class_table); + ZEND_HASH_FOREACH_BUCKET(class_table, p) { + ZEND_ASSERT(p->key != NULL); + ADD_INTERNED_STRING(p->key); + zend_persist_class_entry_calc(&p->val); + } ZEND_HASH_FOREACH_END(); } uint32_t zend_accel_script_persist_calc(zend_persistent_script *new_persistent_script, const char *key, unsigned int key_length, int for_shm) { + Bucket *p; + new_persistent_script->mem = NULL; new_persistent_script->size = 0; new_persistent_script->arena_mem = NULL; @@ -504,7 +525,12 @@ uint32_t zend_accel_script_persist_calc(zend_persistent_script *new_persistent_s if (new_persistent_script->script.function_table.nNumUsed != new_persistent_script->script.function_table.nNumOfElements) { zend_hash_rehash(&new_persistent_script->script.function_table); } - zend_hash_persist_calc(&new_persistent_script->script.function_table, zend_persist_op_array_calc); + zend_hash_persist_calc(&new_persistent_script->script.function_table); + ZEND_HASH_FOREACH_BUCKET(&new_persistent_script->script.function_table, p) { + ZEND_ASSERT(p->key != NULL); + ADD_INTERNED_STRING(p->key); + zend_persist_op_array_calc(&p->val); + } ZEND_HASH_FOREACH_END(); zend_persist_op_array_calc_ex(&new_persistent_script->script.main_op_array); #if defined(__AVX__) || defined(__SSE2__)