summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2020-07-28 19:03:05 +0300
committerDmitry Stogov <dmitry@zend.com>2020-07-28 19:03:05 +0300
commit2a72778e2dc4f8dd9d3843e87138e0d33d928066 (patch)
tree5dd272f5609ad1e587bb86c6d833ff1d04aad0ed
parent251e667488fffa39f900c686a7df862aeade176b (diff)
downloadphp-git-2a72778e2dc4f8dd9d3843e87138e0d33d928066.tar.gz
Check for EG(exception) after leaving function frame
-rw-r--r--ext/opcache/jit/zend_jit.c2
-rw-r--r--ext/opcache/jit/zend_jit_trace.c8
-rw-r--r--ext/opcache/jit/zend_jit_x86.dasc13
3 files changed, 18 insertions, 5 deletions
diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c
index 1968eff8d5..7b7534fff6 100644
--- a/ext/opcache/jit/zend_jit.c
+++ b/ext/opcache/jit/zend_jit.c
@@ -2727,7 +2727,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, NULL)) {
+ if (!zend_jit_leave_func(&dasm_state, opline, op_array, NULL, NULL, 1)) {
goto jit_failure;
}
}
diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c
index a018c31c2e..d894b50f18 100644
--- a/ext/opcache/jit/zend_jit_trace.c
+++ b/ext/opcache/jit/zend_jit_trace.c
@@ -3724,6 +3724,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
}
} else {
int j;
+ int may_throw = 0;
if (!zend_jit_return(&dasm_state, opline, op_array,
op1_info, OP1_REG_ADDR())) {
@@ -3750,9 +3751,14 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
if (!zend_jit_free_cv(&dasm_state, opline, op_array, info, j)) {
goto jit_failure;
}
+ if (info & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_RESOURCE)) {
+ if (info & MAY_BE_RC1) {
+ may_throw = 1;
+ }
+ }
}
}
- if (!zend_jit_leave_func(&dasm_state, opline, op_array, p + 1, &zend_jit_traces[ZEND_JIT_TRACE_NUM])) {
+ if (!zend_jit_leave_func(&dasm_state, opline, op_array, p + 1, &zend_jit_traces[ZEND_JIT_TRACE_NUM], may_throw)) {
goto jit_failure;
}
}
diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc
index 0c8d847dec..a63db2ad9a 100644
--- a/ext/opcache/jit/zend_jit_x86.dasc
+++ b/ext/opcache/jit/zend_jit_x86.dasc
@@ -9986,7 +9986,7 @@ static int zend_jit_free_op(dasm_State **Dst, const zend_op *opline, /*const zen
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, zend_jit_trace_info *trace_info)
+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, int may_throw)
{
/* 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)]
@@ -10055,13 +10055,20 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const ze
&& (JIT_G(current_frame) && !TRACE_FRAME_IS_UNKNOWN_RETURN(JIT_G(current_frame)))) {
zend_jit_reset_opline(Dst, NULL);
} else {
- // TODO: exception handling for tracing JIT ???
| LOAD_OPLINE
| ADD_IP sizeof(zend_op)
}
|8:
+ if ((trace->op != ZEND_JIT_TRACE_END ||
+ trace->stop != ZEND_JIT_TRACE_STOP_RECURSIVE_RET) &&
+ may_throw) {
+ | // if (EG(exception))
+ | MEM_OP2_1_ZTS cmp, aword, executor_globals, exception, 0, r0
+ | jne ->leave_throw_handler
+ }
+
if (trace->op == ZEND_JIT_TRACE_BACK
&& (!JIT_G(current_frame) || TRACE_FRAME_IS_UNKNOWN_RETURN(JIT_G(current_frame)))) {
const zend_op *next_opline = trace->opline;
@@ -10074,6 +10081,7 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const ze
} while (trace->op == ZEND_JIT_TRACE_INIT_CALL);
ZEND_ASSERT(trace->op == ZEND_JIT_TRACE_VM || trace->op == ZEND_JIT_TRACE_END);
next_opline = trace->opline;
+ ZEND_ASSERT(next_opline != NULL);
current_frame = JIT_G(current_frame);
JIT_G(current_frame) = NULL;
exit_point = zend_jit_trace_get_exit_point(opline, NULL, trace, 0);
@@ -10082,7 +10090,6 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const ze
if (!exit_addr) {
return 0;
}
- | // TODO: exception handling ???
if (trace->op == ZEND_JIT_TRACE_END
&& trace->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_RET) {
trace_info->flags |= ZEND_JIT_TRACE_LOOP;