summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2020-05-25 12:55:03 +0300
committerDmitry Stogov <dmitry@zend.com>2020-05-25 12:55:03 +0300
commitb35a9a4ce6ad871333bca2990d68c492d5870f48 (patch)
tree3c07239d8c1aade4df1106138f56a2f2e8520c10
parentce668c0ec6393456be4ce77eabaa4692285d95e5 (diff)
downloadphp-git-b35a9a4ce6ad871333bca2990d68c492d5870f48.tar.gz
Reorder conditions to save one instruction in recursive return loop
-rw-r--r--ext/opcache/jit/zend_jit.c2
-rw-r--r--ext/opcache/jit/zend_jit_internal.h1
-rw-r--r--ext/opcache/jit/zend_jit_trace.c7
-rw-r--r--ext/opcache/jit/zend_jit_x86.dasc14
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;