]> granicus.if.org Git - php/commitdiff
Avoid loop throgh side_exit from the first trace instruction.
authorDmitry Stogov <dmitry@zend.com>
Thu, 7 May 2020 21:48:17 +0000 (00:48 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 7 May 2020 21:48:17 +0000 (00:48 +0300)
ext/opcache/jit/zend_jit_trace.c
ext/opcache/jit/zend_jit_x86.dasc

index 46455f8d54465011aadda2f48f480f42c2acf2db..5523ecacbd654b9d3947442bfc56898133760dc3 100644 (file)
@@ -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)
index a46d0777897a8d7d8be73d9be4d1521ce2e71746..e2a233f2713b2bb4148d6241998932eb376e1aae 100644 (file)
@@ -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;
 }