]> granicus.if.org Git - php/commitdiff
MAY_BE_INDIRECT inference
authorDmitry Stogov <dmitry@zend.com>
Thu, 18 Jun 2020 15:54:32 +0000 (18:54 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 18 Jun 2020 15:54:32 +0000 (18:54 +0300)
Zend/zend_type_info.h
ext/opcache/Optimizer/zend_inference.c
ext/opcache/Optimizer/zend_inference.h
ext/opcache/jit/zend_jit_x86.dasc

index bace8014bfc3fec2b89a299f5954e9061da6d424..9dc90d142b4ed80ee1833e6124f6b74197a4a708 100644 (file)
@@ -61,5 +61,6 @@
 #define MAY_BE_ARRAY_KEY_ANY        (MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_KEY_STRING)
 
 #define MAY_BE_CLASS                (1<<23)
+#define MAY_BE_INDIRECT             (1<<24)
 
 #endif /* ZEND_TYPE_INFO_H */
index 0c0a2921c967d38d6171faa3ae936f9382e6bf09..5a29165aec0fb3450ff0a7dd6416bfa1ce9d43be 100644 (file)
@@ -1983,6 +1983,9 @@ uint32_t zend_array_element_type(uint32_t t1, int write, int insert)
                                tmp |= MAY_BE_RC1 | MAY_BE_RCN;
                        }
                }
