summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_generators.c3
-rw-r--r--ext/opcache/Optimizer/zend_inference.c1
-rw-r--r--ext/opcache/jit/zend_jit_trace.c14
-rw-r--r--ext/opcache/jit/zend_jit_vm_helpers.c6
-rw-r--r--ext/opcache/jit/zend_jit_x86.dasc16
5 files changed, 29 insertions, 11 deletions
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 803627f9a1..2e32301a9b 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -742,9 +742,11 @@ try_again:
{
/* Backup executor globals */
zend_execute_data *original_execute_data = EG(current_execute_data);
+ uint32_t original_jit_trace_num = EG(jit_trace_num);
/* Set executor globals */
EG(current_execute_data) = generator->execute_data;
+ EG(jit_trace_num) = 0;
/* We want the backtrace to look as if the generator function was
* called from whatever method we are current running (e.g. next()).
@@ -777,6 +779,7 @@ try_again:
/* Restore executor globals */
EG(current_execute_data) = original_execute_data;
+ EG(jit_trace_num) = original_jit_trace_num;
/* If an exception was thrown in the generator we have to internally
* rethrow it in the parent scope.
diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c
index 5a29165aec..72b229af3d 100644
--- a/ext/opcache/Optimizer/zend_inference.c
+++ b/ext/opcache/Optimizer/zend_inference.c
@@ -3511,7 +3511,6 @@ static zend_always_inline int _zend_update_type_info(
}
break;
case ZEND_CATCH:
- case ZEND_INCLUDE_OR_EVAL:
/* Forbidden opcodes */
ZEND_UNREACHABLE();
break;
diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c
index bae7799717..1400b78225 100644
--- a/ext/opcache/jit/zend_jit_trace.c
+++ b/ext/opcache/jit/zend_jit_trace.c
@@ -4456,10 +4456,16 @@ done:
}
}
} else if (p->stop == ZEND_JIT_TRACE_STOP_LINK
+ || p->stop == ZEND_JIT_TRACE_STOP_RETURN_HALT
|| p->stop == ZEND_JIT_TRACE_STOP_INTERPRETER) {
if (opline->opcode == ZEND_DO_UCALL
|| opline->opcode == ZEND_DO_FCALL
- || opline->opcode == ZEND_DO_FCALL_BY_NAME) {
+ || opline->opcode == ZEND_DO_FCALL_BY_NAME
+ || opline->opcode == ZEND_GENERATOR_CREATE
+ || opline->opcode == ZEND_GENERATOR_RETURN
+ || opline->opcode == ZEND_YIELD
+ || opline->opcode == ZEND_YIELD_FROM
+ || opline->opcode == ZEND_INCLUDE_OR_EVAL) {
zend_jit_trace_setup_ret_counter(opline, jit_extension->offset);
}
if (JIT_G(current_frame)
@@ -5499,12 +5505,6 @@ static zend_always_inline uint8_t zend_jit_trace_supported(const zend_op *opline
case ZEND_CATCH:
case ZEND_FAST_CALL:
case ZEND_FAST_RET:
- case ZEND_GENERATOR_CREATE:
- case ZEND_GENERATOR_RETURN:
- case ZEND_EXIT:
- case ZEND_YIELD:
- case ZEND_YIELD_FROM:
- case ZEND_INCLUDE_OR_EVAL:
return ZEND_JIT_TRACE_UNSUPPORTED;
default:
return ZEND_JIT_TRACE_SUPPORTED;
diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c
index 5ab2129a30..c7c7afba9d 100644
--- a/ext/opcache/jit/zend_jit_vm_helpers.c
+++ b/ext/opcache/jit/zend_jit_vm_helpers.c
@@ -713,6 +713,9 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
if (EX(call)->func->type == ZEND_INTERNAL_FUNCTION) {
TRACE_RECORD(ZEND_JIT_TRACE_DO_ICALL, 0, EX(call)->func);
}
+ } else if (opline->opcode == ZEND_INCLUDE_OR_EVAL) {
+ stop = ZEND_JIT_TRACE_STOP_INTERPRETER;
+ break;
}
handler = (zend_vm_opcode_handler_t)ZEND_OP_TRACE_INFO(opline, offset)->call_handler;
@@ -975,7 +978,8 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
TRACE_END(ZEND_JIT_TRACE_END, stop, end_opline);
#ifdef HAVE_GCC_GLOBAL_REGS
- if (stop != ZEND_JIT_TRACE_STOP_HALT) {
+ if (stop != ZEND_JIT_TRACE_STOP_HALT
+ && stop != ZEND_JIT_TRACE_STOP_RETURN_HALT) {
EX(opline) = opline;
}
#endif
diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc
index 30411d0724..35c536454a 100644
--- a/ext/opcache/jit/zend_jit_x86.dasc
+++ b/ext/opcache/jit/zend_jit_x86.dasc
@@ -3183,7 +3183,10 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra
if (zend_jit_trace_may_exit(op_array, opline)) {
// TODO: try to avoid this check ???
- if (opline->opcode == ZEND_RETURN || opline->opcode == ZEND_RETURN_BY_REF) {
+ if (opline->opcode == ZEND_RETURN ||
+ opline->opcode == ZEND_RETURN_BY_REF ||
+ opline->opcode == ZEND_GENERATOR_CREATE) {
+
if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
| cmp IP, zend_jit_halt_op
| je ->trace_halt
@@ -3194,8 +3197,17 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra
| test eax, eax
| jl ->trace_halt
}
+ } else if (opline->opcode == ZEND_EXIT ||
+ opline->opcode == ZEND_GENERATOR_RETURN ||
+ opline->opcode == ZEND_YIELD ||
+ opline->opcode == ZEND_YIELD_FROM) {
+ | jmp ->trace_halt
}
- if (trace->op != ZEND_JIT_TRACE_END || trace->stop != ZEND_JIT_TRACE_STOP_RETURN) {
+ if (trace->op != ZEND_JIT_TRACE_END ||
+ (trace->stop != ZEND_JIT_TRACE_STOP_RETURN &&
+ trace->stop != ZEND_JIT_TRACE_STOP_RETURN_HALT &&
+ trace->stop != ZEND_JIT_TRACE_STOP_INTERPRETER)) {
+
const zend_op *next_opline = trace->opline;
const zend_op *exit_opline = NULL;
uint32_t exit_point;