]> granicus.if.org Git - php/commitdiff
Move AVOID_REFCOUNTING type info flag into a separate bit
authorDmitry Stogov <dmitry@zend.com>
Tue, 25 Aug 2020 08:37:30 +0000 (11:37 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 25 Aug 2020 08:37:30 +0000 (11:37 +0300)
ext/opcache/Optimizer/zend_inference.h
ext/opcache/Optimizer/zend_ssa.h
ext/opcache/jit/zend_jit.c
ext/opcache/jit/zend_jit_trace.c
ext/opcache/jit/zend_jit_x86.dasc

index 3d8a0a0dcf169bc721baff54f423c56b8d9eafce..0708d5df94516e39c83c2df7653778e56f56ee79 100644 (file)
@@ -26,7 +26,6 @@
 /* Bitmask for type inference (zend_ssa_var_info.type) */
 #include "zend_type_info.h"
 
-#define AVOID_REFCOUNTING           (1<<26) /* avoid reference counting */
 #define MAY_BE_CLASS_GUARD          (1<<27) /* needs class guard */
 #define MAY_BE_GUARD                (1<<28) /* needs type guard */
 #define MAY_BE_IN_REG               (1<<29) /* value allocated in CPU register */
index 7d065ac42ab4257055036c11e642d5e02c603f59..e7190da3f8ddbce559e42a1a0707aaedce9b1640 100644 (file)
@@ -128,6 +128,7 @@ typedef struct _zend_ssa_var_info {
        unsigned int           recursive : 1;
        unsigned int           use_as_double : 1;
        unsigned int           delayed_fetch_this : 1;
+       unsigned int           avoid_refcounting : 1;
 } zend_ssa_var_info;
 
 typedef struct _zend_ssa {
index 2956591490d3cb9c7567ebe26cb993da6cff71dc..5073894dbe17b64e4b78de3fc4325ec73c506953 100644 (file)
@@ -2817,7 +2817,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                        break;
                                                }
                                                if (!zend_jit_fetch_dim_read(&dasm_state, opline, ssa, ssa_op,
-                                                               OP1_INFO(), OP1_REG_ADDR(), OP2_INFO(), RES_INFO(), RES_REG_ADDR(),
+                                                               OP1_INFO(), OP1_REG_ADDR(), 0,
+                                                               OP2_INFO(), RES_INFO(), RES_REG_ADDR(),
                                                                zend_may_throw(opline, ssa_op, op_array, ssa))) {
                                                        goto jit_failure;
                                                }
@@ -2846,7 +2847,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                        target_label = target_label2 = (uint32_t)-1;
                                                }
                                                if (!zend_jit_isset_isempty_dim(&dasm_state, opline,
-                                                               OP1_INFO(), OP1_REG_ADDR(), OP2_INFO(),
+                                                               OP1_INFO(), OP1_REG_ADDR(), 0,
+                                                               OP2_INFO(),
                                                                zend_may_throw(opline, ssa_op, op_array, ssa),
                                                                smart_branch_opcode, target_label, target_label2,
                                                                NULL)) {
@@ -2886,7 +2888,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                        }
                                                }
                                                if (!zend_jit_fetch_obj(&dasm_state, opline, op_array, ssa, ssa_op,
-                                                               op1_info, op1_addr, 0, ce, ce_is_instanceof, 0, NULL,
+                                                               op1_info, op1_addr, 0, ce, ce_is_instanceof, 0, 0, NULL,
                                                                zend_may_throw(opline, ssa_op, op_array, ssa))) {
                                                        goto jit_failure;
                                                }
index 6ad080003693acf8aef86bd41954127d0bef451a..9e40661b0c61777a5164eb9af95c59adc44e091b 100644 (file)
@@ -2895,6 +2895,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
        zend_class_entry *ce;
        zend_bool ce_is_instanceof;
        zend_bool delayed_fetch_this = 0;
+       zend_bool avoid_refcounting = 0;
        uint32_t i;
        zend_jit_trace_stack_frame *frame, *top, *call;
        zend_jit_trace_stack *stack;
