diff options
Diffstat (limited to 'ext/opcache/Optimizer/zend_optimizer.c')
-rw-r--r-- | ext/opcache/Optimizer/zend_optimizer.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 35843d1970..5946d1ec8e 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -1421,6 +1421,7 @@ static void zend_adjust_fcall_stack_size_graph(zend_op_array *op_array) int zend_optimize_script(zend_script *script, zend_long optimization_level, zend_long debug_level) { zend_class_entry *ce; + zend_string *key; zend_op_array *op_array; zend_string *name; zend_optimizer_ctx ctx; @@ -1440,9 +1441,12 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level, zend zend_optimize_op_array(op_array, &ctx); } ZEND_HASH_FOREACH_END(); - ZEND_HASH_FOREACH_PTR(&script->class_table, ce) { + ZEND_HASH_FOREACH_STR_KEY_PTR(&script->class_table, key, ce) { + if (ce->refcount > 1 && !zend_string_equals_ci(key, ce->name)) { + continue; + } ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, name, op_array) { - if (op_array->scope == ce) { + if (op_array->scope == ce && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { zend_optimize_op_array(op_array, &ctx); } } ZEND_HASH_FOREACH_END(); @@ -1544,16 +1548,22 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level, zend zend_adjust_fcall_stack_size(op_array, &ctx); } ZEND_HASH_FOREACH_END(); - ZEND_HASH_FOREACH_PTR(&script->class_table, ce) { + ZEND_HASH_FOREACH_STR_KEY_PTR(&script->class_table, key, ce) { + if (ce->refcount > 1 && !zend_string_equals_ci(key, ce->name)) { + continue; + } ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, name, op_array) { - if (op_array->scope == ce) { + if (op_array->scope == ce && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { zend_adjust_fcall_stack_size(op_array, &ctx); } } ZEND_HASH_FOREACH_END(); } ZEND_HASH_FOREACH_END(); } - ZEND_HASH_FOREACH_PTR(&script->class_table, ce) { + ZEND_HASH_FOREACH_STR_KEY_PTR(&script->class_table, key, ce) { + if (ce->refcount > 1 && !zend_string_equals_ci(key, ce->name)) { + continue; + } ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, name, op_array) { if (op_array->scope != ce && op_array->type == ZEND_USER_FUNCTION) { zend_op_array *orig_op_array = @@ -1561,10 +1571,12 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level, zend ZEND_ASSERT(orig_op_array != NULL); if (orig_op_array != op_array) { + uint32_t fn_flags = op_array->fn_flags; zend_function *prototype = op_array->prototype; HashTable *ht = op_array->static_variables; *op_array = *orig_op_array; + op_array->fn_flags = fn_flags; op_array->prototype = prototype; op_array->static_variables = ht; } @@ -1582,7 +1594,7 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level, zend ZEND_HASH_FOREACH_PTR(&script->class_table, ce) { ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, name, op_array) { - if (op_array->scope == ce) { + if (op_array->scope == ce && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { zend_dump_op_array(op_array, ZEND_DUMP_RT_CONSTANTS, "after optimizer", NULL); } } ZEND_HASH_FOREACH_END(); |