1
0
mirror of https://github.com/php/php-src.git synced 2026-04-02 05:32:28 +02:00

Fixed tracing JIT support for ZEND_RETURN_BY_REF in CALL VM

This commit is contained in:
Dmitry Stogov
2020-05-27 18:04:16 +03:00
parent 0bf2bfcf8d
commit d2d5738b32
3 changed files with 11 additions and 27 deletions

View File

@@ -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);

View File

@@ -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:

View File

@@ -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;