summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2020-05-27 18:04:16 +0300
committerDmitry Stogov <dmitry@zend.com>2020-05-27 18:04:16 +0300
commitd2d5738b320ae065334f39874ed5756494537bb7 (patch)
tree7f5b1123cc44a7ca609824cbc5b9a305cd31003e
parent0bf2bfcf8d029e7948b755d2d8ec9682fdbddd9f (diff)
downloadphp-git-d2d5738b320ae065334f39874ed5756494537bb7.tar.gz
Fixed tracing JIT support for ZEND_RETURN_BY_REF in CALL VM
-rw-r--r--ext/opcache/jit/zend_jit.c2
-rw-r--r--ext/opcache/jit/zend_jit_trace.c2
-rw-r--r--ext/opcache/jit/zend_jit_x86.dasc34
3 files changed, 11 insertions, 27 deletions
diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c
index 81429086d8..70102e58fe 100644
--- a/ext/opcache/jit/zend_jit.c
+++ b/ext/opcache/jit/zend_jit.c
@@ -111,7 +111,7 @@ static int zend_may_overflow(const zend_op *opline, const zend_op_array *op_arra
static void ZEND_FASTCALL zend_runtime_jit(void);
static int zend_jit_trace_op_len(const zend_op *opline);
-static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op *opline, zend_jit_trace_rec *trace);
+static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op *opline);
static uint32_t zend_jit_trace_get_exit_point(const zend_op *from_opline, const zend_op *to_opline, zend_jit_trace_rec *trace, uint32_t flags);
static const void *zend_jit_trace_get_exit_addr(uint32_t n);
static void zend_jit_trace_add_code(const void *start, uint32_t size);
diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c
index 138f4cbb2c..699103b634 100644
--- a/ext/opcache/jit/zend_jit_trace.c
+++ b/ext/opcache/jit/zend_jit_trace.c
@@ -240,7 +240,7 @@ static zend_string *zend_jit_trace_name(const zend_op_array *op_array, uint32_t
return buf.s;
}
-static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op *opline, zend_jit_trace_rec *trace)
+static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op *opline)
{
switch (opline->opcode) {
case ZEND_IS_IDENTICAL:
diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc
index db194b9e03..c625f68382 100644
--- a/ext/opcache/jit/zend_jit_x86.dasc
+++ b/ext/opcache/jit/zend_jit_x86.dasc
@@ -3148,8 +3148,14 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra
zend_jit_check_exception(Dst);
}
- if (!GCC_GLOBAL_REGS) {
+ while (trace->op != ZEND_JIT_TRACE_VM && trace->op != ZEND_JIT_TRACE_END) {
+ trace++;
+ }
+
+ if (!GCC_GLOBAL_REGS
+ && (trace->op != ZEND_JIT_TRACE_END || trace->stop != ZEND_JIT_TRACE_STOP_RETURN)) {
if (opline->opcode == ZEND_RETURN ||
+ opline->opcode == ZEND_RETURN_BY_REF ||
opline->opcode == ZEND_DO_UCALL ||
opline->opcode == ZEND_DO_FCALL_BY_NAME ||
opline->opcode == ZEND_DO_FCALL) {
@@ -3157,9 +3163,9 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra
}
}
- if (zend_jit_trace_may_exit(op_array, opline, trace)) {
+ if (zend_jit_trace_may_exit(op_array, opline)) {
// TODO: try to avoid this check ???
- if (opline->opcode == ZEND_RETURN) {
+ if (opline->opcode == ZEND_RETURN || opline->opcode == ZEND_RETURN_BY_REF) {
if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
| cmp IP, zend_jit_halt_op
| je ->trace_halt
@@ -3171,9 +3177,6 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra
| jl ->trace_halt
}
}
- while (trace->op != ZEND_JIT_TRACE_VM && trace->op != ZEND_JIT_TRACE_END) {
- trace++;
- }
if (trace->op != ZEND_JIT_TRACE_END || trace->stop != ZEND_JIT_TRACE_STOP_RETURN) {
const zend_op *next_opline = trace->opline;
const zend_op *exit_opline = NULL;
@@ -3221,25 +3224,6 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra
| CMP_IP next_opline
| jne &exit_addr
}
- } else {
- while (trace->op != ZEND_JIT_TRACE_VM && trace->op != ZEND_JIT_TRACE_END) {
- trace++;
- }
- // TODO: remove this ???
- if (opline->opcode == ZEND_RETURN
- && trace->op == ZEND_JIT_TRACE_END
- && trace->stop == ZEND_JIT_TRACE_STOP_RETURN) {
- if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
- | cmp IP, zend_jit_halt_op
- | je ->trace_halt
- } else if (GCC_GLOBAL_REGS) {
- | test IP, IP
- | je ->trace_halt
- } else {
- | test eax, eax
- | jl ->trace_halt
- }
- }
}
last_valid_opline = trace->opline;