diff options
Diffstat (limited to 'ext/opcache/zend_persist_calc.c')
-rw-r--r-- | ext/opcache/zend_persist_calc.c | 201 |
1 files changed, 104 insertions, 97 deletions
diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c index 9de02e91e2..c3292ec2a1 100644 --- a/ext/opcache/zend_persist_calc.c +++ b/ext/opcache/zend_persist_calc.c @@ -29,15 +29,6 @@ #define ADD_DUP_SIZE(m,s) ZCG(current_persistent_script)->size += zend_shared_memdup_size((void*)m, s) #define ADD_SIZE(m) ZCG(current_persistent_script)->size += ZEND_ALIGNED_SIZE(m) -#define ADD_ARENA_SIZE(m) ZCG(current_persistent_script)->arena_size += ZEND_ALIGNED_SIZE(m) - -#define ADD_SIZE_EX(m) do { \ - if (ZCG(is_immutable_class)) { \ - ADD_SIZE(m); \ - } else { \ - ADD_ARENA_SIZE(m); \ - } \ - } while (0) # define ADD_STRING(str) ADD_DUP_SIZE((str), _ZSTR_STRUCT_SIZE(ZSTR_LEN(str))) @@ -55,6 +46,7 @@ } while (0) static void zend_persist_zval_calc(zval *z); +static void zend_persist_op_array_calc(zval *zv); static void zend_hash_persist_calc(HashTable *ht) { @@ -114,6 +106,10 @@ static void zend_persist_zval_calc(zval *z) } break; case IS_ARRAY: + if (!ZCG(current_persistent_script)->corrupted + && zend_accel_in_shm(Z_ARR_P(z))) { + return; + } size = zend_shared_memdup_size(Z_ARR_P(z), sizeof(zend_array)); if (size) { Bucket *p; @@ -129,10 +125,13 @@ static void zend_persist_zval_calc(zval *z) } break; case IS_CONSTANT_AST: - size = zend_shared_memdup_size(Z_AST_P(z), sizeof(zend_ast_ref)); - if (size) { - ADD_SIZE(size); - zend_persist_ast_calc(Z_ASTVAL_P(z)); + if (ZCG(current_persistent_script)->corrupted + || !zend_accel_in_shm(Z_AST_P(z))) { + size = zend_shared_memdup_size(Z_AST_P(z), sizeof(zend_ast_ref)); + if (size) { + ADD_SIZE(size); + zend_persist_ast_calc(Z_ASTVAL_P(z)); + } } break; default: @@ -143,7 +142,9 @@ static void zend_persist_zval_calc(zval *z) static void zend_persist_attributes_calc(HashTable *attributes) { - if (!zend_shared_alloc_get_xlat_entry(attributes)) { + if (!zend_shared_alloc_get_xlat_entry(attributes) + && (ZCG(current_persistent_script)->corrupted + || !zend_accel_in_shm(attributes))) { zend_attribute *attr; uint32_t i; @@ -169,11 +170,7 @@ static void zend_persist_attributes_calc(HashTable *attributes) static void zend_persist_type_calc(zend_type *type) { if (ZEND_TYPE_HAS_LIST(*type)) { - if (ZEND_TYPE_USES_ARENA(*type) && !ZCG(is_immutable_class)) { - ADD_ARENA_SIZE(ZEND_TYPE_LIST_SIZE(ZEND_TYPE_LIST(*type)->num_types)); - } else { - ADD_SIZE(ZEND_TYPE_LIST_SIZE(ZEND_TYPE_LIST(*type)->num_types)); - } + ADD_SIZE(ZEND_TYPE_LIST_SIZE(ZEND_TYPE_LIST(*type)->num_types)); } zend_type *single_type; @@ -198,13 +195,21 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array) } } - if (op_array->scope && zend_shared_alloc_get_xlat_entry(op_array->opcodes)) { - /* already stored */ - ADD_SIZE(ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist_calc(op_array))); + if (op_array->scope) { + if (zend_shared_alloc_get_xlat_entry(op_array->opcodes)) { + /* already stored */ + ADD_SIZE(ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist_calc(op_array))); + return; + } + } + + if (op_array->scope + && !(op_array->fn_flags & ZEND_ACC_CLOSURE) + && (op_array->scope->ce_flags & ZEND_ACC_CACHED)) { return; } - if (op_array->static_variables) { + if (op_array->static_variables && !zend_accel_in_shm(op_array->static_variables)) { if (!zend_shared_alloc_get_xlat_entry(op_array->static_variables)) { Bucket *p; @@ -283,18 +288,28 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array) } } + if (op_array->num_dynamic_func_defs) { + ADD_SIZE(sizeof(void *) * op_array->num_dynamic_func_defs); + for (uint32_t i = 0; i < op_array->num_dynamic_func_defs; i++) { + zval tmp; + ZVAL_PTR(&tmp, op_array->dynamic_func_defs[i]); + zend_persist_op_array_calc(&tmp); + } + } + ADD_SIZE(ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist_calc(op_array))); } static void zend_persist_op_array_calc(zval *zv) { zend_op_array *op_array = Z_PTR_P(zv); - ZEND_ASSERT(op_array->type == ZEND_USER_FUNCTION); - ADD_SIZE(sizeof(zend_op_array)); - zend_persist_op_array_calc_ex(Z_PTR_P(zv)); - if (ZCG(current_persistent_script)->corrupted) { - ADD_ARENA_SIZE(sizeof(void*)); + if (!zend_shared_alloc_get_xlat_entry(op_array)) { + zend_shared_alloc_register_xlat_entry(op_array, op_array); + ADD_SIZE(sizeof(zend_op_array)); + zend_persist_op_array_calc_ex(op_array); + } else { + /* This can happen during preloading, if a dynamic function definition is declared. */ } } @@ -308,21 +323,26 @@ static void zend_persist_class_method_calc(zval *zv) if (op_array->fn_flags & ZEND_ACC_ARENA_ALLOCATED) { old_op_array = zend_shared_alloc_get_xlat_entry(op_array); if (!old_op_array) { - ADD_SIZE_EX(sizeof(zend_internal_function)); + ADD_SIZE(sizeof(zend_internal_function)); zend_shared_alloc_register_xlat_entry(op_array, Z_PTR_P(zv)); } } return; } + if ((op_array->fn_flags & ZEND_ACC_IMMUTABLE) + && !op_array->static_variables + && !ZCG(current_persistent_script)->corrupted + && zend_accel_in_shm(op_array)) { + zend_shared_alloc_register_xlat_entry(op_array, op_array); + return; + } + old_op_array = zend_shared_alloc_get_xlat_entry(op_array); if (!old_op_array) { - ADD_SIZE_EX(sizeof(zend_op_array)); + ADD_SIZE(sizeof(zend_op_array)); zend_persist_op_array_calc_ex(Z_PTR_P(zv)); zend_shared_alloc_register_xlat_entry(op_array, Z_PTR_P(zv)); - if (!ZCG(is_immutable_class)) { - ADD_ARENA_SIZE(sizeof(void*)); - } } else { /* If op_array is shared, the function name refcount is still incremented for each use, * so we need to release it here. We remembered the original function name in xlat. */ @@ -336,7 +356,7 @@ static void zend_persist_class_method_calc(zval *zv) static void zend_persist_property_info_calc(zend_property_info *prop) { - ADD_SIZE_EX(sizeof(zend_property_info)); + ADD_SIZE(sizeof(zend_property_info)); ADD_INTERNED_STRING(prop->name); zend_persist_type_calc(&prop->type); if (ZCG(accel_directives).save_comments && prop->doc_comment) { @@ -352,8 +372,12 @@ static void zend_persist_class_constant_calc(zval *zv) zend_class_constant *c = Z_PTR_P(zv); if (!zend_shared_alloc_get_xlat_entry(c)) { + if (!ZCG(current_persistent_script)->corrupted + && zend_accel_in_shm(Z_PTR_P(zv))) { + return; + } zend_shared_alloc_register_xlat_entry(c, c); - ADD_SIZE_EX(sizeof(zend_class_constant)); + ADD_SIZE(sizeof(zend_class_constant)); zend_persist_zval_calc(&c->value); if (ZCG(accel_directives).save_comments && c->doc_comment) { ADD_STRING(c->doc_comment); @@ -364,29 +388,8 @@ static void zend_persist_class_constant_calc(zval *zv) } } -static void check_property_type_resolution(zend_class_entry *ce) { - zend_property_info *prop; - if (ce->ce_flags & ZEND_ACC_PROPERTY_TYPES_RESOLVED) { - /* Preloading might have computed this already. */ - return; - } - - if (ce->ce_flags & ZEND_ACC_HAS_TYPE_HINTS) { - ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) { - zend_type *single_type; - ZEND_TYPE_FOREACH(prop->type, single_type) { - if (ZEND_TYPE_HAS_NAME(*single_type)) { - return; - } - } ZEND_TYPE_FOREACH_END(); - } ZEND_HASH_FOREACH_END(); - } - ce->ce_flags |= ZEND_ACC_PROPERTY_TYPES_RESOLVED; -} - -static void zend_persist_class_entry_calc(zval *zv) +void zend_persist_class_entry_calc(zend_class_entry *ce) { - zend_class_entry *ce = Z_PTR_P(zv); Bucket *p; if (ce->type == ZEND_USER_CLASS) { @@ -396,19 +399,15 @@ static void zend_persist_class_entry_calc(zval *zv) } zend_shared_alloc_register_xlat_entry(ce, ce); - check_property_type_resolution(ce); - - ZCG(is_immutable_class) = - (ce->ce_flags & ZEND_ACC_LINKED) && - (ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED) && - (ce->ce_flags & ZEND_ACC_PROPERTY_TYPES_RESOLVED) && - !ZCG(current_persistent_script)->corrupted; + ADD_SIZE(sizeof(zend_class_entry)); - ADD_SIZE_EX(sizeof(zend_class_entry)); - ADD_INTERNED_STRING(ce->name); - if (ce->parent_name && !(ce->ce_flags & ZEND_ACC_LINKED)) { - ADD_INTERNED_STRING(ce->parent_name); + if (!(ce->ce_flags & ZEND_ACC_CACHED)) { + ADD_INTERNED_STRING(ce->name); + if (ce->parent_name && !(ce->ce_flags & ZEND_ACC_LINKED)) { + ADD_INTERNED_STRING(ce->parent_name); + } } + zend_hash_persist_calc(&ce->function_table); ZEND_HASH_FOREACH_BUCKET(&ce->function_table, p) { ZEND_ASSERT(p->key != NULL); @@ -440,16 +439,6 @@ static void zend_persist_class_entry_calc(zval *zv) zend_persist_class_constant_calc(&p->val); } ZEND_HASH_FOREACH_END(); - if (ce->info.user.filename) { - ADD_STRING(ce->info.user.filename); - } - if (ZCG(accel_directives).save_comments && ce->info.user.doc_comment) { - ADD_STRING(ce->info.user.doc_comment); - } - if (ce->attributes) { - zend_persist_attributes_calc(ce->attributes); - } - zend_hash_persist_calc(&ce->properties_info); ZEND_HASH_FOREACH_BUCKET(&ce->properties_info, p) { zend_property_info *prop = Z_PTR(p->val); @@ -461,7 +450,31 @@ static void zend_persist_class_entry_calc(zval *zv) } ZEND_HASH_FOREACH_END(); if (ce->properties_info_table) { - ADD_SIZE_EX(sizeof(zend_property_info *) * ce->default_properties_count); + ADD_SIZE(sizeof(zend_property_info *) * ce->default_properties_count); + } + + if (ce->num_interfaces && (ce->ce_flags & ZEND_ACC_LINKED)) { + ADD_SIZE(sizeof(zend_class_entry*) * ce->num_interfaces); + } + + if (ce->iterator_funcs_ptr) { + ADD_SIZE(sizeof(zend_class_iterator_funcs)); + } + + if (ce->ce_flags & ZEND_ACC_CACHED) { + return; + } + + if (ce->info.user.filename) { + ADD_STRING(ce->info.user.filename); + } + + if (ZCG(accel_directives).save_comments && ce->info.user.doc_comment) { + ADD_STRING(ce->info.user.doc_comment); + } + + if (ce->attributes) { + zend_persist_attributes_calc(ce->attributes); } if (ce->num_interfaces) { @@ -473,8 +486,6 @@ static void zend_persist_class_entry_calc(zval *zv) ADD_INTERNED_STRING(ce->interface_names[i].lc_name); } ADD_SIZE(sizeof(zend_class_name) * ce->num_interfaces); - } else { - ADD_SIZE(sizeof(zend_class_entry*) * ce->num_interfaces); } } @@ -524,8 +535,16 @@ static void zend_persist_class_entry_calc(zval *zv) } } - if (ce->iterator_funcs_ptr) { - ADD_SIZE(sizeof(zend_class_iterator_funcs)); + if (ce->backed_enum_table) { + Bucket *p; + ADD_SIZE(sizeof(HashTable)); + zend_hash_persist_calc(ce->backed_enum_table); + ZEND_HASH_FOREACH_BUCKET(ce->backed_enum_table, p) { + if (p->key != NULL) { + ADD_INTERNED_STRING(p->key); + } + zend_persist_zval_calc(&p->val); + } ZEND_HASH_FOREACH_END(); } } } @@ -538,7 +557,7 @@ static void zend_accel_persist_class_table_calc(HashTable *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_persist_class_entry_calc(Z_CE(p->val)); } ZEND_HASH_FOREACH_END(); } @@ -551,14 +570,12 @@ static void zend_persist_warnings_calc(zend_persistent_script *script) { } } -uint32_t zend_accel_script_persist_calc(zend_persistent_script *new_persistent_script, const char *key, unsigned int key_length, int for_shm) +uint32_t zend_accel_script_persist_calc(zend_persistent_script *new_persistent_script, int for_shm) { Bucket *p; new_persistent_script->mem = NULL; new_persistent_script->size = 0; - new_persistent_script->arena_mem = NULL; - new_persistent_script->arena_size = 0; new_persistent_script->corrupted = 0; ZCG(current_persistent_script) = new_persistent_script; @@ -568,10 +585,6 @@ uint32_t zend_accel_script_persist_calc(zend_persistent_script *new_persistent_s } ADD_SIZE(sizeof(zend_persistent_script)); - if (key) { - ADD_SIZE(key_length + 1); - zend_shared_alloc_register_xlat_entry(key, key); - } ADD_STRING(new_persistent_script->script.filename); #if defined(__AVX__) || defined(__SSE2__) @@ -595,12 +608,6 @@ uint32_t zend_accel_script_persist_calc(zend_persistent_script *new_persistent_s zend_persist_op_array_calc_ex(&new_persistent_script->script.main_op_array); zend_persist_warnings_calc(new_persistent_script); -#if defined(__AVX__) || defined(__SSE2__) - /* Align size to 64-byte boundary */ - new_persistent_script->arena_size = (new_persistent_script->arena_size + 63) & ~63; -#endif - - new_persistent_script->size += new_persistent_script->arena_size; new_persistent_script->corrupted = 0; ZCG(current_persistent_script) = NULL; |