+               if (write) {
+                       tmp |= MAY_BE_INDIRECT;
+               }
        }
        if (t1 & MAY_BE_STRING) {
                tmp |= MAY_BE_STRING | MAY_BE_RC1;
@@ -3398,7 +3401,7 @@ static zend_always_inline int _zend_update_type_info(
                                tmp = zend_fetch_prop_type(script,
                                        zend_fetch_prop_info(op_array, ssa, opline, ssa_op), &ce);
                                if (opline->result_type != IS_TMP_VAR) {
-                                       tmp |= MAY_BE_REF;
+                                       tmp |= MAY_BE_REF | MAY_BE_INDIRECT;
                                }
                                UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
                                if (ce) {
@@ -3415,7 +3418,7 @@ static zend_always_inline int _zend_update_type_info(
                        tmp = zend_fetch_prop_type(script,
                                zend_fetch_static_prop_info(script, op_array, ssa, opline), &ce);
                        if (opline->result_type != IS_TMP_VAR) {
-                               tmp |= MAY_BE_REF;
+                               tmp |= MAY_BE_REF | MAY_BE_INDIRECT;
                        }
                        UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
                        if (ce) {
@@ -3524,6 +3527,26 @@ unknown_opcode:
                                        tmp |= MAY_BE_RC1 | MAY_BE_RCN;
                                } else {
                                        tmp |= MAY_BE_REF | MAY_BE_RC1 | MAY_BE_RCN;
+                                       switch (opline->opcode) {
+                                               case ZEND_FETCH_W:
+                                               case ZEND_FETCH_RW:
+                                               case ZEND_FETCH_FUNC_ARG:
+                                               case ZEND_FETCH_UNSET:
+                                               case ZEND_FETCH_DIM_W:
+                                               case ZEND_FETCH_DIM_RW:
+                                               case ZEND_FETCH_DIM_FUNC_ARG:
+                                               case ZEND_FETCH_DIM_UNSET:
+                                               case ZEND_FETCH_OBJ_W:
+                                               case ZEND_FETCH_OBJ_RW:
+                                               case ZEND_FETCH_OBJ_FUNC_ARG:
+                                               case ZEND_FETCH_OBJ_UNSET:
+                                               case ZEND_FETCH_STATIC_PROP_W:
+                                               case ZEND_FETCH_STATIC_PROP_RW:
+                                               case ZEND_FETCH_STATIC_PROP_FUNC_ARG:
+                                               case ZEND_FETCH_STATIC_PROP_UNSET:
+                                                       tmp |= MAY_BE_INDIRECT;
+                                                       break;
+                                       }
                                }
                                UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
                        }
index da103e4bb5280faf8aec83e47be746aaea5d3eaf..525159a72b4e0ae2a6464b5c673f8bd2cb275ef4 100644 (file)
@@ -195,7 +195,7 @@ static zend_always_inline uint32_t get_ssa_var_info(const zend_ssa *ssa, int ssa
        if (ssa->var_info && ssa_var_num >= 0) {
                return ssa->var_info[ssa_var_num].type;
        } else {
-               return 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;
+               return MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_INDIRECT | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
        }
 }
 
index 576bb7badbc038b36ebc54dbb7e541837d76b20f..b4306f5bdba9717ee72f7beabab7c10f68942825 100644 (file)
@@ -1323,7 +1323,7 @@ static void* dasm_labels[zend_lb_MAX];
 // zval should be in FCARG1a
 |.macro ZVAL_DTOR_FUNC, var_info, opline // arg1 must be in FCARG1a
 ||     do {
-||             if (has_concrete_type((var_info) & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
+||             if (has_concrete_type((var_info) & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_INDIRECT))) {
 ||                     zend_uchar type = concrete_type((var_info) & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE));
 ||                     if (type == IS_STRING && !ZEND_DEBUG) {
 |                              EXT_CALL _efree, r0
@@ -1355,7 +1355,7 @@ static void* dasm_labels[zend_lb_MAX];
 
 |.macro ZVAL_PTR_DTOR, addr, op_info, gc, cold, opline
 ||     if ((op_info) & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) {
-||             if ((op_info) & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
+||             if ((op_info) & ((MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_INDIRECT)-(MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
 |                      // if (Z_REFCOUNTED_P(cv)) {
 ||                     if (cold) {
 |                              IF_ZVAL_REFCOUNTED addr, >1
@@ -8916,12 +8916,15 @@ static int zend_jit_send_ref(dasm_State **Dst, const zend_op *opline, const zend
        }
 
        if (opline->op1_type == IS_VAR) {
-               |       LOAD_ZVAL_ADDR r0, op1_addr
-               |       // if (EXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
-               |       IF_NOT_Z_TYPE r0, IS_INDIRECT, >1
-               |       // ret = Z_INDIRECT_P(ret);
-               |       GET_Z_PTR r0, r0
-               |1:
+               if (op1_info & MAY_BE_INDIRECT) {
+                       |       LOAD_ZVAL_ADDR r0, op1_addr
+                       |       // if (EXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
+                       |       IF_NOT_Z_TYPE r0, IS_INDIRECT, >1
+                       |       // ret = Z_INDIRECT_P(ret);
+                       |       GET_Z_PTR r0, r0
+                       |1:
+                       op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0);
+               }
        } else if (opline->op1_type == IS_CV) {
                if (op1_info & MAY_BE_UNDEF) {
                        if (op1_info & (MAY_BE_ANY|MAY_BE_REF)) {
@@ -8939,13 +8942,8 @@ static int zend_jit_send_ref(dasm_State **Dst, const zend_op *opline, const zend
 
        if (op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) {
                if (op1_info & MAY_BE_REF) {
-                       if (opline->op1_type == IS_VAR) {
-                               |       IF_NOT_Z_TYPE r0, IS_REFERENCE, >2
-                               |       GET_Z_PTR r1, r0
-                       } else {
-                               |       IF_NOT_ZVAL_TYPE op1_addr, IS_REFERENCE, >2
-                               |       GET_ZVAL_PTR r1, op1_addr
-                       }
+                       |       IF_NOT_ZVAL_TYPE op1_addr, IS_REFERENCE, >2
+                       |       GET_ZVAL_PTR r1, op1_addr
                        |       GC_ADDREF r1
                        |       SET_ZVAL_PTR arg_addr, r1
                        |       SET_ZVAL_TYPE_INFO arg_addr, IS_REFERENCE_EX