@@ -4011,7 +4012,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                CHECK_OP2_TRACE_TYPE();
                                                res_info = RES_INFO();
                                                if (!zend_jit_fetch_dim_read(&dasm_state, opline, ssa, ssa_op,
-                                                               op1_info, op1_addr, op2_info, res_info, RES_REG_ADDR(),
+                                                               op1_info, op1_addr, ssa->var_info[ssa_op->op1_use].avoid_refcounting,
+                                                               op2_info, res_info, RES_REG_ADDR(),
                                                                (
                                                                        (op1_info & MAY_BE_ANY) != MAY_BE_ARRAY ||
                                                                        (op2_info & (MAY_BE_ANY - (MAY_BE_LONG|MAY_BE_STRING))) != 0 ||
@@ -4052,7 +4054,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                        if (ra) {
                                                                zend_jit_trace_clenup_stack(stack, opline, ssa_op, ssa, ra);
                                                        }
-                                                       if (op1_info & AVOID_REFCOUNTING) {
+                                                       if (ssa->var_info[ssa_op->op1_use].avoid_refcounting) {
                                                                /* Temporary reset ZREG_ZVAL_TRY_ADDREF */
                                                                zend_jit_trace_stack *stack = JIT_G(current_frame)->stack;
                                                                uint32_t old_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->op1.var));
@@ -4073,7 +4075,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                        exit_addr = NULL;
                                                }
                                                if (!zend_jit_isset_isempty_dim(&dasm_state, opline,
-                                                               op1_info, op1_addr, op2_info,
+                                                               op1_info, op1_addr, ssa->var_info[ssa_op->op1_use].avoid_refcounting,
+                                                               op2_info,
                                                                zend_may_throw_ex(opline, ssa_op, op_array, ssa, op1_info, op2_info),
                                                                smart_branch_opcode, -1, -1,
                                                                exit_addr)) {
@@ -4092,6 +4095,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                        case ZEND_FETCH_OBJ_IS:
                                        case ZEND_FETCH_OBJ_W:
                                                delayed_fetch_this = 0;
+                                               avoid_refcounting = 0;
                                                if (opline->op2_type != IS_CONST
                                                 || Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING
                                                 || Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') {
@@ -4140,11 +4144,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                        }
                                                        if (ssa_op->op1_use >= 0) {
                                                                delayed_fetch_this = ssa->var_info[ssa_op->op1_use].delayed_fetch_this;
+                                                               avoid_refcounting = ssa->var_info[ssa_op->op1_use].avoid_refcounting;
                                                        }
                                                }
                                                if (!zend_jit_fetch_obj(&dasm_state, opline, op_array, ssa, ssa_op,
                                                                op1_info, op1_addr, op1_indirect, ce, ce_is_instanceof,
-                                                               delayed_fetch_this, op1_ce,
+                                                               delayed_fetch_this, avoid_refcounting, op1_ce,
                                                                zend_may_throw_ex(opline, ssa_op, op_array, ssa, op1_info, MAY_BE_STRING))) {
                                                        goto jit_failure;
                                                }
@@ -4353,7 +4358,7 @@ done:
                                                if (opline->opcode == ZEND_FETCH_THIS
                                                 && delayed_fetch_this) {
                                                        SET_STACK_REG(stack, EX_VAR_TO_NUM(opline->result.var), ZREG_THIS);
-                                               } else if (ssa->var_info[ssa_op->result_def].type & AVOID_REFCOUNTING) {
+                                               } else if (ssa->var_info[ssa_op->result_def].avoid_refcounting) {
                                                        SET_STACK_REG(stack, EX_VAR_TO_NUM(opline->result.var), ZREG_ZVAL_TRY_ADDREF);
                                                } else if (ra && ra[ssa_op->result_def]) {
                                                        SET_STACK_REG(stack, EX_VAR_TO_NUM(opline->result.var), ra[ssa_op->result_def]->reg);
index 49459267e7e243d42e894692af382169569ac567..84c7c091285bf24c58b21661830a43a312c2b63d 100644 (file)
@@ -10479,12 +10479,23 @@ static zend_bool zend_jit_may_avoid_refcounting(const zend_op *opline)
        return 0;
 }
 
-static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, zend_ssa *ssa, const zend_ssa_op *ssa_op, uint32_t op1_info, zend_jit_addr op1_addr, uint32_t op2_info, uint32_t res_info, zend_jit_addr res_addr, int may_throw)
+static int zend_jit_fetch_dim_read(dasm_State        **Dst,
+                                   const zend_op      *opline,
+                                   zend_ssa           *ssa,
+                                   const zend_ssa_op  *ssa_op,
+                                   uint32_t            op1_info,
+                                   zend_jit_addr       op1_addr,
+                                   zend_bool           op1_avoid_refcounting,
+                                   uint32_t            op2_info,
+                                   uint32_t            res_info,
+                                   zend_jit_addr       res_addr,
+                                   int                 may_throw)
 {
        zend_jit_addr orig_op1_addr, op2_addr;
        const void *exit_addr = NULL;
        const void *not_found_exit_addr = NULL;
        const void *res_exit_addr = NULL;
+       zend_bool result_avoid_refcounting = 0;
 
        orig_op1_addr = OP1_ADDR();
        op2_addr = OP2_ADDR();
@@ -10498,7 +10509,7 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, zend
                }
        }
 
