]> granicus.if.org Git - php/commitdiff
Reorder conditions to save one instruction in recursive return loop
authorDmitry Stogov <dmitry@zend.com>
Mon, 25 May 2020 09:55:03 +0000 (12:55 +0300)
committerDmitry Stogov <dmitry@zend.com>
Mon, 25 May 2020 09:55:03 +0000 (12:55 +0300)
ext/opcache/jit/zend_jit.c
ext/opcache/jit/zend_jit_internal.h
ext/opcache/jit/zend_jit_trace.c
ext/opcache/jit/zend_jit_x86.dasc

index c96a1bc97305eb00e36d345cd1e81f709d1d4200..a3b3661d74537df6caae2b8bfa7289498acc28c2 100644 (file)
@@ -2673,7 +2673,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                                        }
                                                                }
                                                        }
-                                                   if (!zend_jit_leave_func(&dasm_state, opline, op_array, NULL)) {
+                                                   if (!zend_jit_leave_func(&dasm_state, opline, op_array, NULL, NULL)) {
                                                                goto jit_failure;
                                                    }
                                                }
index 93c05be006278087dca34c5a5e1ebe4ba20a602f..46c129212e34cf71048541a261fb2c9861b25c27 100644 (file)
@@ -331,6 +331,7 @@ typedef union _zend_jit_trace_stack {
 
 /* trace info flags */
 #define ZEND_JIT_TRACE_CHECK_INTERRUPT (1<<0)
+#define ZEND_JIT_TRACE_LOOP            (1<<1)
 
 typedef struct _zend_jit_trace_info {
        uint32_t                  id;            /* trace id */
index 22b01f4d2e14757e384dda376f0ad3e209fbf867..d438b09bc1f597fa891bb93a207c0d8057d68c46 100644 (file)
@@ -3334,7 +3334,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                                        }
                                                                }
                                                        }
-                                                       if (!zend_jit_leave_func(&dasm_state, opline, op_array, p + 1)) {
+                                                       if (!zend_jit_leave_func(&dasm_state, opline, op_array, p + 1, &zend_jit_traces[ZEND_JIT_TRACE_NUM])) {
                                                                goto jit_failure;
                                                        }
                                                }
@@ -4046,7 +4046,10 @@ done:
                if (p->stop != ZEND_JIT_TRACE_STOP_RECURSIVE_RET) {
                        t->flags |= ZEND_JIT_TRACE_CHECK_INTERRUPT;
                }
-               zend_jit_trace_end_loop(&dasm_state, 0, timeout_exit_addr); /* jump back to start of the trace loop */
+               if (!(t->flags & ZEND_JIT_TRACE_LOOP)) {
+                       t->flags |= ZEND_JIT_TRACE_LOOP;
+                       zend_jit_trace_end_loop(&dasm_state, 0, timeout_exit_addr); /* jump back to start of the trace loop */
+               }
        } else if (p->stop == ZEND_JIT_TRACE_STOP_LINK) {
                if (ra) {
                        /* Generate code for trace deoptimization */
index f18660ec5c25717db643bfc828e75959550da006..5b6741a20529446bcc9941c28e7ea9d9f5d43497 100644 (file)
@@ -9572,7 +9572,7 @@ static int zend_jit_free_cv(dasm_State **Dst, const zend_op *opline, const zend_
        return 1;
 }
 
-static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, zend_jit_trace_rec *trace)
+static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, zend_jit_trace_rec *trace, zend_jit_trace_info *trace_info)
 {
        /* ZEND_CALL_FAKE_CLOSURE handled on slow path to eliminate check for ZEND_CALL_CLOSURE on fast path */
        |       mov FCARG1d, dword [FP + offsetof(zend_execute_data, This.u1.type_info)]
@@ -9669,8 +9669,16 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const ze
                                return 0;
                        }
                        |       // TODO: exception handling ???
-                       |       CMP_IP next_opline
-                       |       jne &exit_addr
+                       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
+                       } else {
+                               |       CMP_IP next_opline
+                               |       jne &exit_addr
+                       }
 
                        last_valid_opline = trace->opline;