]> granicus.if.org Git - php/commitdiff
Keep information about SSA variables, that may be modified indirectly.
authorDmitry Stogov <dmitry@zend.com>
Wed, 5 Jul 2017 16:15:16 +0000 (19:15 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 5 Jul 2017 16:15:16 +0000 (19:15 +0300)
ext/opcache/Optimizer/zend_cfg.c
ext/opcache/Optimizer/zend_cfg.h
ext/opcache/Optimizer/zend_inference.c
ext/opcache/Optimizer/zend_ssa.c
ext/opcache/Optimizer/zend_ssa.h

index 7cc02b6560a93d781af51916bbc24fdc99d788c1..6ae5880c8ff26b062f3ee75bf7084c58225702f2 100644 (file)
@@ -598,6 +598,8 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
        /* Build CFG, Step 4, Mark Reachable Basic Blocks */
        zend_mark_reachable_blocks(op_array, cfg, 0);
 
+       cfg->dynamic = (flags & ZEND_FUNC_INDIRECT_VAR_ACCESS);
+
        if (func_flags) {
                *func_flags |= flags;
        }
index 315b93ef3a4d1479875182dec40e381921975996..ccff7d4425425ef81c8d7c7082bb74c72b069230 100644 (file)
@@ -92,6 +92,7 @@ typedef struct _zend_cfg {
        unsigned int      split_at_live_ranges : 1;
        unsigned int      split_at_calls : 1;
        unsigned int      split_at_recv : 1;
+       unsigned int      dynamic : 1;        /* accesses varables by name   */
 } zend_cfg;
 
 /* Build Flags */
index 7f1e79170582aa67a5387938f12396a6c98f7a93..5234bc8ef6e4f34c0e0352375202e650eb363ab3 100644 (file)
@@ -3835,21 +3835,14 @@ static int zend_infer_types(const zend_op_array *op_array, const zend_script *sc
        /* Narrowing integer initialization to doubles */
        zend_type_narrowing(op_array, script, ssa);
 
-       for (j = 0; j < op_array->last_var; j++) {
-               /* $php_errormsg and $http_response_header may be updated indirectly */
-               if (zend_string_equals_literal(op_array->vars[j], "php_errormsg")) {
-                       int i;
-                       for (i = 0; i < ssa_vars_count; i++) {
-                               if (ssa->vars[i].var == j) {
-                                       ssa_var_info[i].type |= MAY_BE_STRING | MAY_BE_RC1 | MAY_BE_RCN;
-                               }
-                       }
-               } else if (zend_string_equals_literal(op_array->vars[j], "http_response_header")) {
-                       int i;
-                       for (i = 0; i < ssa_vars_count; i++) {
-                               if (ssa->vars[i].var == j) {
-                                       ssa_var_info[i].type |= MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_STRING | MAY_BE_RC1 | MAY_BE_RCN;
-                               }
+       for (j = 0; j < ssa_vars_count; j++) {
+               if (ssa->vars[j].alias) {
+                       if (ssa->vars[j].alias == PHP_ERRORMSG_ALIAS) {
+                               ssa_var_info[j].type |= MAY_BE_STRING | MAY_BE_RC1 | MAY_BE_RCN;
+                       } else if (ssa->vars[j].alias == PHP_ERRORMSG_ALIAS) {
+                               ssa_var_info[j].type |= MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_STRING | MAY_BE_RC1 | MAY_BE_RCN;
+                       } else {
+                               ssa_var_info[j].type = MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
                        }
                }
        }
index 54bf985d40ca1d5e606af1e25b691e4816542a46..927ebb096cbe3eeeb64f9db1089de5ced27c881a 100644 (file)
@@ -1100,6 +1100,22 @@ int zend_ssa_compute_use_def_chains(zend_arena **arena, const zend_op_array *op_
                }
        }
 
+       /* Mark indirectly accessed variables */
+       for (i = 0; i < op_array->last_var; i++) {
+               if (ssa->cfg.dynamic) {
+                       ssa_vars[i].alias = SYMTABLE_ALIAS;
+               } else if (zend_string_equals_literal(op_array->vars[i], "php_errormsg")) {
+                       ssa_vars[i].alias = PHP_ERRORMSG_ALIAS;
+               } else if (zend_string_equals_literal(op_array->vars[i], "http_response_header")) {
+                       ssa_vars[i].alias = HTTP_RESPONSE_HEADER_ALIAS;
+               }
+       }
+       for (i = op_array->last_var; i < ssa->vars_count; i++) {
+               if (ssa_vars[i].var < op_array->last_var) {
+                       ssa_vars[i].alias = ssa_vars[ssa_vars[i].var].alias;
+               }
+       }
+
        return SUCCESS;
 }
 /* }}} */
index 1130d9d62a6bddd55cda78a69edbb9bf03843c4a..b8e5d8c3e87e70b3a9b6860db85dfc9e9c249418 100644 (file)
@@ -92,6 +92,13 @@ typedef struct _zend_ssa_op {
        int                    res_use_chain;
 } zend_ssa_op;
 
+typedef enum _zend_ssa_alias_kind {
+       NO_ALIAS,
+       SYMTABLE_ALIAS,
+       PHP_ERRORMSG_ALIAS,
+       HTTP_RESPONSE_HEADER_ALIAS
+} zend_ssa_alias_kind;
+
 typedef struct _zend_ssa_var {
        int                    var;            /* original var number; op.var for CVs and following numbers for VARs and TMP_VARs */
        int                    scc;            /* strongly connected component */
@@ -102,6 +109,7 @@ typedef struct _zend_ssa_var {
        zend_ssa_phi          *sym_use_chain;  /* uses of this value in Pi constaints */
        unsigned int           no_val : 1;     /* value doesn't mater (used as op1 in ZEND_ASSIGN) */
        unsigned int           scc_entry : 1;
+       zend_ssa_alias_kind    alias : 2;  /* value may be changed indirectly */
 } zend_ssa_var;
 
 typedef struct _zend_ssa_var_info {