-       if (op1_info & AVOID_REFCOUNTING) {
+       if (op1_avoid_refcounting) {
                SET_STACK_REG(JIT_G(current_frame)->stack,
                        EX_VAR_TO_NUM(opline->op1.var), ZREG_NONE);
        }
@@ -10512,7 +10523,7 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, zend
                int32_t exit_point;
 
                if ((opline->op1_type & (IS_VAR|IS_TMP_VAR))
-                && !(op1_info & AVOID_REFCOUNTING)) {
+                && !op1_avoid_refcounting) {
                        flags |= ZEND_JIT_EXIT_FREE_OP1;
                }
                if ((opline->op2_type & (IS_VAR|IS_TMP_VAR))
@@ -10524,8 +10535,8 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, zend
                 && (ssa_op+1)->op1_use == ssa_op->result_def
                 && !(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF) - (MAY_BE_STRING|MAY_BE_LONG)))
                 && zend_jit_may_avoid_refcounting(opline+1)) {
-                       res_info |= AVOID_REFCOUNTING;
-                       ssa->var_info[ssa_op->result_def].type |= AVOID_REFCOUNTING;
+                       result_avoid_refcounting = 1;
+                       ssa->var_info[ssa_op->result_def].avoid_refcounting = 1;
                }
 
                if (!(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF) - (MAY_BE_STRING|MAY_BE_LONG)))) {
@@ -10722,7 +10733,7 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, zend
                                        |       SET_ZVAL_TYPE_INFO res_addr, type
                                } else {
                                        |       SET_ZVAL_TYPE_INFO res_addr, edx
-                                       if (!(res_info & AVOID_REFCOUNTING)) {
+                                       if (!result_avoid_refcounting) {
                                                |       TRY_ADDREF res_info, dh, r1
                                        }
                                }
@@ -10751,7 +10762,7 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, zend
 #endif
 
        |       FREE_OP opline->op2_type, opline->op2, op2_info, 0, opline
-       if (!(op1_info & AVOID_REFCOUNTING)) {
+       if (!op1_avoid_refcounting) {
                |       FREE_OP opline->op1_type, opline->op1, op1_info, 0, opline
        }
 
@@ -10764,7 +10775,17 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, zend
        return 1;
 }
 
-static int zend_jit_isset_isempty_dim(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, zend_jit_addr op1_addr, uint32_t op2_info, int may_throw, zend_uchar smart_branch_opcode, uint32_t target_label, uint32_t target_label2, const void *exit_addr)
+static int zend_jit_isset_isempty_dim(dasm_State    **Dst,
+                                      const zend_op  *opline,
+                                      uint32_t        op1_info,
+                                      zend_jit_addr   op1_addr,
+                                      zend_bool       op1_avoid_refcounting,
+                                      uint32_t        op2_info,
+                                      int             may_throw,
+                                      zend_uchar      smart_branch_opcode,
+                                      uint32_t        target_label,
+                                      uint32_t        target_label2,
+                                      const void     *exit_addr)
 {
        zend_jit_addr op2_addr, res_addr;
 
@@ -10791,7 +10812,7 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst, const zend_op *opline, u
                if (exit_addr
                 && !(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_ARRAY))
                 && !may_throw
-                && (!(opline->op1_type & (IS_TMP_VAR|IS_VAR)) || (op1_info & AVOID_REFCOUNTING))
+                && (!(opline->op1_type & (IS_TMP_VAR|IS_VAR)) || op1_avoid_refcounting)
                 && (!(opline->op2_type & (IS_TMP_VAR|IS_VAR)) || !(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_LONG)))) {
                        if (smart_branch_opcode == ZEND_JMPNZ) {
                                found_exit_addr = exit_addr;
@@ -10859,7 +10880,7 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst, const zend_op *opline, u
 
        |8:
        |       FREE_OP opline->op2_type, opline->op2, op2_info, 0, opline
-       if (!(op1_info & AVOID_REFCOUNTING)) {
+       if (!op1_avoid_refcounting) {
                |       FREE_OP opline->op1_type, opline->op1, op1_info, 0, opline
        }
        if (may_throw) {
@@ -10895,7 +10916,7 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst, const zend_op *opline, u
 
        |9: // not found
        |       FREE_OP opline->op2_type, opline->op2, op2_info, 0, opline
-       if (!(op1_info & AVOID_REFCOUNTING)) {
+       if (!op1_avoid_refcounting) {
                |       FREE_OP opline->op1_type, opline->op1, op1_info, 0, opline
        }
        if (may_throw) {
@@ -11320,7 +11341,20 @@ static int zend_jit_class_guard(dasm_State **Dst, const zend_op *opline, zend_cl
        return 1;
 }
 
-static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, zend_ssa *ssa, const zend_ssa_op *ssa_op, uint32_t op1_info, zend_jit_addr op1_addr, zend_bool op1_indirect, zend_class_entry *ce, zend_bool ce_is_instanceof, zend_bool use_this, zend_class_entry *trace_ce, int may_throw)
+static int zend_jit_fetch_obj(dasm_State          **Dst,
+                              const zend_op        *opline,
+                              const zend_op_array  *op_array,
+                              zend_ssa             *ssa,
+                              const zend_ssa_op    *ssa_op,
+                              uint32_t              op1_info,
+                              zend_jit_addr         op1_addr,
+                              zend_bool             op1_indirect,
+                              zend_class_entry     *ce,
+                              zend_bool             ce_is_instanceof,
+                              zend_bool             use_this,
+                              zend_bool             op1_avoid_refcounting,
+                              zend_class_entry     *trace_ce,
+                              int                   may_throw)
 {
        zval *member;
        zend_property_info *prop_info;
@@ -11494,7 +11528,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zen
                        }
                }
        }
-       if (op1_info & AVOID_REFCOUNTING) {
+       if (op1_avoid_refcounting) {
                SET_STACK_REG(JIT_G(current_frame)->stack,
                        EX_VAR_TO_NUM(opline->op1.var), ZREG_NONE);
        }
@@ -11506,6 +11540,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zen
                |       SET_ZVAL_TYPE_INFO res_addr, IS_INDIRECT
        } else {
                uint32_t res_info = RES_INFO();
+               zend_bool result_avoid_refcounting = 0;
 
                if ((res_info & MAY_BE_GUARD) && JIT_G(current_frame) && prop_info) {
                        uint32_t flags = 0;
@@ -11518,7 +11553,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zen
 
                        if ((opline->op1_type & (IS_VAR|IS_TMP_VAR))
                         && !use_this
-                        && !(op1_info & AVOID_REFCOUNTING)) {
+                        && !op1_avoid_refcounting) {
                                flags = ZEND_JIT_EXIT_FREE_OP1;
                        }
 
@@ -11528,8 +11563,8 @@ static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zen
                         && (res_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))
                         && (ssa_op+1)->op1_use == ssa_op->result_def
                         && zend_jit_may_avoid_refcounting(opline+1)) {
-                               res_info |= AVOID_REFCOUNTING;
-                               ssa->var_info[ssa_op->result_def].type |= AVOID_REFCOUNTING;
+                               result_avoid_refcounting = 1;
+                               ssa->var_info[ssa_op->result_def].avoid_refcounting = 1;
                        }
 
                        old_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->result.var));
@@ -11564,7 +11599,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zen
                                |       SET_ZVAL_TYPE_INFO res_addr, type
                        } else {
                                |       SET_ZVAL_TYPE_INFO res_addr, edx
-                               if (!(res_info & AVOID_REFCOUNTING)) {
+                               if (!result_avoid_refcounting) {
                                        |       TRY_ADDREF res_info, dh, r1
                                }
                        }
@@ -11652,7 +11687,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zen
                        |       SAVE_VALID_OPLINE opline, r0
                        |       EXT_CALL zend_jit_extract_helper, r0
                        |1:
-               } else if (!(op1_info & AVOID_REFCOUNTING)) {
+               } else if (!op1_avoid_refcounting) {
                        |       FREE_OP opline->op1_type, opline->op1, op1_info, 1, opline
                }
        }