From: Dmitry Stogov Date: Mon, 31 Mar 2014 14:13:16 +0000 (+0400) Subject: Optimizer related fixes (incomplete) X-Git-Tag: POST_PHPNG_MERGE~412^2~200 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7465be4fbdbcdefd38c83f9e343220304abb200d;p=php Optimizer related fixes (incomplete) --- diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 26d4f99d23..3faa6ed689 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -533,7 +533,7 @@ static void zend_rebuild_access_path(zend_cfg *cfg, zend_op_array *op_array, int #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO -# define VAR_NUM_EX(op) ((op ## _type & (IS_TMP_VAR|IS_VAR))?VAR_NUM((op).var):(op).var) +# define VAR_NUM_EX(op) VAR_NUM((op).var) # define VAR_SOURCE(op) Tsource[VAR_NUM(op.var)] # define SET_VAR_SOURCE(opline) Tsource[VAR_NUM(opline->result.var)] = opline @@ -627,7 +627,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, /* we track data dependencies only insight a single basic block */ if (op_array->T) { - Tsource = ecalloc(op_array->T, sizeof(zend_op *)); + Tsource = ecalloc(op_array->last_var + op_array->T, sizeof(zend_op *)); } opline = block->start_opline; end = opline + block->len; @@ -1637,12 +1637,13 @@ next_target: zend_op *target, *target_end; char *same_t=NULL; zend_code_block *target_block; - int var_num = 0; - if (op_array->T >= (zend_uint)op_array->last_var) { - var_num = op_array->T; - } else { - var_num = op_array->last_var; - } + int var_num = op_array->last_var + op_array->T; +//??? if (op_array->T >= (zend_uint)op_array->last_var) { +//??? var_num = op_array->T; +//??? } else { +//??? var_num = op_array->last_var; +//??? } + if (var_num <= 0) { return; } diff --git a/ext/opcache/Optimizer/compact_literals.c b/ext/opcache/Optimizer/compact_literals.c index 4fa3c7d33d..76df128ef6 100644 --- a/ext/opcache/Optimizer/compact_literals.c +++ b/ext/opcache/Optimizer/compact_literals.c @@ -378,9 +378,7 @@ static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC) Z_TYPE(op_array->literals[i].constant) == Z_TYPE(op_array->literals[*pos].constant) && info[i].flags == info[*pos].flags) { - if (info[i].flags & (LITERAL_EX_OBJ|LITERAL_EX_CLASS)) { - efree(key); - } + STR_RELEASE(key); map[i] = *pos; zval_dtor(&op_array->literals[i].constant); n = LITERAL_NUM_RELATED(info[i].flags); @@ -393,9 +391,7 @@ static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC) map[i] = j; if (info[i].flags & LITERAL_MAY_MERGE) { zend_hash_add_ptr(&hash, key, (void**)&j); - if (info[i].flags & (LITERAL_EX_OBJ|LITERAL_EX_CLASS)) { - STR_RELEASE(key); - } + STR_RELEASE(key); } if (i != j) { op_array->literals[j] = op_array->literals[i]; diff --git a/ext/opcache/Optimizer/optimize_temp_vars_5.c b/ext/opcache/Optimizer/optimize_temp_vars_5.c index 7c94379416..77e07a586e 100644 --- a/ext/opcache/Optimizer/optimize_temp_vars_5.c +++ b/ext/opcache/Optimizer/optimize_temp_vars_5.c @@ -104,6 +104,16 @@ static void optimize_temporary_variables(zend_op_array *op_array) if (ZEND_RESULT_TYPE(opline) & (IS_VAR | IS_TMP_VAR)) { start_of_T[VAR_NUM(ZEND_RESULT(opline).var) - offset] = opline; } + /* special puprose variable to keep HashPointer on VM stack */ + if (opline->opcode == ZEND_OP_DATA && + (opline-1)->opcode == ZEND_FE_FETCH && + opline->op1_type == IS_TMP_VAR) { + start_of_T[VAR_NUM(ZEND_OP1(opline).var) - offset] = opline; + if (sizeof(HashPointer) > sizeof(zval)) { + /* Make shure 1 zval is enough for HashPointer (2 must be enough) */ + start_of_T[VAR_NUM(ZEND_OP1(opline).var) + 1 - offset] = opline; + } + } #endif opline--; } @@ -120,13 +130,26 @@ static void optimize_temporary_variables(zend_op_array *op_array) || ((op_const_means_class[opline->opcode] & OP1_CONST_IS_CLASS) && ZEND_OP1_TYPE(opline) == IS_CONST) #endif ) { - currT = VAR_NUM(ZEND_OP1(opline).var) - offset; - if (!valid_T[currT]) { - GET_AVAILABLE_T(); - map_T[currT] = i; - valid_T[currT] = 1; + + /* special puprose variable to keep HashPointer on VM stack */ + if (opline->opcode == ZEND_OP_DATA && + (opline-1)->opcode == ZEND_FE_FETCH && + opline->op1_type == IS_TMP_VAR) { + max++; + ZEND_OP1(opline).var = NUM_VAR(max + offset); + if (sizeof(HashPointer) > sizeof(zval)) { + /* Make shure 1 zval is enough for HashPointer (2 must be enough) */ + max++; + } + } else { + currT = VAR_NUM(ZEND_OP1(opline).var) - offset; + if (!valid_T[currT]) { + GET_AVAILABLE_T(); + map_T[currT] = i; + valid_T[currT] = 1; + } + ZEND_OP1(opline).var = NUM_VAR(map_T[currT] + offset); } - ZEND_OP1(opline).var = NUM_VAR(map_T[currT] + offset); } /* Skip OP_DATA */ diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c index e828ae2357..221fd0f1f2 100644 --- a/ext/opcache/Optimizer/pass1_5.c +++ b/ext/opcache/Optimizer/pass1_5.c @@ -494,7 +494,6 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { #endif collect_constants = 0; break; - #if ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO case ZEND_FETCH_R: case ZEND_FETCH_W: @@ -559,7 +558,6 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { } break; #endif - } opline++; i++; diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 16a1a09c1f..1262cc222b 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -69,7 +69,7 @@ static int zend_optimizer_lookup_cv(zend_op_array *op_array, zend_string* name) (op_array->vars[i]->h == hash_value && op_array->vars[i]->len == name->len && memcmp(op_array->vars[i], name->val, name->len) == 0)) { - return i; + return (int)EX_VAR_NUM_2(NULL, i); } i++; } @@ -77,7 +77,30 @@ static int zend_optimizer_lookup_cv(zend_op_array *op_array, zend_string* name) op_array->last_var++; op_array->vars = erealloc(op_array->vars, op_array->last_var * sizeof(zend_string*)); op_array->vars[i] = STR_DUP(name, 0); - return i; + + /* all IS_TMP_VAR and IS_VAR variable numbers have to be adjusted */ + { + zend_op *opline = op_array->opcodes; + zend_op *end = opline + op_array->last; + while (opline < end) { + if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) { + opline->op1.var += sizeof(zval); + } + if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) { + opline->op2.var += sizeof(zval); + } + if (opline->result_type & (IS_TMP_VAR|IS_VAR)) { + opline->result.var += sizeof(zval); + } + if (opline->opcode == ZEND_DECLARE_INHERITED_CLASS || + opline->opcode == ZEND_DECLARE_INHERITED_CLASS_DELAYED) { + opline->extended_value += sizeof(zval); + } + opline++; + } + } + + return (int)EX_VAR_NUM_2(NULL, i); } #endif