]> granicus.if.org Git - php/commitdiff
Optimizer related fixes (incomplete)
authorDmitry Stogov <dmitry@zend.com>
Mon, 31 Mar 2014 14:13:16 +0000 (18:13 +0400)
committerDmitry Stogov <dmitry@zend.com>
Mon, 31 Mar 2014 14:13:16 +0000 (18:13 +0400)
ext/opcache/Optimizer/block_pass.c
ext/opcache/Optimizer/compact_literals.c
ext/opcache/Optimizer/optimize_temp_vars_5.c
ext/opcache/Optimizer/pass1_5.c
ext/opcache/Optimizer/zend_optimizer.c

index 26d4f99d23b62aad51db4ebb55ef6e8fa59c1f24..3faa6ed689cc63eb952a0cad2123074989045dab 100644 (file)
@@ -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;
                                }
index 4fa3c7d33daeb23fe93967c630d455c23ef1b193..76df128ef6d92555f7183bbe18b8a252a71e11ad 100644 (file)
@@ -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];
index 7c94379416baa6fea54aaa5ac953ef3859332165..77e07a586e96ef5d3b3528abfb92dbdd3218f8fc 100644 (file)
@@ -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 */
index e828ae235792cfec5aeffd70c5f55a72aafe8d95..221fd0f1f293a303b4f7e62de422dc8f991762c6 100644 (file)
@@ -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++;
index 16a1a09c1f2fb36ae533ed693a5315b7ddeb1326..1262cc222bbe954f64c5262111fbbead7ea3b815 100644 (file)
@@ -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