From 21679865b116f348dc5e3d0079028186f144976a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 9 Dec 2024 17:50:17 +0300 Subject: [PATCH 01/11] Preallocate space for Win64 shadow args Otherwise "fixed_call_stack" doesn't make sense --- ext/opcache/jit/zend_jit_ir.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 4087f294db8c6..3eca617941ade 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -39,6 +39,7 @@ (1<<(16+6)) | (1<<(16+7)) | (1<<(16+8)) | (1<<(16+9)) | (1<<(16+10)) | \ (1<<(16+11)) | (1<<(16+12)) | (1<<(16+13)) | (1<<(16+14)) | (1<<(16+15))) */ +# define IR_SHADOW_ARGS 32 # else # define IR_REGSET_PRESERVED ((1<<3) | (1<<5) | (1<<12) | (1<<13) | (1<<14) | (1<<15)) /* all preserved registers */ # endif @@ -2709,7 +2710,11 @@ static void zend_jit_init_ctx(zend_jit_ctx *jit, uint32_t flags) // jit->ctx.fixed_save_regset &= 0xffff; // TODO: don't save FP registers ??? //#endif } +#ifdef _WIN64 + jit->ctx.fixed_call_stack_size = 16 + IR_SHADOW_ARGS; +#else jit->ctx.fixed_call_stack_size = 16; +#endif } else { #ifdef ZEND_VM_HYBRID_JIT_RED_ZONE_SIZE jit->ctx.fixed_stack_red_zone = ZEND_VM_HYBRID_JIT_RED_ZONE_SIZE; @@ -8978,7 +8983,11 @@ static int zend_jit_init_method_call(zend_jit_ctx *jit, // JIT: alloca(sizeof(void*)); this_ref2 = ir_ALLOCA(ir_CONST_ADDR(0x10)); } else { +#ifdef _WIN64 + this_ref2 = ir_HARD_COPY_A(jit_ADD_OFFSET(jit, ir_RLOAD_A(IR_REG_SP), IR_SHADOW_ARGS)); +#else this_ref2 = ir_HARD_COPY_A(ir_RLOAD_A(IR_REG_SP)); +#endif } ir_STORE(this_ref2, this_ref); @@ -8994,10 +9003,17 @@ static int zend_jit_init_method_call(zend_jit_ctx *jit, this_ref2); } - this_ref2 = ir_LOAD_A(ir_RLOAD_A(IR_REG_SP)); + if (!jit->ctx.fixed_call_stack_size) { + this_ref2 = ir_LOAD_A(ir_RLOAD_A(IR_REG_SP)); // JIT: revert alloca ir_AFREE(ir_CONST_ADDR(0x10)); + } else { +#ifdef _WIN64 + this_ref2 = ir_LOAD_A(jit_ADD_OFFSET(jit, ir_RLOAD_A(IR_REG_SP), IR_SHADOW_ARGS)); +#else + this_ref2 = ir_LOAD_A(ir_RLOAD_A(IR_REG_SP)); +#endif } ir_GUARD(ref2, jit_STUB_ADDR(jit, jit_stub_exception_handler)); @@ -10257,7 +10273,11 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen // JIT: alloca(sizeof(void*)); ptr = ir_ALLOCA(ir_CONST_ADDR(sizeof(zval))); } else { +#ifdef _WIN64 + ptr = ir_HARD_COPY_A(jit_ADD_OFFSET(jit, ir_RLOAD_A(IR_REG_SP), IR_SHADOW_ARGS)); +#else ptr = ir_HARD_COPY_A(ir_RLOAD_A(IR_REG_SP)); +#endif } res_addr = ZEND_ADDR_REF_ZVAL(ptr); } @@ -10385,7 +10405,16 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen func_info |= MAY_BE_NULL; if (func_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) { - ir_ref sp = ir_RLOAD_A(IR_REG_SP); + ir_ref sp; + if (!jit->ctx.fixed_call_stack_size) { + sp = ir_RLOAD_A(IR_REG_SP); + } else { +#ifdef _WIN32 + sp = jit_ADD_OFFSET(jit, ir_RLOAD_A(IR_REG_SP), IR_SHADOW_ARGS); +#else + sp = ir_RLOAD_A(IR_REG_SP); +#endif + } res_addr = ZEND_ADDR_REF_ZVAL(sp); jit_ZVAL_PTR_DTOR(jit, res_addr, func_info, 1, opline); } From 8c69cf00751be3b67a0a648edfff509af87fc5af Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 9 Dec 2024 18:14:32 +0300 Subject: [PATCH 02/11] typo --- ext/opcache/jit/zend_jit_ir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 3eca617941ade..ab183e44115b1 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -10409,7 +10409,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen if (!jit->ctx.fixed_call_stack_size) { sp = ir_RLOAD_A(IR_REG_SP); } else { -#ifdef _WIN32 +#ifdef _WIN64 sp = jit_ADD_OFFSET(jit, ir_RLOAD_A(IR_REG_SP), IR_SHADOW_ARGS); #else sp = ir_RLOAD_A(IR_REG_SP); From 1ed53204f0d29327bebea4228b65fdc670cff5f2 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 11 Dec 2024 17:19:06 +0300 Subject: [PATCH 03/11] Setup unwinder for JIT functions This is not a general solution. It works while all the JIT-ed functions have the same "fixed stack frame". Unwinder uses hard-coded unwind data this "fixed dtack frame". --- ext/opcache/jit/zend_jit_ir.c | 61 +++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index ab183e44115b1..090736ec282dc 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -3213,6 +3213,63 @@ static zend_never_inline void zend_jit_set_sp_adj_vm(void) } #endif +#ifdef _WIN64 +/* + * We use a single unwind entry for the whole JIT buffer. + * This works, because all the JIT-ed PHP functions have the same "fixed stack frame". + */ +static PRUNTIME_FUNCTION zend_jit_uw_func = NULL; + +#ifdef ZEND_JIT_RT_UNWINDER +static PRUNTIME_FUNCTION zend_jit_unwind_callback(DWORD64 pc, PVOID context) +{ + return zend_jit_uw_func; +} +#endif + +static void zend_jit_setup_unwinder(void) +{ + /* Hardcoded SEH unwinf data for JIT-ed PHP functions with "fixed stack frame" */ + static const unsigned char uw_data[] = { + 0x01, // UBYTE: 3 Version , UBYTE: 5 Flags + 0x10, // UBYTE Size of prolog + 0x09, // UBYTE Count of unwind codes + 0x00, // UBYTE: 4 Frame Register, UBYTE: 4 Frame Register offset (scaled) + // USHORT * n Unwind codes array + 0x10, 0x82, // c: subq $0x48, %rsp + 0x0c, 0xf0, // a: pushq %r15 + 0x0a, 0xe0, // 8: pushq %r14 + 0x08, 0xd0, // 6: pushq %r13 + 0x06, 0xc0, // 4: pushq %r12 + 0x04, 0x70, // 3: pushq %rdi + 0x03, 0x60, // 2: pushq %rsi + 0x02, 0x50, // 1: pushq %rbp + 0x01, 0x30, // 0: pushq %rbx + }; + + zend_jit_uw_func = (PRUNTIME_FUNCTION)*dasm_ptr; + *dasm_ptr = (char*)*dasm_ptr + ZEND_MM_ALIGNED_SIZE_EX(sizeof(RUNTIME_FUNCTION) + sizeof(uw_data), 16); + + zend_jit_uw_func->BeginAddress = 0; + zend_jit_uw_func->EndAddress = (uintptr_t)dasm_end - (uintptr_t)dasm_buf; + zend_jit_uw_func->UnwindData = (uintptr_t)zend_jit_uw_func + sizeof(RUNTIME_FUNCTION) - (uintptr_t)dasm_buf; + memcpy((char*)zend_jit_uw_func + sizeof(RUNTIME_FUNCTION), uw_data, sizeof(uw_data)); + +#ifdef ZEND_JIT_RT_UNWINDER + RtlInstallFunctionTableCallback( + (uintptr_t)dasm_buf | 3, + (uintptr_t) dasm_buf, + (uintptr_t)dasm_end - (uintptr_t)dasm_buf, + zend_jit_unwind_callback, + NULL, + NULL); +#else + RtlAddFunctionTable(zend_jit_uw_func, 1, (uintptr_t)dasm_buf); +#endif +} +#endif + + static void zend_jit_setup(void) { #if defined(IR_TARGET_X86) @@ -3420,6 +3477,10 @@ static void zend_jit_setup(void) zend_jit_calc_trace_prologue_size(); zend_jit_setup_stubs(); JIT_G(debug) = debug; + +#ifdef _WIN64 + zend_jit_setup_unwinder(); +#endif } static void zend_jit_shutdown_ir(void) From 3dbe5ebb5edde5679a5c737660b5a4a3e90929c3 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 11 Dec 2024 21:12:55 +0300 Subject: [PATCH 04/11] Revert "Dynamically xfail test case which fails on CI" This reverts commit 7cc327fd5ad78ccc640d635c5dc6a16d8240d28f. --- Zend/tests/gh16508.phpt | 11 +++++++++++ Zend/tests/gh16509.phpt | 11 ----------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Zend/tests/gh16508.phpt b/Zend/tests/gh16508.phpt index e5b89b6029040..954d60e93d623 100644 --- a/Zend/tests/gh16508.phpt +++ b/Zend/tests/gh16508.phpt @@ -2,6 +2,17 @@ GH-16508: Missing lineno in inheritance errors of delayed early bound classes --EXTENSIONS-- opcache +--SKIPIF-- + --INI-- opcache.enable_cli=1 --FILE-- diff --git a/Zend/tests/gh16509.phpt b/Zend/tests/gh16509.phpt index 0a71a095cf3c9..6ba724ae1d548 100644 --- a/Zend/tests/gh16509.phpt +++ b/Zend/tests/gh16509.phpt @@ -1,16 +1,5 @@ --TEST-- GH-16509: Incorrect lineno reported for function redeclaration ---SKIPIF-- - --FILE-- Date: Wed, 11 Dec 2024 21:13:05 +0300 Subject: [PATCH 05/11] Revert "Dynamically xfail test case which fails on CI" This reverts commit bdde797159efeb1c4fadc4e45e43fc03d9e7278a. --- Zend/tests/gh16508.phpt | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Zend/tests/gh16508.phpt b/Zend/tests/gh16508.phpt index 954d60e93d623..e5b89b6029040 100644 --- a/Zend/tests/gh16508.phpt +++ b/Zend/tests/gh16508.phpt @@ -2,17 +2,6 @@ GH-16508: Missing lineno in inheritance errors of delayed early bound classes --EXTENSIONS-- opcache ---SKIPIF-- - --INI-- opcache.enable_cli=1 --FILE-- From 330d639e5aa8a40947ec0bcf9357caea9b4ad963 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 11 Dec 2024 21:13:10 +0300 Subject: [PATCH 06/11] Revert "Dynamically xfail test cases which fail on CI (GH-15710)" This reverts commit 6d5962074f60b401ab5797333c00d292f36f3d90. --- Zend/tests/bug54268.phpt | 8 -------- Zend/tests/gh9407.phpt | 11 ----------- Zend/tests/stack_limit/stack_limit_014.phpt | 8 -------- ext/spl/tests/gh14639.phpt | 8 -------- tests/lang/bug45392.phpt | 8 -------- 5 files changed, 43 deletions(-) diff --git a/Zend/tests/bug54268.phpt b/Zend/tests/bug54268.phpt index e0a1b8b1bc824..3567aaa6ee570 100644 --- a/Zend/tests/bug54268.phpt +++ b/Zend/tests/bug54268.phpt @@ -8,14 +8,6 @@ $zend_mm_enabled = getenv("USE_ZEND_ALLOC"); if ($zend_mm_enabled === "0") { die("skip Zend MM disabled"); } -$tracing = extension_loaded("Zend OPcache") - && ($conf = opcache_get_configuration()["directives"]) - && array_key_exists("opcache.jit", $conf) - && $conf["opcache.jit"] === "tracing"; -if (PHP_OS_FAMILY === "Windows" && PHP_INT_SIZE == 8 && $tracing) { - $url = "https://github.com/php/php-src/issues/15709"; - die("xfail Test fails on Windows x64 (VS17) and tracing JIT; see $url"); -} ?> --FILE-- --FILE-- --EXTENSIONS-- zend_test diff --git a/ext/spl/tests/gh14639.phpt b/ext/spl/tests/gh14639.phpt index 520ee20839c28..1b6f621d27bd3 100644 --- a/ext/spl/tests/gh14639.phpt +++ b/ext/spl/tests/gh14639.phpt @@ -7,14 +7,6 @@ memory_limit=2M if (getenv("USE_ZEND_ALLOC") === "0") { die("skip Zend MM disabled"); } -$tracing = extension_loaded("Zend OPcache") - && ($conf = opcache_get_configuration()["directives"]) - && array_key_exists("opcache.jit", $conf) - && $conf["opcache.jit"] === "tracing"; -if (PHP_OS_FAMILY === "Windows" && PHP_INT_SIZE == 8 && $tracing) { - $url = "https://github.com/php/php-src/pull/14919#issuecomment-2259003979"; - die("xfail Test fails on Windows x64 (VS17) and tracing JIT; see $url"); -} ?> --FILE-- --FILE-- Date: Wed, 11 Dec 2024 21:20:09 +0300 Subject: [PATCH 07/11] Remove XFAIL sections --- Zend/tests/gh8841.phpt | 11 ----------- Zend/tests/traits/bugs/gh13177.phpt | 11 ----------- 2 files changed, 22 deletions(-) diff --git a/Zend/tests/gh8841.phpt b/Zend/tests/gh8841.phpt index 9133fd4d4aec9..5587c5ad8227e 100644 --- a/Zend/tests/gh8841.phpt +++ b/Zend/tests/gh8841.phpt @@ -1,16 +1,5 @@ --TEST-- GH-8841 (php-cli core dump calling a badly formed function) ---SKIPIF-- - --FILE-- --FILE-- Date: Thu, 12 Dec 2024 02:13:12 +0300 Subject: [PATCH 08/11] Add hard-coded SEH unwind data for EXITCALL --- ext/opcache/jit/zend_jit_ir.c | 43 +++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 090736ec282dc..bb5536121bb30 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -3233,7 +3233,7 @@ static void zend_jit_setup_unwinder(void) static const unsigned char uw_data[] = { 0x01, // UBYTE: 3 Version , UBYTE: 5 Flags 0x10, // UBYTE Size of prolog - 0x09, // UBYTE Count of unwind codes + 0x0a, // UBYTE Count of unwind codes 0x00, // UBYTE: 4 Frame Register, UBYTE: 4 Frame Register offset (scaled) // USHORT * n Unwind codes array 0x10, 0x82, // c: subq $0x48, %rsp @@ -3245,15 +3245,44 @@ static void zend_jit_setup_unwinder(void) 0x03, 0x60, // 2: pushq %rsi 0x02, 0x50, // 1: pushq %rbp 0x01, 0x30, // 0: pushq %rbx + 0x00, 0x00, + }; + static const unsigned char uw_data_exitcall[] = { + 0x01, // UBYTE: 3 Version , UBYTE: 5 Flags + 0x10, // UBYTE Size of prolog + 0x0a, // UBYTE Count of unwind codes + 0x00, // UBYTE: 4 Frame Register, UBYTE: 4 Frame Register offset (scaled) + // USHORT * n Unwind codes array + 0x10, 0x01, 0x2f, 0x00, // c: subq 376, %rsp ; 0x48 + 32+16*8+16*8+8+8 + 0x0c, 0xf0, // a: pushq %r15 + 0x0a, 0xe0, // 8: pushq %r14 + 0x08, 0xd0, // 6: pushq %r13 + 0x06, 0xc0, // 4: pushq %r12 + 0x04, 0x70, // 3: pushq %rdi + 0x03, 0x60, // 2: pushq %rsi + 0x02, 0x50, // 1: pushq %rbp + 0x01, 0x30, // 0: pushq %rbx }; zend_jit_uw_func = (PRUNTIME_FUNCTION)*dasm_ptr; - *dasm_ptr = (char*)*dasm_ptr + ZEND_MM_ALIGNED_SIZE_EX(sizeof(RUNTIME_FUNCTION) + sizeof(uw_data), 16); + *dasm_ptr = (char*)*dasm_ptr + ZEND_MM_ALIGNED_SIZE_EX(sizeof(RUNTIME_FUNCTION) * 4 + + sizeof(uw_data) + sizeof(uw_data_exitcall) + sizeof(uw_data), 16); + + zend_jit_uw_func[0].BeginAddress = 0; + zend_jit_uw_func[1].BeginAddress = (uintptr_t)zend_jit_stub_handlers[jit_stub_trace_exit] - (uintptr_t)dasm_buf; + zend_jit_uw_func[2].BeginAddress = (uintptr_t)zend_jit_stub_handlers[jit_stub_undefined_offset] - (uintptr_t)dasm_buf; + + zend_jit_uw_func[0].EndAddress = zend_jit_uw_func[1].BeginAddress; + zend_jit_uw_func[1].EndAddress = zend_jit_uw_func[2].BeginAddress; + zend_jit_uw_func[2].EndAddress = (uintptr_t)dasm_end - (uintptr_t)dasm_buf; + + zend_jit_uw_func[0].UnwindData = (uintptr_t)zend_jit_uw_func - (uintptr_t)dasm_buf + sizeof(RUNTIME_FUNCTION) * 4; + zend_jit_uw_func[1].UnwindData = zend_jit_uw_func[0].UnwindData + sizeof(uw_data); + zend_jit_uw_func[2].UnwindData = zend_jit_uw_func[1].UnwindData + sizeof(uw_data_exitcall); - zend_jit_uw_func->BeginAddress = 0; - zend_jit_uw_func->EndAddress = (uintptr_t)dasm_end - (uintptr_t)dasm_buf; - zend_jit_uw_func->UnwindData = (uintptr_t)zend_jit_uw_func + sizeof(RUNTIME_FUNCTION) - (uintptr_t)dasm_buf; - memcpy((char*)zend_jit_uw_func + sizeof(RUNTIME_FUNCTION), uw_data, sizeof(uw_data)); + memcpy((char*)dasm_buf + zend_jit_uw_func[0].UnwindData, uw_data, sizeof(uw_data)); + memcpy((char*)dasm_buf + zend_jit_uw_func[1].UnwindData, uw_data_exitcall, sizeof(uw_data_exitcall)); + memcpy((char*)dasm_buf + zend_jit_uw_func[2].UnwindData, uw_data, sizeof(uw_data)); #ifdef ZEND_JIT_RT_UNWINDER RtlInstallFunctionTableCallback( @@ -3264,7 +3293,7 @@ static void zend_jit_setup_unwinder(void) NULL, NULL); #else - RtlAddFunctionTable(zend_jit_uw_func, 1, (uintptr_t)dasm_buf); + RtlAddFunctionTable(zend_jit_uw_func, 3, (uintptr_t)dasm_buf); #endif } #endif From b9244a0ebfb88ee2bdc5820a9ec4390286c8e0e8 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 12 Dec 2024 10:29:55 +0300 Subject: [PATCH 09/11] Fix unwind data --- ext/opcache/jit/zend_jit_ir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index bb5536121bb30..09d2da78027a2 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -3233,7 +3233,7 @@ static void zend_jit_setup_unwinder(void) static const unsigned char uw_data[] = { 0x01, // UBYTE: 3 Version , UBYTE: 5 Flags 0x10, // UBYTE Size of prolog - 0x0a, // UBYTE Count of unwind codes + 0x09, // UBYTE Count of unwind codes 0x00, // UBYTE: 4 Frame Register, UBYTE: 4 Frame Register offset (scaled) // USHORT * n Unwind codes array 0x10, 0x82, // c: subq $0x48, %rsp From 3c88fb9a1b88504a8e5d365f69260cbb11c02697 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 12 Dec 2024 11:02:40 +0300 Subject: [PATCH 10/11] Fix Windows multi-process support --- ext/opcache/jit/zend_jit.c | 6 ++++-- ext/opcache/jit/zend_jit_ir.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 558faae22d0a0..21870089e484a 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -3628,9 +3628,11 @@ void zend_jit_startup(void *buf, size_t size, bool reattached) } zend_jit_unprotect(); - zend_jit_setup(); + zend_jit_setup(reattached); zend_jit_protect(); - zend_jit_init_handlers(); + if (!reattached) { + zend_jit_init_handlers(); + } zend_jit_trace_startup(reattached); diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 09d2da78027a2..8209353452366 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -3299,7 +3299,7 @@ static void zend_jit_setup_unwinder(void) #endif -static void zend_jit_setup(void) +static void zend_jit_setup(bool reattached) { #if defined(IR_TARGET_X86) if (!zend_cpu_supports_sse2()) { @@ -3504,7 +3504,9 @@ static void zend_jit_setup(void) } zend_jit_calc_trace_prologue_size(); - zend_jit_setup_stubs(); + if (!reattached) { + zend_jit_setup_stubs(); + } JIT_G(debug) = debug; #ifdef _WIN64 From 3280df4ab111df9ac648ee3b677e557df3ca30fd Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 13 Dec 2024 02:02:09 +0300 Subject: [PATCH 11/11] Typo --- ext/opcache/jit/zend_jit_ir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 8209353452366..843d3ae90d84c 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -3229,7 +3229,7 @@ static PRUNTIME_FUNCTION zend_jit_unwind_callback(DWORD64 pc, PVOID context) static void zend_jit_setup_unwinder(void) { - /* Hardcoded SEH unwinf data for JIT-ed PHP functions with "fixed stack frame" */ + /* Hardcoded SEH unwind data for JIT-ed PHP functions with "fixed stack frame" */ static const unsigned char uw_data[] = { 0x01, // UBYTE: 3 Version , UBYTE: 5 Flags 0x10, // UBYTE Size of prolog