diff options
-rw-r--r-- | ext/opcache/Optimizer/optimize_temp_vars_5.c | 51 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_optimizer.c | 52 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_optimizer.h | 2 |
3 files changed, 53 insertions, 52 deletions
diff --git a/ext/opcache/Optimizer/optimize_temp_vars_5.c b/ext/opcache/Optimizer/optimize_temp_vars_5.c index cb7d4e4913..cf5d7d26a6 100644 --- a/ext/opcache/Optimizer/optimize_temp_vars_5.c +++ b/ext/opcache/Optimizer/optimize_temp_vars_5.c @@ -38,54 +38,6 @@ max = i; \ } -void optimize_adjust_fcall_stack_size(zend_op_array *callee, uint32_t delta, zend_optimizer_ctx *ctx) { - zval *val; - zend_op *start, *end; - zend_op_array *op_array; - zend_string *name; - - if (!delta || !callee->function_name) { - return; - } - - name = zend_string_tolower(callee->function_name); - op_array = &ctx->script->main_op_array; - start = op_array->opcodes; - end = op_array->opcodes + op_array->last - 1; - while (start < end) { - if (start->opcode == ZEND_INIT_FCALL) { - zval *zv = RT_CONSTANT(op_array, start->op2); - if (Z_STR_P(zv) == name || - ((Z_STRLEN_P(zv) == name->len) && - !memcmp(Z_STRVAL_P(zv), name->val, name->len))) { - start->op1.num -= (delta * sizeof(zval)); - } - } - start++; - } - - ZEND_HASH_REVERSE_FOREACH_VAL(&ctx->script->function_table, val) { - op_array = Z_PTR_P(val); - if (op_array == callee) { - continue; /* we can not break here */ - } - start = op_array->opcodes; - end = op_array->opcodes + op_array->last - 1; - while (start < end) { - if (start->opcode == ZEND_INIT_FCALL) { - zval *zv = RT_CONSTANT(op_array, start->op2); - if (Z_STR_P(zv) == name || - ((Z_STRLEN_P(zv) == name->len) && - !memcmp(Z_STRVAL_P(zv), name->val, name->len))) { - start->op1.num -= (delta * sizeof(zval)); - } - } - start++; - } - } ZEND_HASH_FOREACH_END(); - zend_string_release(name); -} - void optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_ctx *ctx) { int T = op_array->T; @@ -228,8 +180,5 @@ void optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_ctx *c } zend_arena_release(&ctx->arena, checkpoint); - if (op_array->scope == NULL) { - optimize_adjust_fcall_stack_size(op_array, op_array->T - (max + 1), ctx); - } op_array->T = max + 1; } diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 229831231e..34a95b9e5d 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -498,6 +498,26 @@ static void zend_accel_optimize(zend_op_array *op_array, } } +static void zend_accel_adjust_fcall_stack_size(zend_op_array *op_array, zend_optimizer_ctx *ctx) +{ + zend_function *func; + zend_op *opline, *end; + + opline = op_array->opcodes; + end = opline + op_array->last; + while (opline < end) { + if (opline->opcode == ZEND_INIT_FCALL) { + func = zend_hash_find_ptr( + &ctx->script->function_table, + Z_STR_P(RT_CONSTANT(op_array, opline->op2))); + if (func) { + opline->op1.num = zend_vm_calc_used_stack(opline->extended_value, func); + } + } + opline++; + } +} + int zend_accel_script_optimize(zend_persistent_script *script) { uint idx, j; @@ -540,6 +560,38 @@ int zend_accel_script_optimize(zend_persistent_script *script) } } + if (ZEND_OPTIMIZER_PASS_12 & OPTIMIZATION_LEVEL) { + zend_accel_adjust_fcall_stack_size(&script->main_op_array, &ctx); + + for (idx = 0; idx < script->function_table.nNumUsed; idx++) { + p = script->function_table.arData + idx; + if (Z_TYPE(p->val) == IS_UNDEF) continue; + op_array = (zend_op_array*)Z_PTR(p->val); + zend_accel_adjust_fcall_stack_size(op_array, &ctx); + } + + for (idx = 0; idx < script->class_table.nNumUsed; idx++) { + p = script->class_table.arData + idx; + if (Z_TYPE(p->val) == IS_UNDEF) continue; + ce = (zend_class_entry*)Z_PTR(p->val); + for (j = 0; j < ce->function_table.nNumUsed; j++) { + q = ce->function_table.arData + j; + if (Z_TYPE(q->val) == IS_UNDEF) continue; + op_array = (zend_op_array*)Z_PTR(q->val); + if (op_array->scope == ce) { + zend_accel_adjust_fcall_stack_size(op_array, &ctx); + } else if (op_array->type == ZEND_USER_FUNCTION) { + zend_op_array *orig_op_array; + if ((orig_op_array = zend_hash_find_ptr(&op_array->scope->function_table, q->key)) != NULL) { + HashTable *ht = op_array->static_variables; + *op_array = *orig_op_array; + op_array->static_variables = ht; + } + } + } + } + } + if (ctx.constants) { zend_hash_destroy(ctx.constants); } diff --git a/ext/opcache/Optimizer/zend_optimizer.h b/ext/opcache/Optimizer/zend_optimizer.h index 5092bfe2a6..cc06c8ea01 100644 --- a/ext/opcache/Optimizer/zend_optimizer.h +++ b/ext/opcache/Optimizer/zend_optimizer.h @@ -36,7 +36,7 @@ #define ZEND_OPTIMIZER_PASS_9 (1<<8) /* TMP VAR usage */ #define ZEND_OPTIMIZER_PASS_10 (1<<9) /* NOP removal */ #define ZEND_OPTIMIZER_PASS_11 (1<<10) /* Merge equal constants */ -#define ZEND_OPTIMIZER_PASS_12 (1<<11) +#define ZEND_OPTIMIZER_PASS_12 (1<<11) /* Adjust used stack */ #define ZEND_OPTIMIZER_PASS_13 (1<<12) #define ZEND_OPTIMIZER_PASS_14 (1<<13) |