From b35a9a4ce6ad871333bca2990d68c492d5870f48 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 25 May 2020 12:55:03 +0300 Subject: [PATCH] Reorder conditions to save one instruction in recursive return loop --- ext/opcache/jit/zend_jit.c | 2 +- ext/opcache/jit/zend_jit_internal.h | 1 + ext/opcache/jit/zend_jit_trace.c | 7 +++++-- ext/opcache/jit/zend_jit_x86.dasc | 14 +++++++++++--- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index c96a1bc973..a3b3661d74 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -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; } } diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h index 93c05be006..46c129212e 100644 --- a/ext/opcache/jit/zend_jit_internal.h +++ b/ext/opcache/jit/zend_jit_internal.h @@ -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 */ diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 22b01f4d2e..d438b09bc1 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -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 */ diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index f18660ec5c..5b6741a205 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -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; -- 2.40.0