From: Dmitry Stogov Date: Thu, 7 May 2020 21:48:17 +0000 (+0300) Subject: Avoid loop throgh side_exit from the first trace instruction. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ef45d4d69851fc59ee327e03b5ed67569297a6f7;p=php Avoid loop throgh side_exit from the first trace instruction. --- diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 46455f8d54..5523ecacbd 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -4895,6 +4895,7 @@ int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf { 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 *orig_opline = EX(opline); const zend_op *opline; zend_jit_trace_info *t = &zend_jit_traces[trace_num]; @@ -4922,7 +4923,7 @@ int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf } if (EG(vm_interrupt)) { - return 0; + return 1; /* Lock-free check if the side trace was already JIT-ed or blacklist-ed in another process */ } else if (t->exit_info[exit_num].flags & (ZEND_JIT_EXIT_JITED|ZEND_JIT_EXIT_BLACKLISTED)) { return 0; @@ -4949,12 +4950,14 @@ int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf fprintf(stderr, "---- EXIT %d/%d blacklisted\n", trace_num, exit_num); } + return 0; } } else if (zend_jit_trace_exit_is_hot(trace_num, exit_num)) { return zend_jit_trace_hot_side(execute_data, trace_num, exit_num); } - return 0; + /* Return 1 to call original handler instead of the same JIT-ed trace */ + return (orig_opline == t->opline && EX(opline) == orig_opline); } static zend_always_inline uint8_t zend_jit_trace_supported(const zend_op *opline) diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index a46d077789..e2a233f271 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -2383,28 +2383,17 @@ static int zend_jit_trace_exit_stub(dasm_State **Dst) | add r4, 8*4+8*8 /* CPU regs + SSE regs */ |.endif - | // check for interrupt (try to avoid this ???) - | MEM_OP2_1_ZTS cmp, byte, executor_globals, vm_interrupt, 0, r0 - | jne ->interrupt_handler + | test eax, eax + | jne >1 | // execute_data = EG(current_execute_data) | MEM_OP2_2_ZTS mov, FP, aword, executor_globals, current_execute_data, r0 - | test eax, eax - | jl ->trace_halt | // opline = EX(opline) | LOAD_OPLINE if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { -#if 1 - //TODO: this doesn't work for exit from first instruction ??? | add r4, HYBRID_SPAD | JMP_IP -#else - | mov r0, EX->func - | mov r1, aword [r0 + offsetof(zend_op_array, reserved[zend_func_info_rid])] - | mov r1, aword [r1 + offsetof(zend_jit_op_array_trace_extension, offset)] - | jmp aword [IP + r1] -#endif } else if (GCC_GLOBAL_REGS) { | add r4, SPAD // stack alignment | JMP_IP @@ -2416,6 +2405,44 @@ static int zend_jit_trace_exit_stub(dasm_State **Dst) | ret } + |1: + | jl ->trace_halt + + | // execute_data = EG(current_execute_data) + | MEM_OP2_2_ZTS mov, FP, aword, executor_globals, current_execute_data, r0 + | // opline = EX(opline) + | LOAD_OPLINE + + | // check for interrupt (try to avoid this ???) + | MEM_OP2_1_ZTS cmp, byte, executor_globals, vm_interrupt, 0, r0 + | jne ->interrupt_handler + + if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { + | add r4, HYBRID_SPAD + | mov r0, EX->func + | mov r0, aword [r0 + offsetof(zend_op_array, reserved[zend_func_info_rid])] + | mov r0, aword [r0 + offsetof(zend_jit_op_array_trace_extension, offset)] + | jmp aword [IP + r0] + } else if (GCC_GLOBAL_REGS) { + | add r4, SPAD // stack alignment + | mov r0, EX->func + | mov r0, aword [r0 + offsetof(zend_op_array, reserved[zend_func_info_rid])] + | mov r0, aword [r0 + offsetof(zend_jit_op_array_trace_extension, offset)] + | jmp aword [IP + r0] + } else { + | mov IP, aword EX->opline + | mov FCARG1a, FP + | mov r0, EX->func + | mov r0, aword [r0 + offsetof(zend_op_array, reserved[zend_func_info_rid])] + | mov r0, aword [r0 + offsetof(zend_jit_op_array_trace_extension, offset)] + | call aword [IP + r0] + | mov FP, aword T2 // restore FP + | mov RX, aword T3 // restore IP + | add r4, NR_SPAD // stack alignment + | mov r0, 1 // ZEND_VM_ENTER + | ret + } + return 1; }