]> granicus.if.org Git - php/commitdiff
Save CPU regesters on side exit for deoptimization
authorDmitry Stogov <dmitry@zend.com>
Mon, 6 Apr 2020 20:48:20 +0000 (23:48 +0300)
committerDmitry Stogov <dmitry@zend.com>
Mon, 6 Apr 2020 20:48:20 +0000 (23:48 +0300)
ext/opcache/jit/zend_jit.c
ext/opcache/jit/zend_jit_internal.h
ext/opcache/jit/zend_jit_trace.c
ext/opcache/jit/zend_jit_vm_helpers.c
ext/opcache/jit/zend_jit_x86.dasc
ext/opcache/jit/zend_jit_x86.h

index 76acfc29defed1797da4c6b989216d4df2a63a10..b5c4ca82d7d9bd2156673a1db30668f944010d7d 100644 (file)
@@ -33,6 +33,7 @@
 #include "Optimizer/zend_call_graph.h"
 #include "Optimizer/zend_dump.h"
 
+#include "jit/zend_jit_x86.h"
 #include "jit/zend_jit_internal.h"
 
 #ifdef ZTS
@@ -165,7 +166,6 @@ static zend_bool zend_long_is_power_of_two(zend_long x)
 #define OP1_DATA_RANGE_EX() OP_RANGE_EX(ssa_op + 1, op1)
 
 #include "dynasm/dasm_x86.h"
-#include "jit/zend_jit_x86.h"
 #include "jit/zend_jit_helpers.c"
 #include "jit/zend_jit_disasm_x86.c"
 #ifndef _WIN32
index 60f9520d0b6e0b6e915898c518525c1a1aa879ac..54eaca15c6bc1ea32cd70337c2256a6cc96891b5 100644 (file)
@@ -422,7 +422,7 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_ret_trace_helper(ZEND_OPCODE_HAND
 ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_trace_helper(ZEND_OPCODE_HANDLER_ARGS);
 
 int ZEND_FASTCALL zend_jit_trace_hot_root(zend_execute_data *execute_data, const zend_op *opline);
-int ZEND_FASTCALL zend_jit_trace_exit(uint32_t trace_num, uint32_t exit_num);
+int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf *regs);
 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);
 
 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)
index d2fe33b63fbf6d540bd3fcd085f106ea49fbbdde..f24ae1c2a131f3bb3abe7de70202f929a945f591 100644 (file)
@@ -3879,8 +3879,9 @@ blacklist:
        return (stop == ZEND_JIT_TRACE_STOP_HALT) ? -1 : 0;
 }
 
