From: Dmitry Stogov Date: Fri, 29 May 2020 10:25:59 +0000 (+0300) Subject: Allow tracing JIT generate code when function exits from VM (e.g. for magic __get... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dc7a0fb2361ff4fe6217776b73b6eca4569fa275;p=php Allow tracing JIT generate code when function exits from VM (e.g. for magic __get/__set) --- diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h index 631e2ed4d2..3dd0d1f770 100644 --- a/ext/opcache/jit/zend_jit_internal.h +++ b/ext/opcache/jit/zend_jit_internal.h @@ -142,6 +142,7 @@ int ZEND_FASTCALL zend_jit_check_constant(const zval *key); _(RECURSIVE_CALL, "recursive call") \ _(RECURSIVE_RET, "recursive return") \ _(RETURN, "return") \ + _(RETURN_HALT, "return from interpreter") \ _(LINK, "link to another trace") \ /* compilation and linking successful */ \ _(COMPILED, "compiled") \ diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 37c65a001b..741662da55 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -4110,7 +4110,8 @@ done: } t->link = zend_jit_find_trace(p->opline->handler); zend_jit_trace_link_to_root(&dasm_state, &zend_jit_traces[t->link]); - } else if (p->stop == ZEND_JIT_TRACE_STOP_RETURN) { + } else if (p->stop == ZEND_JIT_TRACE_STOP_RETURN + || p->stop == ZEND_JIT_TRACE_STOP_RETURN_HALT) { zend_jit_trace_return(&dasm_state, 0); } else { // TODO: not implemented ??? @@ -4659,6 +4660,7 @@ int ZEND_FASTCALL zend_jit_trace_hot_root(zend_execute_data *execute_data, const { const zend_op *orig_opline; zend_jit_trace_stop stop; + int ret = 0; zend_op_array *op_array; zend_jit_op_array_trace_extension *jit_extension; size_t offset; @@ -4706,6 +4708,9 @@ repeat: } if (ZEND_JIT_TRACE_STOP_OK(stop)) { + if (stop == ZEND_JIT_TRACE_STOP_RETURN_HALT) { + ret = -1; + } if (JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_STOP) { if (stop == ZEND_JIT_TRACE_STOP_LINK) { uint32_t idx = trace_buffer[1].last; @@ -4730,6 +4735,9 @@ repeat: goto abort; } } else { + if (stop == ZEND_JIT_TRACE_STOP_HALT) { + ret = -1; + } abort: if (JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_ABORT) { fprintf(stderr, "---- TRACE %d abort (%s)\n", @@ -4755,7 +4763,7 @@ abort: fprintf(stderr, "\n"); } - return (stop == ZEND_JIT_TRACE_STOP_HALT) ? -1 : 0; + return ret; } static void zend_jit_blacklist_trace_exit(uint32_t trace_num, uint32_t exit_num) @@ -4929,6 +4937,7 @@ exit: int ZEND_FASTCALL zend_jit_trace_hot_side(zend_execute_data *execute_data, uint32_t parent_num, uint32_t exit_num) { zend_jit_trace_stop stop; + int ret = 0; uint32_t trace_num; zend_jit_trace_rec trace_buffer[ZEND_JIT_TRACE_MAX_LENGTH]; @@ -4965,6 +4974,9 @@ int ZEND_FASTCALL zend_jit_trace_hot_side(zend_execute_data *execute_data, uint3 } if (ZEND_JIT_TRACE_STOP_OK(stop)) { + if (stop == ZEND_JIT_TRACE_STOP_RETURN_HALT) { + ret = -1; + } if (JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_STOP) { if (stop == ZEND_JIT_TRACE_STOP_LINK) { uint32_t idx = trace_buffer[1].last; @@ -4998,6 +5010,9 @@ int ZEND_FASTCALL zend_jit_trace_hot_side(zend_execute_data *execute_data, uint3 goto abort; } } else { + if (stop == ZEND_JIT_TRACE_STOP_HALT) { + ret = -1; + } abort: if (JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_ABORT) { fprintf(stderr, "---- TRACE %d abort (%s)\n", @@ -5018,7 +5033,7 @@ abort: fprintf(stderr, "\n"); } - return (stop == ZEND_JIT_TRACE_STOP_HALT) ? -1 : 0; + return ret; } int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf *regs) diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index f9d14d1f43..db530cf3ef 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -682,7 +682,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, #ifdef HAVE_GCC_GLOBAL_REGS handler(); if (UNEXPECTED(opline == zend_jit_halt_op)) { - stop = ZEND_JIT_TRACE_STOP_HALT; + stop = ZEND_JIT_TRACE_STOP_RETURN_HALT; break; } if (UNEXPECTED(execute_data != prev_execute_data)) { @@ -690,7 +690,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, rc = handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); if (rc != 0) { if (rc < 0) { - stop = ZEND_JIT_TRACE_STOP_HALT; + stop = ZEND_JIT_TRACE_STOP_RETRUN_HALT; break; } execute_data = EG(current_execute_data);