From 2207da9fce658530a7e46f0b1048bd22cf9ceec3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 18 Nov 2024 23:36:36 +0000 Subject: [PATCH 1/3] Fixed JIT startup failure not being respected by new threads in ZTS --- ext/opcache/ZendAccelerator.c | 1 + ext/opcache/jit/zend_jit.c | 4 +++- ext/opcache/jit/zend_jit.h | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 9bcd035c35295..9d43f3a3d2b52 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -3278,6 +3278,7 @@ static zend_result accel_post_startup(void) || zend_jit_startup(ZSMMG(reserved), jit_size, reattached) != SUCCESS) { JIT_G(enabled) = false; JIT_G(on) = false; + zend_jit_startup_failed = true; /* The JIT is implicitly disabled with opcache.jit_buffer_size=0, so we don't want to * emit a warning here. */ if (JIT_G(buffer_size) != 0) { diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 4e1c8e290bb32..1b1991215496e 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -103,6 +103,8 @@ typedef struct _zend_jit_stub { #define JIT_STUB(name, offset, adjustment) \ {JIT_STUB_PREFIX #name, zend_jit_ ## name ## _stub, offset, adjustment} +bool zend_jit_startup_failed = false; + zend_ulong zend_jit_profile_counter = 0; int zend_jit_profile_counter_rid = -1; @@ -4796,7 +4798,7 @@ ZEND_EXT_API int zend_jit_config(zend_string *jit, int stage) return FAILURE; } - if (zend_string_equals_literal_ci(jit, "disable")) { + if (zend_jit_startup_failed || zend_string_equals_literal_ci(jit, "disable")) { JIT_G(enabled) = 0; JIT_G(on) = 0; return SUCCESS; diff --git a/ext/opcache/jit/zend_jit.h b/ext/opcache/jit/zend_jit.h index d22422181af9c..84130e11b8f7c 100644 --- a/ext/opcache/jit/zend_jit.h +++ b/ext/opcache/jit/zend_jit.h @@ -91,6 +91,8 @@ typedef struct _zend_jit_trace_rec zend_jit_trace_rec; typedef struct _zend_jit_trace_stack_frame zend_jit_trace_stack_frame; typedef struct _sym_node zend_sym_node; +extern bool zend_jit_startup_failed; + typedef struct _zend_jit_globals { bool enabled; bool on; From 59dda863738753349d3ab4a50862b64c6b76e57f Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 Nov 2024 11:50:12 +0000 Subject: [PATCH 2/3] Alternative fix that should cover all cases there doesn't seem to be a thread post-startup hook that runs after zend_startup_cb() that could be used for this this fix is similar to accel_startup_ok() as seen here: https://github.com/php/php-src/blob/fc1db70f106525e81f9a24539340b7cf2e82e844/ext/opcache/ZendAccelerator.c#L2631-L2634 --- ext/opcache/jit/zend_jit.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 1b1991215496e..6ecd63e2829ed 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -4798,7 +4798,7 @@ ZEND_EXT_API int zend_jit_config(zend_string *jit, int stage) return FAILURE; } - if (zend_jit_startup_failed || zend_string_equals_literal_ci(jit, "disable")) { + if (zend_string_equals_literal_ci(jit, "disable")) { JIT_G(enabled) = 0; JIT_G(on) = 0; return SUCCESS; @@ -5098,6 +5098,13 @@ static void zend_jit_reset_counters(void) ZEND_EXT_API void zend_jit_activate(void) { +#ifdef ZTS + if (zend_jit_startup_failed) { + JIT_G(enabled) = 0; + JIT_G(on) = 0; + return; + } +#endif zend_jit_profile_counter = 0; if (JIT_G(on)) { if (JIT_G(trigger) == ZEND_JIT_ON_HOT_COUNTERS) { From 975cbda17698cb3906533dbbcc6c1a6360ec9e9d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 19 Nov 2024 18:29:32 +0000 Subject: [PATCH 3/3] Flip zend_jit_startup_failed -> zend_jit_startup_ok --- ext/opcache/ZendAccelerator.c | 3 ++- ext/opcache/jit/zend_jit.c | 4 ++-- ext/opcache/jit/zend_jit.h | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 9d43f3a3d2b52..1afcff2d1c243 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -3278,12 +3278,13 @@ static zend_result accel_post_startup(void) || zend_jit_startup(ZSMMG(reserved), jit_size, reattached) != SUCCESS) { JIT_G(enabled) = false; JIT_G(on) = false; - zend_jit_startup_failed = true; /* The JIT is implicitly disabled with opcache.jit_buffer_size=0, so we don't want to * emit a warning here. */ if (JIT_G(buffer_size) != 0) { zend_accel_error(ACCEL_LOG_WARNING, "Could not enable JIT!"); } + } else { + zend_jit_startup_ok = true; } } #endif diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 6ecd63e2829ed..8e81e187ec628 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -103,7 +103,7 @@ typedef struct _zend_jit_stub { #define JIT_STUB(name, offset, adjustment) \ {JIT_STUB_PREFIX #name, zend_jit_ ## name ## _stub, offset, adjustment} -bool zend_jit_startup_failed = false; +bool zend_jit_startup_ok = false; zend_ulong zend_jit_profile_counter = 0; int zend_jit_profile_counter_rid = -1; @@ -5099,7 +5099,7 @@ static void zend_jit_reset_counters(void) ZEND_EXT_API void zend_jit_activate(void) { #ifdef ZTS - if (zend_jit_startup_failed) { + if (!zend_jit_startup_ok) { JIT_G(enabled) = 0; JIT_G(on) = 0; return; diff --git a/ext/opcache/jit/zend_jit.h b/ext/opcache/jit/zend_jit.h index 84130e11b8f7c..f0a6a81cf6ca9 100644 --- a/ext/opcache/jit/zend_jit.h +++ b/ext/opcache/jit/zend_jit.h @@ -91,7 +91,7 @@ typedef struct _zend_jit_trace_rec zend_jit_trace_rec; typedef struct _zend_jit_trace_stack_frame zend_jit_trace_stack_frame; typedef struct _sym_node zend_sym_node; -extern bool zend_jit_startup_failed; +extern bool zend_jit_startup_ok; typedef struct _zend_jit_globals { bool enabled;