diff options
author | Dmitry Stogov <dmitry@zend.com> | 2015-05-20 23:12:04 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2015-05-20 23:12:04 +0300 |
commit | 5ff5201543971bb793b634d7dab5f0dc7f802a60 (patch) | |
tree | 83f862912de51c537d83b01eb50a4a6be311f652 | |
parent | d6bcf2bf2e90eeda9155e70d757cc76412835925 (diff) | |
download | php-git-5ff5201543971bb793b634d7dab5f0dc7f802a60.tar.gz |
Improved script copyining from SHM to process memory
-rw-r--r-- | ext/opcache/zend_accelerator_util_funcs.c | 239 |
1 files changed, 71 insertions, 168 deletions
diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index d3abaca7ff..990639aeb4 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -40,7 +40,6 @@ typedef int (*id_function_t)(void *, void *); typedef void (*unique_copy_ctor_func_t)(void *pElement); -static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind); static zend_ast *zend_ast_clone(zend_ast *ast); static void zend_accel_destroy_zend_function(zval *zv) @@ -153,80 +152,36 @@ void zend_accel_copy_internal_functions(void) ZCG(internal_functions_count) = zend_hash_num_elements(&ZCG(function_table)); } -static zend_always_inline zend_string *zend_clone_str(zend_string *str) -{ - zend_string *ret; - - if (EXPECTED(IS_INTERNED(str))) { - ret = str; - } else if (GC_REFCOUNT(str) <= 1 || (ret = accel_xlat_get(str)) == NULL) { - ret = zend_string_dup(str, 0); - GC_FLAGS(ret) = GC_FLAGS(str); - if (GC_REFCOUNT(str) > 1) { - accel_xlat_set(str, ret); - } - } else { - GC_REFCOUNT(ret)++; - } - return ret; -} - -static inline void zend_clone_zval(zval *src, int bind) +static inline void zend_clone_zval(zval *src) { void *ptr; - if (Z_IMMUTABLE_P(src)) { - return; + if (Z_TYPE_P(src) == IS_REFERENCE) { + ptr = accel_xlat_get(Z_REF_P(src)); + if (ptr != NULL) { + Z_REF_P(src) = ptr; + return; + } else { + zend_reference *old = Z_REF_P(src); + ZVAL_NEW_REF(src, &old->val); + Z_REF_P(src)->gc = old->gc; + accel_xlat_set(old, Z_REF_P(src)); + src = Z_REFVAL_P(src); + } } + if (Z_TYPE_P(src) == IS_CONSTANT_AST) { + if (Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_AST_P(src))) != NULL) { + Z_AST_P(src) = ptr; + } else { + zend_ast_ref *old = Z_AST_P(src); - switch (Z_TYPE_P(src)) { - case IS_STRING: - case IS_CONSTANT: - Z_STR_P(src) = zend_clone_str(Z_STR_P(src)); - break; - case IS_ARRAY: - if (Z_ARR_P(src) != &EG(symbol_table)) { - if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_ARR_P(src))) != NULL) { - Z_ARR_P(src) = ptr; - } else { - zend_array *old = Z_ARR_P(src); - - Z_ARR_P(src) = emalloc(sizeof(zend_array)); - Z_ARR_P(src)->gc = old->gc; - if (bind && Z_REFCOUNT_P(src) > 1) { - accel_xlat_set(old, Z_ARR_P(src)); - } - zend_hash_clone_zval(Z_ARRVAL_P(src), old, 0); - } - } - break; - case IS_REFERENCE: - if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_REF_P(src))) != NULL) { - Z_REF_P(src) = ptr; - } else { - zend_reference *old = Z_REF_P(src); - ZVAL_NEW_REF(src, &old->val); - Z_REF_P(src)->gc = old->gc; - if (bind && Z_REFCOUNT_P(src) > 1) { - accel_xlat_set(old, Z_REF_P(src)); - } - zend_clone_zval(Z_REFVAL_P(src), bind); - } - break; - case IS_CONSTANT_AST: - if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_AST_P(src))) != NULL) { - Z_AST_P(src) = ptr; - } else { - zend_ast_ref *old = Z_AST_P(src); - - ZVAL_NEW_AST(src, old->ast); - Z_AST_P(src)->gc = old->gc; - if (bind && Z_REFCOUNT_P(src) > 1) { - accel_xlat_set(old, Z_AST_P(src)); - } - Z_ASTVAL_P(src) = zend_ast_clone(Z_ASTVAL_P(src)); + ZVAL_NEW_AST(src, old->ast); + Z_AST_P(src)->gc = old->gc; + if (Z_REFCOUNT_P(src) > 1) { + accel_xlat_set(old, Z_AST_P(src)); } - break; + Z_ASTVAL_P(src) = zend_ast_clone(Z_ASTVAL_P(src)); + } } } @@ -239,7 +194,6 @@ static zend_ast *zend_ast_clone(zend_ast *ast) copy->kind = ZEND_AST_ZVAL; copy->attr = ast->attr; ZVAL_COPY_VALUE(©->val, zend_ast_get_zval(ast)); - zend_clone_zval(©->val, 0); return (zend_ast *) copy; } else if (zend_ast_is_list(ast)) { zend_ast_list *list = zend_ast_get_list(ast); @@ -272,10 +226,9 @@ static zend_ast *zend_ast_clone(zend_ast *ast) } } -static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind) +static void zend_hash_clone_constants(HashTable *ht, HashTable *source) { - uint idx; - Bucket *p, *q, *r; + Bucket *p, *q, *end; zend_ulong nIndex; ht->nTableSize = source->nTableSize; @@ -292,65 +245,34 @@ static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind) return; } - if (source->u.flags & HASH_FLAG_PACKED) { - ht->u.flags |= HASH_FLAG_PACKED; - HT_SET_DATA_ADDR(ht, (Bucket *) emalloc(HT_SIZE(ht))); - HT_HASH_RESET_PACKED(ht); - - for (idx = 0; idx < source->nNumUsed; idx++) { - p = source->arData + idx; - if (Z_TYPE(p->val) == IS_UNDEF) continue; - nIndex = p->h | ht->nTableMask; + ZEND_ASSERT((source->u.flags & HASH_FLAG_PACKED) == 0); + HT_SET_DATA_ADDR(ht, emalloc(HT_SIZE(ht))); + HT_HASH_RESET(ht); - r = ht->arData + ht->nNumUsed; - q = ht->arData + p->h; - while (r != q) { - ZVAL_UNDEF(&r->val); - r++; - } - ht->nNumUsed = p->h + 1; + p = source->arData; + end = p + source->nNumUsed; + for (; p != end; p++) { + if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue; + nIndex = p->h | ht->nTableMask; - /* Initialize key */ - q->h = p->h; - q->key = NULL; + /* Insert into hash collision list */ + q = ht->arData + ht->nNumUsed; + Z_NEXT(q->val) = HT_HASH(ht, nIndex); + HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(ht->nNumUsed++); - /* Copy data */ - ZVAL_COPY_VALUE(&q->val, &p->val); - zend_clone_zval(&q->val, bind); - } - } else { - HT_SET_DATA_ADDR(ht, emalloc(HT_SIZE(ht))); - HT_HASH_RESET(ht); - - for (idx = 0; idx < source->nNumUsed; idx++) { - p = source->arData + idx; - if (Z_TYPE(p->val) == IS_UNDEF) continue; - nIndex = p->h | ht->nTableMask; - - /* Insert into hash collision list */ - q = ht->arData + ht->nNumUsed; - Z_NEXT(q->val) = HT_HASH(ht, nIndex); - HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(ht->nNumUsed++); - - /* Initialize key */ - q->h = p->h; - if (!p->key) { - q->key = NULL; - } else { - q->key = zend_clone_str(p->key); - } + /* Initialize key */ + q->h = p->h; + q->key = p->key; - /* Copy data */ - ZVAL_COPY_VALUE(&q->val, &p->val); - zend_clone_zval(&q->val, bind); - } + /* Copy data */ + ZVAL_COPY_VALUE(&q->val, &p->val); + zend_clone_zval(&q->val); } } static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class_entry *old_ce, zend_class_entry *ce) { - uint idx; - Bucket *p, *q; + Bucket *p, *q, *end; zend_ulong nIndex; zend_op_array *new_entry; @@ -372,9 +294,10 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class HT_SET_DATA_ADDR(ht, emalloc(HT_SIZE(ht))); HT_HASH_RESET(ht); - for (idx = 0; idx < source->nNumUsed; idx++) { - p = source->arData + idx; - if (Z_TYPE(p->val) == IS_UNDEF) continue; + p = source->arData; + end = p + source->nNumUsed; + for (; p != end; p++) { + if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue; nIndex = p->h | ht->nTableMask; @@ -386,7 +309,7 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class /* Initialize key */ q->h = p->h; ZEND_ASSERT(p->key != NULL); - q->key = zend_clone_str(p->key); + q->key = p->key; /* Copy data */ ZVAL_PTR(&q->val, ARENA_REALLOC(Z_PTR(p->val))); @@ -407,8 +330,7 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_class_entry *old_ce) { - uint idx; - Bucket *p, *q; + Bucket *p, *q, *end; zend_ulong nIndex; zend_property_info *prop_info; @@ -430,9 +352,10 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla HT_SET_DATA_ADDR(ht, emalloc(HT_SIZE(ht))); HT_HASH_RESET(ht); - for (idx = 0; idx < source->nNumUsed; idx++) { - p = source->arData + idx; - if (Z_TYPE(p->val) == IS_UNDEF) continue; + p = source->arData; + end = p + source->nNumUsed; + for (; p != end; p++) { + if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue; nIndex = p->h | ht->nTableMask; @@ -444,7 +367,7 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla /* Initialize key */ q->h = p->h; ZEND_ASSERT(p->key != NULL); - q->key = zend_clone_str(p->key); + q->key = p->key; /* Copy data */ prop_info = ARENA_REALLOC(Z_PTR(p->val)); @@ -452,7 +375,6 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla if (prop_info->ce == old_ce || (prop_info->flags & ZEND_ACC_SHADOW)) { /* Copy constructor */ - prop_info->name = zend_clone_str(prop_info->name); if (prop_info->doc_comment) { if (ZCG(accel_directives).load_comments) { prop_info->doc_comment = zend_string_dup(prop_info->doc_comment, 0); @@ -480,17 +402,19 @@ static void zend_class_copy_ctor(zend_class_entry **pce) { zend_class_entry *ce = *pce; zend_class_entry *old_ce = ce; + zval *src, *dst, *end; *pce = ce = ARENA_REALLOC(old_ce); ce->refcount = 1; if (old_ce->default_properties_table) { - int i; - ce->default_properties_table = emalloc(sizeof(zval) * old_ce->default_properties_count); - for (i = 0; i < old_ce->default_properties_count; i++) { - ZVAL_COPY_VALUE(&ce->default_properties_table[i], &old_ce->default_properties_table[i]); - zend_clone_zval(&ce->default_properties_table[i], 1); + src = old_ce->default_properties_table; + end = src + old_ce->default_properties_count; + dst = ce->default_properties_table; + for (; src != end; src++, dst++) { + ZVAL_COPY_VALUE(dst, src); + zend_clone_zval(dst); } } @@ -498,12 +422,13 @@ static void zend_class_copy_ctor(zend_class_entry **pce) /* static members */ if (old_ce->default_static_members_table) { - int i; - ce->default_static_members_table = emalloc(sizeof(zval) * old_ce->default_static_members_count); - for (i = 0; i < old_ce->default_static_members_count; i++) { - ZVAL_COPY_VALUE(&ce->default_static_members_table[i], &old_ce->default_static_members_table[i]); - zend_clone_zval(&ce->default_static_members_table[i], 1); + src = old_ce->default_static_members_table; + end = src + old_ce->default_static_members_count; + dst = ce->default_static_members_table; + for (; src != end; src++, dst++) { + ZVAL_COPY_VALUE(dst, src); + zend_clone_zval(dst); } } ce->static_members_table = ce->default_static_members_table; @@ -512,11 +437,9 @@ static void zend_class_copy_ctor(zend_class_entry **pce) zend_hash_clone_prop_info(&ce->properties_info, &old_ce->properties_info, old_ce); /* constants table */ - zend_hash_clone_zval(&ce->constants_table, &old_ce->constants_table, 1); + zend_hash_clone_constants(&ce->constants_table, &old_ce->constants_table); ce->constants_table.u.flags &= ~HASH_FLAG_APPLY_PROTECTION; - ce->name = zend_clone_str(ce->name); - /* interfaces aren't really implemented, so we create a new table */ if (ce->num_interfaces) { ce->interfaces = emalloc(sizeof(zend_class_entry *) * ce->num_interfaces); @@ -569,21 +492,6 @@ static void zend_class_copy_ctor(zend_class_entry **pce) memcpy(trait_aliases[i], ce->trait_aliases[i], sizeof(zend_trait_alias)); trait_aliases[i]->trait_method = emalloc(sizeof(zend_trait_method_reference)); memcpy(trait_aliases[i]->trait_method, ce->trait_aliases[i]->trait_method, sizeof(zend_trait_method_reference)); - if (trait_aliases[i]->trait_method) { - if (trait_aliases[i]->trait_method->method_name) { - trait_aliases[i]->trait_method->method_name = - zend_clone_str(trait_aliases[i]->trait_method->method_name); - } - if (trait_aliases[i]->trait_method->class_name) { - trait_aliases[i]->trait_method->class_name = - zend_clone_str(trait_aliases[i]->trait_method->class_name); - } - } - - if (trait_aliases[i]->alias) { - trait_aliases[i]->alias = - zend_clone_str(trait_aliases[i]->alias); - } i++; } trait_aliases[i] = NULL; @@ -605,11 +513,6 @@ static void zend_class_copy_ctor(zend_class_entry **pce) trait_precedences[i]->trait_method = emalloc(sizeof(zend_trait_method_reference)); memcpy(trait_precedences[i]->trait_method, ce->trait_precedences[i]->trait_method, sizeof(zend_trait_method_reference)); - trait_precedences[i]->trait_method->method_name = - zend_clone_str(trait_precedences[i]->trait_method->method_name); - trait_precedences[i]->trait_method->class_name = - zend_clone_str(trait_precedences[i]->trait_method->class_name); - if (trait_precedences[i]->exclude_from_classes) { zend_string **exclude_from_classes; int j = 0; @@ -621,7 +524,7 @@ static void zend_class_copy_ctor(zend_class_entry **pce) j = 0; while (trait_precedences[i]->exclude_from_classes[j].class_name) { exclude_from_classes[j] = - zend_clone_str(trait_precedences[i]->exclude_from_classes[j].class_name); + trait_precedences[i]->exclude_from_classes[j].class_name; j++; } exclude_from_classes[j] = NULL; |