Skip to content

Commit 60090ad

Browse files
committed
Move EG(vm_interrupt) checks at the end of the trace loops
1 parent 9dcf494 commit 60090ad

File tree

3 files changed

+35
-12
lines changed

3 files changed

+35
-12
lines changed

ext/opcache/jit/zend_jit_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ typedef struct _zend_jit_trace_info {
353353
uint32_t code_size; /* size of native code */
354354
uint32_t exit_counters; /* offset in exit counters array */
355355
uint32_t stack_map_size;
356+
uint32_t loop_kind; /* LOOP, RECURSIVE_CALL or RECURSIVE_RET */
356357
const zend_op *opline; /* first opline */
357358
const void *code_start; /* address of native code */
358359
zend_jit_trace_exit_info *exit_info; /* info about side exits */

ext/opcache/jit/zend_jit_trace.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2456,6 +2456,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
24562456
zend_uchar res_type = IS_UNKNOWN;
24572457
const zend_op *opline, *orig_opline;
24582458
const zend_ssa_op *ssa_op, *orig_ssa_op;
2459+
const void *timeout_exit_addr = NULL;
24592460

24602461
JIT_G(current_trace) = trace_buffer;
24612462

@@ -2628,17 +2629,16 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
26282629
}
26292630

26302631
if (trace_buffer->stop != ZEND_JIT_TRACE_STOP_RECURSIVE_RET) {
2631-
const void *exit_addr = NULL;
2632-
26332632
if (ra && zend_jit_trace_stack_needs_deoptimization(stack, op_array->last_var + op_array->T)) {
2634-
uint32_t exit_point = zend_jit_trace_get_exit_point(NULL, NULL, NULL, 0);
2633+
uint32_t exit_point = zend_jit_trace_get_exit_point(NULL, NULL, NULL, ZEND_JIT_EXIT_TO_VM);
26352634

2636-
exit_addr = zend_jit_trace_get_exit_addr(exit_point);
2637-
if (!exit_addr) {
2635+
timeout_exit_addr = zend_jit_trace_get_exit_addr(exit_point);
2636+
if (!timeout_exit_addr) {
26382637
goto jit_failure;
26392638
}
2639+
} else {
2640+
timeout_exit_addr = dasm_labels[zend_lbinterrupt_handler];
26402641
}
2641-
zend_jit_check_timeout(&dasm_state, opline, exit_addr);
26422642
}
26432643

26442644
if (ra && trace_buffer->stop != ZEND_JIT_TRACE_STOP_LOOP) {
@@ -3981,7 +3981,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
39813981
}
39823982
}
39833983
t->link = ZEND_JIT_TRACE_NUM;
3984-
zend_jit_jmp(&dasm_state, 0); /* jump back to start of the trace loop */
3984+
t->loop_kind = p->stop;
3985+
zend_jit_trace_end_loop(&dasm_state, 0, timeout_exit_addr); /* jump back to start of the trace loop */
39853986
} else if (p->stop == ZEND_JIT_TRACE_STOP_LINK) {
39863987
if (ra) {
39873988
/* Generate code for trace deoptimization */
@@ -4000,7 +4001,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
40004001
goto jit_failure;
40014002
}
40024003
t->link = zend_jit_find_trace(p->opline->handler);
4003-
zend_jit_trace_link_to_root(&dasm_state, p->opline->handler);
4004+
zend_jit_trace_link_to_root(&dasm_state, &zend_jit_traces[t->link]);
40044005
} else if (p->stop == ZEND_JIT_TRACE_STOP_RETURN) {
40054006
zend_jit_trace_return(&dasm_state, 0);
40064007
} else {
@@ -4139,6 +4140,7 @@ static zend_jit_trace_stop zend_jit_compile_root_trace(zend_jit_trace_rec *trace
41394140
t->exit_count = 0;
41404141
t->child_count = 0;
41414142
t->stack_map_size = 0;
4143+
t->loop_kind = 0;
41424144
t->opline = ((zend_jit_trace_start_rec*)trace_buffer)->opline;
41434145
t->exit_info = exit_info;
41444146
t->stack_map = NULL;
@@ -4699,6 +4701,7 @@ static zend_jit_trace_stop zend_jit_compile_side_trace(zend_jit_trace_rec *trace
46994701
t->exit_count = 0;
47004702
t->child_count = 0;
47014703
t->stack_map_size = 0;
4704+
t->loop_kind = 0;
47024705
t->opline = NULL;
47034706
t->exit_info = exit_info;
47044707
t->stack_map = NULL;

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2784,6 +2784,18 @@ static int zend_jit_check_timeout(dasm_State **Dst, const zend_op *opline, const
27842784
return 1;
27852785
}
27862786

2787+
static int zend_jit_trace_end_loop(dasm_State **Dst, int loop_label, const void *timeout_exit_addr)
2788+
{
2789+
if (timeout_exit_addr) {
2790+
| MEM_OP2_1_ZTS cmp, byte, executor_globals, vm_interrupt, 0, r0
2791+
| je =>loop_label
2792+
| jmp &timeout_exit_addr
2793+
} else {
2794+
| jmp =>loop_label
2795+
}
2796+
return 1;
2797+
}
2798+
27872799
static int zend_jit_check_exception(dasm_State **Dst)
27882800
{
27892801
| MEM_OP2_1_ZTS cmp, aword, executor_globals, exception, 0, r0
@@ -2984,9 +2996,9 @@ static int zend_jit_link_side_trace(const void *code, size_t size, uint32_t exit
29842996
return zend_jit_patch(code, size, zend_jit_trace_get_exit_addr(exit_num), addr);
29852997
}
29862998

2987-
static int zend_jit_trace_link_to_root(dasm_State **Dst, const void *code)
2999+
static int zend_jit_trace_link_to_root(dasm_State **Dst, zend_jit_trace_info *t)
29883000
{
2989-
const void *exit_addr;
3001+
const void *link_addr;
29903002
size_t prologue_size;
29913003

29923004
/* Skip prologue. */
@@ -3016,9 +3028,16 @@ static int zend_jit_trace_link_to_root(dasm_State **Dst, const void *code)
30163028
prologue_size = 12;
30173029
#endif
30183030
}
3019-
exit_addr = (const void*)((const char*)code + prologue_size);
3031+
link_addr = (const void*)((const char*)t->code_start + prologue_size);
30203032

3021-
| jmp &exit_addr
3033+
if (t->link == t->id && t->loop_kind != ZEND_JIT_TRACE_STOP_RECURSIVE_RET) {
3034+
/* Check timeout for links to LOOP */
3035+
| MEM_OP2_1_ZTS cmp, byte, executor_globals, vm_interrupt, 0, r0
3036+
| je &link_addr
3037+
| jmp ->interrupt_handler
3038+
} else {
3039+
| jmp &link_addr
3040+
}
30223041
return 1;
30233042
}
30243043

0 commit comments

Comments
 (0)