From e5b7fc04509f696aa28381d388059d46e970a14b Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Thu, 4 Sep 2025 12:04:50 +0200 Subject: [PATCH 1/3] Expose the origin of exit points in zend_jit_dump_exit_info() --- ext/opcache/jit/zend_jit.c | 3 ++- ext/opcache/jit/zend_jit_internal.h | 4 ++++ ext/opcache/jit/zend_jit_trace.c | 16 ++++++++++++++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 30f49fb73f67..f6a2f415c760 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -106,7 +106,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_runtime_jit(Z static int zend_jit_trace_op_len(const zend_op *opline); static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op *opline); -static uint32_t zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_t flags); +static uint32_t _zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_t flags ZEND_FILE_LINE_DC); +#define zend_jit_trace_get_exit_point(to_opline, flags) _zend_jit_trace_get_exit_point(to_opline, flags ZEND_FILE_LINE_CC) static const void *zend_jit_trace_get_exit_addr(uint32_t n); static void zend_jit_trace_add_code(const void *start, uint32_t size); static zend_string *zend_jit_func_name(const zend_op_array *op_array); diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h index 57c0dedb2fa2..1bffc969902a 100644 --- a/ext/opcache/jit/zend_jit_internal.h +++ b/ext/opcache/jit/zend_jit_internal.h @@ -456,6 +456,10 @@ typedef struct _zend_jit_trace_exit_info { uint32_t stack_offset; zend_jit_ref_snapshot poly_func; zend_jit_ref_snapshot poly_this; +#if ZEND_DEBUG + const char *filename; + int lineno; +#endif } zend_jit_trace_exit_info; typedef struct _zend_jit_trace_stack { diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 66bb380c23d8..933c3fc32dce 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -132,7 +132,7 @@ static uint32_t zend_jit_exit_point_by_addr(const void *addr) return (uint32_t)-1; } -static uint32_t zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_t flags) +static uint32_t _zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_t flags ZEND_FILE_LINE_DC) { zend_jit_trace_info *t = &zend_jit_traces[ZEND_JIT_TRACE_NUM]; uint32_t exit_point; @@ -178,7 +178,12 @@ static uint32_t zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_t && memcmp(t->stack_map + t->exit_info[i].stack_offset, stack, stack_size * sizeof(zend_jit_trace_stack)) == 0)) { if (t->exit_info[i].opline == to_opline && t->exit_info[i].flags == flags - && t->exit_info[i].stack_size == stack_size) { + && t->exit_info[i].stack_size == stack_size +#if ZEND_DEBUG + && strcmp(t->exit_info[i].filename, __zend_filename) == 0 + && t->exit_info[i].lineno == __zend_lineno +#endif + ) { return i; } } @@ -202,6 +207,10 @@ static uint32_t zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_t t->exit_info[exit_point].stack_offset = stack_offset; t->exit_info[exit_point].poly_func = (zend_jit_ref_snapshot){.reg = ZREG_NONE}; t->exit_info[exit_point].poly_this = (zend_jit_ref_snapshot){.reg = ZREG_NONE}; +#if ZEND_DEBUG + t->exit_info[exit_point].filename = __zend_filename; + t->exit_info[exit_point].lineno = __zend_lineno; +#endif } return exit_point; @@ -8096,6 +8105,9 @@ static void zend_jit_dump_exit_info(zend_jit_trace_info *t) fprintf(stderr, ":unknown(zval_copy(%s))", zend_reg_name(STACK_REG(stack, j))); } } +#if ZEND_DEBUG + fprintf(stderr, " %s:%d", t->exit_info[i].filename, t->exit_info[i].lineno); +#endif fprintf(stderr, "\n"); } } From 838c437905df9d6bb44846d6391e6a0d1d58314a Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Thu, 11 Sep 2025 12:48:12 +0200 Subject: [PATCH 2/3] Collect filename/lineno only when ZEND_JIT_DEBUG_TRACE_EXIT_INFO flag is set --- ext/opcache/jit/zend_jit_trace.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 933c3fc32dce..3dc04ab6dabf 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -180,8 +180,9 @@ static uint32_t _zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_ && t->exit_info[i].flags == flags && t->exit_info[i].stack_size == stack_size #if ZEND_DEBUG - && strcmp(t->exit_info[i].filename, __zend_filename) == 0 - && t->exit_info[i].lineno == __zend_lineno + && (((JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_EXIT_INFO) == 0) + || (strcmp(t->exit_info[i].filename, __zend_filename) == 0 + && t->exit_info[i].lineno == __zend_lineno)) #endif ) { return i; @@ -208,8 +209,13 @@ static uint32_t _zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_ t->exit_info[exit_point].poly_func = (zend_jit_ref_snapshot){.reg = ZREG_NONE}; t->exit_info[exit_point].poly_this = (zend_jit_ref_snapshot){.reg = ZREG_NONE}; #if ZEND_DEBUG - t->exit_info[exit_point].filename = __zend_filename; - t->exit_info[exit_point].lineno = __zend_lineno; + if ((JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_EXIT_INFO) != 0) { + t->exit_info[exit_point].filename = __zend_filename; + t->exit_info[exit_point].lineno = __zend_lineno; + } else { + t->exit_info[exit_point].filename = NULL; + t->exit_info[exit_point].lineno = 0; + } #endif } @@ -8106,7 +8112,9 @@ static void zend_jit_dump_exit_info(zend_jit_trace_info *t) } } #if ZEND_DEBUG - fprintf(stderr, " %s:%d", t->exit_info[i].filename, t->exit_info[i].lineno); + if ((JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_EXIT_INFO) != 0) { + fprintf(stderr, " %s:%d", t->exit_info[i].filename, t->exit_info[i].lineno); + } #endif fprintf(stderr, "\n"); } From aa646b032fb5ac6b82583b0bc92804f2ef934296 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Mon, 15 Sep 2025 09:10:31 +0200 Subject: [PATCH 3/3] Use a separate flag --- ext/opcache/jit/zend_jit.h | 19 ++++++++++--------- ext/opcache/jit/zend_jit_trace.c | 6 +++--- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/ext/opcache/jit/zend_jit.h b/ext/opcache/jit/zend_jit.h index 5e6b225676aa..9b8e054d2292 100644 --- a/ext/opcache/jit/zend_jit.h +++ b/ext/opcache/jit/zend_jit.h @@ -64,15 +64,16 @@ #define ZEND_JIT_DEBUG_SIZE (1<<9) #define ZEND_JIT_DEBUG_ASM_ADDR (1<<10) -#define ZEND_JIT_DEBUG_TRACE_START (1<<12) -#define ZEND_JIT_DEBUG_TRACE_STOP (1<<13) -#define ZEND_JIT_DEBUG_TRACE_COMPILED (1<<14) -#define ZEND_JIT_DEBUG_TRACE_EXIT (1<<15) -#define ZEND_JIT_DEBUG_TRACE_ABORT (1<<16) -#define ZEND_JIT_DEBUG_TRACE_BLACKLIST (1<<17) -#define ZEND_JIT_DEBUG_TRACE_BYTECODE (1<<18) -#define ZEND_JIT_DEBUG_TRACE_TSSA (1<<19) -#define ZEND_JIT_DEBUG_TRACE_EXIT_INFO (1<<20) +#define ZEND_JIT_DEBUG_TRACE_START (1<<12) +#define ZEND_JIT_DEBUG_TRACE_STOP (1<<13) +#define ZEND_JIT_DEBUG_TRACE_COMPILED (1<<14) +#define ZEND_JIT_DEBUG_TRACE_EXIT (1<<15) +#define ZEND_JIT_DEBUG_TRACE_ABORT (1<<16) +#define ZEND_JIT_DEBUG_TRACE_BLACKLIST (1<<17) +#define ZEND_JIT_DEBUG_TRACE_BYTECODE (1<<18) +#define ZEND_JIT_DEBUG_TRACE_TSSA (1<<19) +#define ZEND_JIT_DEBUG_TRACE_EXIT_INFO (1<<20) +#define ZEND_JIT_DEBUG_TRACE_EXIT_INFO_SRC (1<<21) #define ZEND_JIT_DEBUG_IR_SRC (1<<24) #define ZEND_JIT_DEBUG_IR_FINAL (1<<25) diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 3dc04ab6dabf..21698f71500c 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -180,7 +180,7 @@ static uint32_t _zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_ && t->exit_info[i].flags == flags && t->exit_info[i].stack_size == stack_size #if ZEND_DEBUG - && (((JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_EXIT_INFO) == 0) + && (((JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_EXIT_INFO_SRC) == 0) || (strcmp(t->exit_info[i].filename, __zend_filename) == 0 && t->exit_info[i].lineno == __zend_lineno)) #endif @@ -209,7 +209,7 @@ static uint32_t _zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_ t->exit_info[exit_point].poly_func = (zend_jit_ref_snapshot){.reg = ZREG_NONE}; t->exit_info[exit_point].poly_this = (zend_jit_ref_snapshot){.reg = ZREG_NONE}; #if ZEND_DEBUG - if ((JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_EXIT_INFO) != 0) { + if ((JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_EXIT_INFO_SRC) != 0) { t->exit_info[exit_point].filename = __zend_filename; t->exit_info[exit_point].lineno = __zend_lineno; } else { @@ -8112,7 +8112,7 @@ static void zend_jit_dump_exit_info(zend_jit_trace_info *t) } } #if ZEND_DEBUG - if ((JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_EXIT_INFO) != 0) { + if ((JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_EXIT_INFO_SRC) != 0) { fprintf(stderr, " %s:%d", t->exit_info[i].filename, t->exit_info[i].lineno); } #endif