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);
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) {
}
}
- 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
| 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;
| 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;