Skip to content

Commit 4006c00

Browse files
committed
Save CPU regesters on side exit for deoptimization
1 parent c4bdf41 commit 4006c00

File tree

6 files changed

+66
-8
lines changed

6 files changed

+66
-8
lines changed

ext/opcache/jit/zend_jit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "Optimizer/zend_call_graph.h"
3434
#include "Optimizer/zend_dump.h"
3535

36+
#include "jit/zend_jit_x86.h"
3637
#include "jit/zend_jit_internal.h"
3738

3839
#ifdef ZTS
@@ -165,7 +166,6 @@ static zend_bool zend_long_is_power_of_two(zend_long x)
165166
#define OP1_DATA_RANGE_EX() OP_RANGE_EX(ssa_op + 1, op1)
166167

167168
#include "dynasm/dasm_x86.h"
168-
#include "jit/zend_jit_x86.h"
169169
#include "jit/zend_jit_helpers.c"
170170
#include "jit/zend_jit_disasm_x86.c"
171171
#ifndef _WIN32

ext/opcache/jit/zend_jit_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_ret_trace_helper(ZEND_OPCODE_HAND
422422
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_trace_helper(ZEND_OPCODE_HANDLER_ARGS);
423423

424424
int ZEND_FASTCALL zend_jit_trace_hot_root(zend_execute_data *execute_data, const zend_op *opline);
425-
int ZEND_FASTCALL zend_jit_trace_exit(uint32_t trace_num, uint32_t exit_num);
425+
int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf *regs);
426426
zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *execute_data, const zend_op *opline, zend_jit_trace_rec *trace_buffer, uint8_t start);
427427

428428
static zend_always_inline const zend_op* zend_jit_trace_get_exit_opline(zend_jit_trace_rec *trace, const zend_op *opline, zend_bool *exit_if_true)

ext/opcache/jit/zend_jit_trace.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3879,8 +3879,9 @@ int ZEND_FASTCALL zend_jit_trace_hot_side(zend_execute_data *execute_data, uint3
38793879
return (stop == ZEND_JIT_TRACE_STOP_HALT) ? -1 : 0;
38803880
}
38813881

3882-
int ZEND_FASTCALL zend_jit_trace_exit(uint32_t trace_num, uint32_t exit_num)
3882+
int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf *regs)
38833883
{
3884+
uint32_t trace_num = (uint32_t)(uintptr_t)EG(reserved)[zend_func_info_rid];
38843885
zend_execute_data *execute_data = EG(current_execute_data);
38853886
const zend_op *opline;
38863887
zend_jit_trace_info *t = &zend_jit_traces[trace_num];

ext/opcache/jit/zend_jit_vm_helpers.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "Optimizer/zend_func_info.h"
2929
#include "Optimizer/zend_call_graph.h"
3030
#include "zend_jit.h"
31+
#include "zend_jit_x86.h"
3132
#include "zend_jit_internal.h"
3233

3334
#ifdef HAVE_GCC_GLOBAL_REGS

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2326,16 +2326,62 @@ static int zend_jit_trace_exit_stub(dasm_State **Dst)
23262326
{
23272327
|->trace_exit:
23282328
|
2329-
| // TODO: Save CPU registers ???
2329+
| // Save CPU registers
2330+
|.if X64
2331+
| sub r4, 16*8+16*8-8 /* CPU regs + SSE regs */
2332+
| mov aword [r4+11*8], r11
2333+
| mov aword [r4+10*8], r10
2334+
| mov aword [r4+9*8], r9
2335+
| mov aword [r4+8*8], r8
2336+
| mov aword [r4+7*8], rdi
2337+
| mov aword [r4+6*8], rsi
2338+
| mov aword [r4+2*8], rdx
2339+
| mov aword [r4+1*8], rcx
2340+
| mov aword [r4+0*8], rax
2341+
| mov FCARG1a, aword [r4+16*8+16*8-8] // exit_num = POP
2342+
| mov FCARG2a, r4
2343+
| movsd qword [r4+16*8+15*8], xmm15
2344+
| movsd qword [r4+16*8+14*8], xmm14
2345+
| movsd qword [r4+16*8+13*8], xmm13
2346+
| movsd qword [r4+16*8+12*8], xmm12
2347+
| movsd qword [r4+16*8+11*8], xmm11
2348+
| movsd qword [r4+16*8+10*8], xmm10
2349+
| movsd qword [r4+16*8+9*8], xmm9
2350+
| movsd qword [r4+16*8+8*8], xmm8
2351+
| movsd qword [r4+16*8+7*8], xmm7
2352+
| movsd qword [r4+16*8+6*8], xmm6
2353+
| movsd qword [r4+16*8+5*8], xmm5
2354+
| movsd qword [r4+16*8+4*8], xmm4
2355+
| movsd qword [r4+16*8+3*8], xmm3
2356+
| movsd qword [r4+16*8+2*8], xmm2
2357+
| movsd qword [r4+16*8+1*8], xmm1
2358+
| movsd qword [r4+16*8+0*8], xmm0
2359+
|.else
2360+
| sub r4, 8*4+8*8-4 /* CPU regs + SSE regs */
2361+
| mov aword [r4+2*4], edx
2362+
| mov aword [r4+1*4], ecx
2363+
| mov aword [r4+0*4], eax
2364+
| mov FCARG1a, aword [r4+8*4+8*8-4] // exit_num = POP
2365+
| mov FCARG2a, r4
2366+
| movsd qword [r4+8*4+7*8], xmm7
2367+
| movsd qword [r4+8*4+6*8], xmm6
2368+
| movsd qword [r4+8*4+5*8], xmm5
2369+
| movsd qword [r4+8*4+4*8], xmm4
2370+
| movsd qword [r4+8*4+3*8], xmm3
2371+
| movsd qword [r4+8*4+2*8], xmm2
2372+
| movsd qword [r4+8*4+1*8], xmm1
2373+
| movsd qword [r4+8*4+0*8], xmm0
2374+
|.endif
23302375
|
2331-
| // trace_num = EG(reserved)[zend_func_info_rid]
2332-
| MEM_OP2_2_ZTS mov, FCARG1a, aword, executor_globals, reserved[zend_func_info_rid], r0
2333-
| // exit_num = POP
2334-
| pop FCARG2a
23352376
| // EX(opline) = opline
23362377
| SAVE_OPLINE
23372378
| // zend_jit_trace_exit(trace_num, exit_num)
23382379
| EXT_CALL zend_jit_trace_exit, r0
2380+
|.if X64
2381+
| add r4, 16*8+16*8 /* CPU regs + SSE regs */
2382+
|.else
2383+
| add r4, 8*4+8*8 /* CPU regs + SSE regs */
2384+
|.endif
23392385
| // execute_data = EG(current_excute_data)
23402386
| MEM_OP2_2_ZTS mov, FP, aword, executor_globals, current_execute_data, r0
23412387
| test eax, eax

ext/opcache/jit/zend_jit_x86.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ typedef enum _zend_reg {
6565
ZREG_NUM
6666
} zend_reg;
6767

68+
typedef struct _zend_jit_registers_buf {
69+
#if defined(__x86_64__) || defined(_WIN64)
70+
uint64_t r[16];
71+
double xmm[16];
72+
#else
73+
uint32_t r[8];
74+
double xmm[8];
75+
#endif
76+
} zend_jit_registers_buf;
77+
6878
#define ZREG_RAX ZREG_R0
6979
#define ZREG_RCX ZREG_R1
7080
#define ZREG_RDX ZREG_R2

0 commit comments

Comments
 (0)