summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2020-06-03 10:58:17 +0300
committerDmitry Stogov <dmitry@zend.com>2020-06-03 10:58:17 +0300
commitc93c3b4f0efd97f83d9f90017c30e13ef40b52de (patch)
tree2acd2f6b5aca7ee4b0f07d70821822112dae57ed
parent26ce32c45af555a401fc1e9194ae16ea5ee9b7e6 (diff)
downloadphp-git-c93c3b4f0efd97f83d9f90017c30e13ef40b52de.tar.gz
Handle VM interrupts after DO_ICALL through side exits
-rw-r--r--ext/opcache/jit/zend_jit_x86.dasc34
1 files changed, 20 insertions, 14 deletions
diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc
index cf0e66aa5e..5d5d3e2f16 100644
--- a/ext/opcache/jit/zend_jit_x86.dasc
+++ b/ext/opcache/jit/zend_jit_x86.dasc
@@ -2794,22 +2794,16 @@ static int zend_jit_check_timeout(dasm_State **Dst, const zend_op *opline, const
| jne ->interrupt_handler
#else
| MEM_OP2_1_ZTS cmp, byte, executor_globals, vm_interrupt, 0, r0
- if (last_valid_opline == opline) {
- if (exit_addr) {
- | jne &exit_addr
- } else {
- | jne ->interrupt_handler
- }
+ if (exit_addr) {
+ | jne &exit_addr
+ } else if (last_valid_opline == opline) {
+ | jne ->interrupt_handler
} else {
| jne >1
|.cold_code
|1:
| LOAD_IP_ADDR opline
- if (exit_addr) {
- | jmp &exit_addr
- } else {
- | jmp ->interrupt_handler
- }
+ | jmp ->interrupt_handler
|.code
}
#endif
@@ -8231,6 +8225,7 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
zend_jit_addr res_addr;
uint32_t call_num_args = 0;
zend_bool unknown_num_args = 0;
+ const void *exit_addr = NULL;
if (RETURN_VALUE_USED(opline)) {
res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
@@ -8340,8 +8335,8 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
if (!func) {
if (trace) {
uint32_t exit_point = zend_jit_trace_get_exit_point(opline, opline, NULL, ZEND_JIT_EXIT_TO_VM);
- const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
+ exit_addr = zend_jit_trace_get_exit_addr(exit_point);
if (!exit_addr) {
return 0;
}
@@ -8628,8 +8623,8 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
if (!func) {
if (trace) {
uint32_t exit_point = zend_jit_trace_get_exit_point(opline, opline, NULL, ZEND_JIT_EXIT_TO_VM);
- const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
+ exit_addr = zend_jit_trace_get_exit_addr(exit_point);
if (!exit_addr) {
return 0;
}
@@ -8762,9 +8757,20 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
|.code
// TODO: Can we avoid checking for interrupts after each call ???
- if (!zend_jit_check_timeout(Dst, opline + 1, NULL)) {
+ if (trace && last_valid_opline != opline) {
+ int32_t exit_point = zend_jit_trace_get_exit_point(opline, opline + 1, NULL, ZEND_JIT_EXIT_TO_VM);
+
+ exit_addr = zend_jit_trace_get_exit_addr(exit_point);
+ if (!exit_addr) {
+ return 0;
+ }
+ } else {
+ exit_addr = NULL;
+ }
+ if (!zend_jit_check_timeout(Dst, opline + 1, exit_addr)) {
return 0;
}
+
if (opline->opcode != ZEND_DO_ICALL) {
| LOAD_IP_ADDR (opline + 1)
}