-int ZEND_FASTCALL zend_jit_trace_exit(uint32_t trace_num, uint32_t exit_num)
+int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf *regs)
 {
+       uint32_t trace_num = (uint32_t)(uintptr_t)EG(reserved)[zend_func_info_rid];
        zend_execute_data *execute_data = EG(current_execute_data);
        const zend_op *opline;
        zend_jit_trace_info *t = &zend_jit_traces[trace_num];
index 906cba34587b973ccb81b87667f924235d7b0c40..450fa6055d568c1a5ee11dddd575f7165bb022c3 100644 (file)
@@ -28,6 +28,7 @@
 #include "Optimizer/zend_func_info.h"
 #include "Optimizer/zend_call_graph.h"
 #include "zend_jit.h"
+#include "zend_jit_x86.h"
 #include "zend_jit_internal.h"
 
 #ifdef HAVE_GCC_GLOBAL_REGS
index 2306c7a39205f5212b3385b5159d246d2d369039..b5c71f2cbb3730ce565767106d8225cefde85f87 100644 (file)
@@ -2326,16 +2326,62 @@ static int zend_jit_trace_exit_stub(dasm_State **Dst)
 {
        |->trace_exit:
        |
-       |       // TODO: Save CPU registers ???
+       |       // Save CPU registers
+       |.if X64
+       |       sub r4, 16*8+16*8-8 /* CPU regs + SSE regs */
+       |       mov aword [r4+11*8], r11
+       |       mov aword [r4+10*8], r10
+       |       mov aword [r4+9*8], r9
+       |       mov aword [r4+8*8], r8
+       |       mov aword [r4+7*8], rdi
+       |       mov aword [r4+6*8], rsi
+       |       mov aword [r4+2*8], rdx
+       |       mov aword [r4+1*8], rcx
+       |       mov aword [r4+0*8], rax
+       |       mov FCARG1a, aword [r4+16*8+16*8-8] // exit_num = POP
+       |       mov FCARG2a, r4
+       |       movsd qword [r4+16*8+15*8], xmm15
+       |       movsd qword [r4+16*8+14*8], xmm14
+       |       movsd qword [r4+16*8+13*8], xmm13
+       |       movsd qword [r4+16*8+12*8], xmm12
+       |       movsd qword [r4+16*8+11*8], xmm11
+       |       movsd qword [r4+16*8+10*8], xmm10
+       |       movsd qword [r4+16*8+9*8], xmm9
+       |       movsd qword [r4+16*8+8*8], xmm8
+       |       movsd qword [r4+16*8+7*8], xmm7
+       |       movsd qword [r4+16*8+6*8], xmm6
+       |       movsd qword [r4+16*8+5*8], xmm5
+       |       movsd qword [r4+16*8+4*8], xmm4
+       |       movsd qword [r4+16*8+3*8], xmm3
+       |       movsd qword [r4+16*8+2*8], xmm2
+       |       movsd qword [r4+16*8+1*8], xmm1
+       |       movsd qword [r4+16*8+0*8], xmm0
+       |.else
+       |       sub r4, 8*4+8*8-4 /* CPU regs + SSE regs */
+       |       mov aword [r4+2*4], edx
+       |       mov aword [r4+1*4], ecx
+       |       mov aword [r4+0*4], eax
+       |       mov FCARG1a, aword [r4+8*4+8*8-4] // exit_num = POP
+       |       mov FCARG2a, r4
+       |       movsd qword [r4+8*4+7*8], xmm7
+       |       movsd qword [r4+8*4+6*8], xmm6
+       |       movsd qword [r4+8*4+5*8], xmm5
+       |       movsd qword [r4+8*4+4*8], xmm4
+       |       movsd qword [r4+8*4+3*8], xmm3
+       |       movsd qword [r4+8*4+2*8], xmm2
+       |       movsd qword [r4+8*4+1*8], xmm1
+       |       movsd qword [r4+8*4+0*8], xmm0
+       |.endif
        |
-       |       // trace_num = EG(reserved)[zend_func_info_rid]
-       |       MEM_OP2_2_ZTS mov, FCARG1a, aword, executor_globals, reserved[zend_func_info_rid], r0
-       |       // exit_num = POP
-       |       pop FCARG2a
        |       // EX(opline) = opline
        |       SAVE_OPLINE
        |       // zend_jit_trace_exit(trace_num, exit_num)
        |       EXT_CALL zend_jit_trace_exit, r0
+       |.if X64
+       |       add r4, 16*8+16*8 /* CPU regs + SSE regs */
+       |.else
+       |       add r4, 8*4+8*8 /* CPU regs + SSE regs */
+       |.endif
        |       // execute_data = EG(current_excute_data)
        |       MEM_OP2_2_ZTS mov, FP, aword, executor_globals, current_execute_data, r0
        |       test eax, eax
index 71fcb93ae13b46b6ccd4e548ed53ea1fe54479a3..8b2365efada357e85eaa30d701de7db9c01c2343 100644 (file)
@@ -65,6 +65,16 @@ typedef enum _zend_reg {
        ZREG_NUM
 } zend_reg;
 
+typedef struct _zend_jit_registers_buf {
+#if defined(__x86_64__) || defined(_WIN64)
+       uint64_t r[16];
+       double xmm[16];
+#else
+       uint32_t r[8];
+       double xmm[8];
+#endif
+} zend_jit_registers_buf;
+
 #define        ZREG_RAX ZREG_R0
 #define        ZREG_RCX ZREG_R1
 #define        ZREG_RDX ZREG_R2