]> granicus.if.org Git - php/commitdiff
If we don't know the return address, just escape to VM, instead of adding side exit.
authorDmitry Stogov <dmitry@zend.com>
Thu, 3 Sep 2020 14:12:23 +0000 (17:12 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 3 Sep 2020 14:12:23 +0000 (17:12 +0300)
Remove unnecessary exception checks.

ext/opcache/jit/zend_jit.c
ext/opcache/jit/zend_jit_trace.c
ext/opcache/jit/zend_jit_x86.dasc

index 7900130bb6e803461e0e03252150c162f8f89577..92c499e349ef0b29f707e9f7bcf1e8aee2d44ec0 100644 (file)
@@ -2740,7 +2740,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                                        }
                                                                }
                                                        }
-                                                       if (!zend_jit_leave_func(&dasm_state, op_array, NULL, NULL,
+                                                       if (!zend_jit_leave_func(&dasm_state, op_array, opline, op1_info, NULL, NULL,
                                                                        (ssa->cfg.flags & ZEND_FUNC_INDIRECT_VAR_ACCESS) != 0, 1)) {
                                                                goto jit_failure;
                                                        }
index 5834cbe0e55a6709191fd5bb4043491245487849..408e540e0fe88833e6816ef7c83dd5cd7eececc3 100644 (file)
@@ -4076,7 +4076,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                                        }
                                                                }
                                                        }
-                                                       if (!zend_jit_leave_func(&dasm_state, op_array, p + 1, &zend_jit_traces[ZEND_JIT_TRACE_NUM],
+                                                       if (!zend_jit_leave_func(&dasm_state, op_array, opline, op1_info,
+                                                                       p + 1, &zend_jit_traces[ZEND_JIT_TRACE_NUM],
                                                                        (op_array_ssa->cfg.flags & ZEND_FUNC_INDIRECT_VAR_ACCESS) != 0, may_throw)) {
                                                                goto jit_failure;
                                                        }
index 74449877ac5fb86921e3117c87c7210cc49a27a8..58149c902932a255658d3e41a471e1c3019acd3a 100644 (file)
@@ -10194,7 +10194,7 @@ static int zend_jit_free_op(dasm_State **Dst, const zend_op *opline, uint32_t in
        return 1;
 }
 
-static int zend_jit_leave_func(dasm_State **Dst, const zend_op_array *op_array, zend_jit_trace_rec *trace, zend_jit_trace_info *trace_info, int indirect_var_access, int may_throw)
+static int zend_jit_leave_func(dasm_State **Dst, const zend_op_array *op_array, const zend_op *opline, uint32_t op1_info, zend_jit_trace_rec *trace, zend_jit_trace_info *trace_info, int indirect_var_access, int may_throw)
 {
        zend_bool may_be_top_frame =
                JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE ||
@@ -10293,50 +10293,49 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op_array *op_array,
 
                |8:
 
-               if ((trace->op != ZEND_JIT_TRACE_END ||
-                               trace->stop != ZEND_JIT_TRACE_STOP_RECURSIVE_RET) &&
-                                       may_throw) {
-                       |       // if (EG(exception))
-                       |       MEM_OP2_1_ZTS cmp, aword, executor_globals, exception, 0, r0
-                       |       jne ->leave_throw_handler
-               }
-
                if (trace->op == ZEND_JIT_TRACE_BACK
                 && (!JIT_G(current_frame) || TRACE_FRAME_IS_UNKNOWN_RETURN(JIT_G(current_frame)))) {
                        const zend_op *next_opline = trace->opline;
-                       uint32_t exit_point;
-                       const void *exit_addr;
-                       zend_jit_trace_stack_frame *current_frame;
 
+                       if ((opline->op1_type & (IS_VAR|IS_TMP_VAR))
+                        && (op1_info & MAY_BE_RC1)
+                        && (op1_info & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_RESOURCE|MAY_BE_ARRAY_OF_ARRAY))) {
+                               /* exception might be thrown during destruction of unused return value */
+                               |       // if (EG(exception))
+                               |       MEM_OP2_1_ZTS cmp, aword, executor_globals, exception, 0, r0
+                               |       jne ->leave_throw_handler
+                       }
                        do {
                                trace++;
                        } while (trace->op == ZEND_JIT_TRACE_INIT_CALL);
                        ZEND_ASSERT(trace->op == ZEND_JIT_TRACE_VM || trace->op == ZEND_JIT_TRACE_END);
                        next_opline = trace->opline;
                        ZEND_ASSERT(next_opline != NULL);
-                       current_frame = JIT_G(current_frame);
-                       JIT_G(current_frame) = NULL;
-                       exit_point = zend_jit_trace_get_exit_point(NULL, 0);
-                       JIT_G(current_frame) = current_frame;
-                       exit_addr = zend_jit_trace_get_exit_addr(exit_point);
-                       if (!exit_addr) {
-                               return 0;
-                       }
+
                        if (trace->op == ZEND_JIT_TRACE_END
                         && trace->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_RET) {
                                trace_info->flags |= ZEND_JIT_TRACE_LOOP;
                                |       CMP_IP next_opline
                                |       je =>0 // LOOP
-                               |       jmp &exit_addr
+                               |       jmp ->trace_escape
                        } else {
                                |       CMP_IP next_opline
-                               |       jne &exit_addr
+                               |       jne ->trace_escape
                        }
 
                        last_valid_opline = trace->opline;
 
                        return 1;
+               } else if (may_throw ||
+                               (((opline->op1_type & (IS_VAR|IS_TMP_VAR))
+                                 && (op1_info & MAY_BE_RC1)
+                                 && (op1_info & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_RESOURCE|MAY_BE_ARRAY_OF_ARRAY)))
+                                && (!JIT_G(current_frame) || TRACE_FRAME_IS_RETURN_VALUE_UNUSED(JIT_G(current_frame))))) {
+                       |       // if (EG(exception))
+                       |       MEM_OP2_1_ZTS cmp, aword, executor_globals, exception, 0, r0
+                       |       jne ->leave_throw_handler
                }
+
                return 1;
        } else {
                |       // if (EG(exception))