From abb2385e7c856d1fc4119d54f2025afe964f8e41 Mon Sep 17 00:00:00 2001 From: henderkes Date: Sat, 7 Nov 2026 16:43:00 +0700 Subject: [PATCH 1/2] Move remaining fast globals to native TLS --- UPGRADING.INTERNALS | 4 ++++ Zend/zend.c | 3 ++- Zend/zend_globals_macros.h | 8 ++++++-- Zend/zend_ini_scanner.l | 2 +- Zend/zend_signal.c | 5 +++-- Zend/zend_signal.h | 8 ++++++-- Zend/zend_virtual_cwd.c | 7 ++++--- Zend/zend_virtual_cwd.h | 10 +++++++--- ext/opcache/ZendAccelerator.c | 7 ++++--- ext/opcache/ZendAccelerator.h | 10 +++++++--- ext/opcache/jit/zend_jit.c | 7 ++++--- ext/opcache/jit/zend_jit.h | 10 +++++++--- main/SAPI.c | 5 +++-- main/SAPI.h | 8 ++++++-- main/main.c | 23 +++++------------------ main/php_globals.h | 8 ++++++-- 16 files changed, 75 insertions(+), 50 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index c94b605c5c96..e9ae569a884d 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -53,6 +53,10 @@ PHP 8.7 INTERNALS UPGRADE NOTES freed with zend_hash_destroy() + pefree(). - The ZTS symbols compiler_globals_offset and executor_globals_offset have been removed: CG()/EG() now reach the globals through a __thread struct. +- PG(), SG(), CWDG(), SIGG(), ZCG(), JIT_G() and INI_SCNG() use native TLS. + The core_globals_offset, sapi_globals_offset, cwd_globals_offset, + zend_signal_globals_offset, accel_globals_offset, jit_globals_offset and + ini_scanner_globals_offset symbols have been removed. - Removed zend_error_noreturn_unchecked(). ======================== diff --git a/Zend/zend.c b/Zend/zend.c index 3e489d8d3804..e27cfd1db2fc 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -58,6 +58,7 @@ ZEND_TLS_API TSRM_TLS TSRM_TLS_MODEL_ATTR zend_tsrm_ls_cache _tsrm_ls_cache = {0 static void *executor_globals_tls_addr(void) { return &_tsrm_ls_cache.eg; } static void *compiler_globals_tls_addr(void) { return &_tsrm_ls_cache.cg; } static void *language_scanner_globals_tls_addr(void) { return &language_scanner_globals; } +static void *ini_scanner_globals_tls_addr(void) { return &ini_scanner_globals; } static HashTable *global_function_table = NULL; static HashTable *global_class_table = NULL; static HashTable *global_constants_table = NULL; @@ -1034,7 +1035,7 @@ void zend_startup(zend_utility_functions *utility_functions) /* {{{ */ ts_allocate_tls_id(&compiler_globals_id, compiler_globals_tls_addr, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor); ts_allocate_tls_id(&executor_globals_id, executor_globals_tls_addr, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor); ts_allocate_tls_id(&language_scanner_globals_id, language_scanner_globals_tls_addr, sizeof(zend_php_scanner_globals), (ts_allocate_ctor) php_scanner_globals_ctor, NULL); - ts_allocate_fast_id(&ini_scanner_globals_id, &ini_scanner_globals_offset, sizeof(zend_ini_scanner_globals), (ts_allocate_ctor) ini_scanner_globals_ctor, NULL); + ts_allocate_tls_id(&ini_scanner_globals_id, ini_scanner_globals_tls_addr, sizeof(zend_ini_scanner_globals), (ts_allocate_ctor) ini_scanner_globals_ctor, NULL); compiler_globals = ts_resource(compiler_globals_id); executor_globals = ts_resource(executor_globals_id); diff --git a/Zend/zend_globals_macros.h b/Zend/zend_globals_macros.h index 684ed696adf1..6c6135405fb4 100644 --- a/Zend/zend_globals_macros.h +++ b/Zend/zend_globals_macros.h @@ -67,9 +67,13 @@ extern ZEND_API zend_php_scanner_globals language_scanner_globals; /* INI Scanner */ #ifdef ZTS -# define INI_SCNG(v) ZEND_TSRMG_FAST(ini_scanner_globals_offset, zend_ini_scanner_globals *, v) extern ZEND_API ts_rsrc_id ini_scanner_globals_id; -extern ZEND_API size_t ini_scanner_globals_offset; +# ifdef ZEND_TLS_DIRECT +extern ZEND_TLS_API TSRM_TLS TSRM_TLS_MODEL_ATTR zend_ini_scanner_globals ini_scanner_globals; +# define INI_SCNG(v) (ini_scanner_globals.v) +# else +# define INI_SCNG(v) ZEND_TSRMG(ini_scanner_globals_id, zend_ini_scanner_globals *, v) +# endif #else # define INI_SCNG(v) (ini_scanner_globals.v) extern ZEND_API zend_ini_scanner_globals ini_scanner_globals; diff --git a/Zend/zend_ini_scanner.l b/Zend/zend_ini_scanner.l index e837ce85c1d1..02ecd60858d0 100644 --- a/Zend/zend_ini_scanner.l +++ b/Zend/zend_ini_scanner.l @@ -103,7 +103,7 @@ #define SCNG INI_SCNG #ifdef ZTS ZEND_API ts_rsrc_id ini_scanner_globals_id; -ZEND_API size_t ini_scanner_globals_offset; +ZEND_TLS_API TSRM_TLS TSRM_TLS_MODEL_ATTR zend_ini_scanner_globals ini_scanner_globals; #else ZEND_API zend_ini_scanner_globals ini_scanner_globals; #endif diff --git a/Zend/zend_signal.c b/Zend/zend_signal.c index 2e4b398aa965..9acd59a5579c 100644 --- a/Zend/zend_signal.c +++ b/Zend/zend_signal.c @@ -43,7 +43,8 @@ #ifdef ZTS ZEND_API int zend_signal_globals_id; -ZEND_API size_t zend_signal_globals_offset; +ZEND_TLS_API TSRM_TLS TSRM_TLS_MODEL_ATTR zend_signal_globals_t zend_signal_globals; +static void *zend_signal_globals_tls_addr(void) { return &zend_signal_globals; } #else ZEND_API zend_signal_globals_t zend_signal_globals; #endif /* not ZTS */ @@ -412,7 +413,7 @@ ZEND_API void zend_signal_startup(void) { #ifdef ZTS - ts_allocate_fast_id(&zend_signal_globals_id, &zend_signal_globals_offset, sizeof(zend_signal_globals_t), (ts_allocate_ctor) zend_signal_globals_ctor, NULL); + ts_allocate_tls_id(&zend_signal_globals_id, zend_signal_globals_tls_addr, sizeof(zend_signal_globals_t), (ts_allocate_ctor) zend_signal_globals_ctor, NULL); #else zend_signal_globals_ctor(&zend_signal_globals); #endif diff --git a/Zend/zend_signal.h b/Zend/zend_signal.h index 973f0c302b21..171c40a483f4 100644 --- a/Zend/zend_signal.h +++ b/Zend/zend_signal.h @@ -62,10 +62,14 @@ typedef struct _zend_signal_globals_t { } zend_signal_globals_t; # ifdef ZTS -# define SIGG(v) ZEND_TSRMG_FAST(zend_signal_globals_offset, zend_signal_globals_t *, v) BEGIN_EXTERN_C() ZEND_API extern int zend_signal_globals_id; -ZEND_API extern size_t zend_signal_globals_offset; +# ifdef ZEND_TLS_DIRECT +# define SIGG(v) (zend_signal_globals.v) +extern ZEND_TLS_API TSRM_TLS TSRM_TLS_MODEL_ATTR zend_signal_globals_t zend_signal_globals; +# else +# define SIGG(v) ZEND_TSRMG(zend_signal_globals_id, zend_signal_globals_t *, v) +# endif END_EXTERN_C() # else # define SIGG(v) (zend_signal_globals.v) diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index 03dffa633c5b..a9d13e0068ea 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -81,8 +81,9 @@ MUTEX_T cwd_mutex; #endif #ifdef ZTS -ts_rsrc_id cwd_globals_id; -size_t cwd_globals_offset; +CWD_API ts_rsrc_id cwd_globals_id; +ZEND_TLS_API TSRM_TLS TSRM_TLS_MODEL_ATTR virtual_cwd_globals cwd_globals; +static void *cwd_globals_tls_addr(void) { return &cwd_globals; } #else virtual_cwd_globals cwd_globals; #endif @@ -204,7 +205,7 @@ CWD_API void virtual_cwd_startup(void) /* {{{ */ { virtual_cwd_main_cwd_init(0); #ifdef ZTS - ts_allocate_fast_id(&cwd_globals_id, &cwd_globals_offset, sizeof(virtual_cwd_globals), (ts_allocate_ctor) cwd_globals_ctor, (ts_allocate_dtor) cwd_globals_dtor); + ts_allocate_tls_id(&cwd_globals_id, cwd_globals_tls_addr, sizeof(virtual_cwd_globals), (ts_allocate_ctor) cwd_globals_ctor, (ts_allocate_dtor) cwd_globals_dtor); #else cwd_globals_ctor(&cwd_globals); #endif diff --git a/Zend/zend_virtual_cwd.h b/Zend/zend_virtual_cwd.h index ad30c0323892..ae51701fe0b3 100644 --- a/Zend/zend_virtual_cwd.h +++ b/Zend/zend_virtual_cwd.h @@ -242,9 +242,13 @@ typedef struct _virtual_cwd_globals { } virtual_cwd_globals; #ifdef ZTS -extern ts_rsrc_id cwd_globals_id; -extern size_t cwd_globals_offset; -# define CWDG(v) ZEND_TSRMG_FAST(cwd_globals_offset, virtual_cwd_globals *, v) +extern CWD_API ts_rsrc_id cwd_globals_id; +# ifdef ZEND_TLS_DIRECT +# define CWDG(v) (cwd_globals.v) +extern ZEND_TLS_API TSRM_TLS TSRM_TLS_MODEL_ATTR virtual_cwd_globals cwd_globals; +# else +# define CWDG(v) ZEND_TSRMG(cwd_globals_id, virtual_cwd_globals *, v) +# endif #else extern virtual_cwd_globals cwd_globals; # define CWDG(v) (cwd_globals.v) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 7ea59be43821..a2067fa74368 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -107,8 +107,9 @@ static zend_extension opcache_extension_entry; #ifndef ZTS zend_accel_globals accel_globals; #else -int accel_globals_id; -size_t accel_globals_offset; +ZEND_API int accel_globals_id; +ZEND_TLS_API TSRM_TLS TSRM_TLS_MODEL_ATTR zend_accel_globals accel_globals; +static void *accel_globals_tls_addr(void) { return &accel_globals; } #endif /* Points to the structure shared across all PHP processes */ @@ -3426,7 +3427,7 @@ void start_accel_extension(void) static int accel_startup(zend_extension *extension) { #ifdef ZTS - accel_globals_id = ts_allocate_fast_id(&accel_globals_id, &accel_globals_offset, sizeof(zend_accel_globals), (ts_allocate_ctor) accel_globals_ctor, (ts_allocate_dtor) accel_globals_dtor); + accel_globals_id = ts_allocate_tls_id(&accel_globals_id, accel_globals_tls_addr, sizeof(zend_accel_globals), (ts_allocate_ctor) accel_globals_ctor, (ts_allocate_dtor) accel_globals_dtor); #else accel_globals_ctor(&accel_globals); #endif diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index 1eedee04f02b..13f3c2fae667 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -308,9 +308,13 @@ extern zend_accel_shared_globals *accel_shared_globals; #define ZCSG(element) (accel_shared_globals->element) #ifdef ZTS -# define ZCG(v) ZEND_TSRMG_FAST(accel_globals_offset, zend_accel_globals *, v) -extern int accel_globals_id; -extern size_t accel_globals_offset; +extern ZEND_API int accel_globals_id; +# ifdef ZEND_TLS_DIRECT +# define ZCG(v) (accel_globals.v) +extern ZEND_TLS_API TSRM_TLS TSRM_TLS_MODEL_ATTR zend_accel_globals accel_globals; +# else +# define ZCG(v) ZEND_TSRMG(accel_globals_id, zend_accel_globals *, v) +# endif #else # define ZCG(v) (accel_globals.v) extern zend_accel_globals accel_globals; diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 47921d5a7104..1809bc355018 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -47,8 +47,9 @@ #endif #ifdef ZTS -int jit_globals_id; -size_t jit_globals_offset; +ZEND_API int jit_globals_id; +ZEND_TLS_API TSRM_TLS TSRM_TLS_MODEL_ATTR zend_jit_globals jit_globals; +static void *jit_globals_tls_addr(void) { return &jit_globals; } #else zend_jit_globals jit_globals; #endif @@ -3770,7 +3771,7 @@ int zend_jit_debug_config(zend_long old_val, zend_long new_val, int stage) void zend_jit_init(void) { #ifdef ZTS - jit_globals_id = ts_allocate_fast_id(&jit_globals_id, &jit_globals_offset, sizeof(zend_jit_globals), (ts_allocate_ctor) zend_jit_globals_ctor, (ts_allocate_dtor) zend_jit_globals_dtor); + jit_globals_id = ts_allocate_tls_id(&jit_globals_id, jit_globals_tls_addr, sizeof(zend_jit_globals), (ts_allocate_ctor) zend_jit_globals_ctor, (ts_allocate_dtor) zend_jit_globals_dtor); #else zend_jit_globals_ctor(&jit_globals); #endif diff --git a/ext/opcache/jit/zend_jit.h b/ext/opcache/jit/zend_jit.h index 44d0b4eaf2aa..437e07ccf3cd 100644 --- a/ext/opcache/jit/zend_jit.h +++ b/ext/opcache/jit/zend_jit.h @@ -151,9 +151,13 @@ typedef struct _zend_jit_globals { } zend_jit_globals; #ifdef ZTS -# define JIT_G(v) ZEND_TSRMG_FAST(jit_globals_offset, zend_jit_globals *, v) -extern int jit_globals_id; -extern size_t jit_globals_offset; +extern ZEND_API int jit_globals_id; +# ifdef ZEND_TLS_DIRECT +# define JIT_G(v) (jit_globals.v) +extern ZEND_TLS_API TSRM_TLS TSRM_TLS_MODEL_ATTR zend_jit_globals jit_globals; +# else +# define JIT_G(v) ZEND_TSRMG(jit_globals_id, zend_jit_globals *, v) +# endif #else # define JIT_G(v) (jit_globals.v) extern zend_jit_globals jit_globals; diff --git a/main/SAPI.c b/main/SAPI.c index 6b9ef7bf1a3e..c3a729d7c0f5 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -37,7 +37,8 @@ #ifdef ZTS SAPI_API int sapi_globals_id; -SAPI_API size_t sapi_globals_offset; +ZEND_TLS_API TSRM_TLS TSRM_TLS_MODEL_ATTR sapi_globals_struct sapi_globals; +static void *sapi_globals_tls_addr(void) { return &sapi_globals; } #else sapi_globals_struct sapi_globals; #endif @@ -69,7 +70,7 @@ SAPI_API void sapi_startup(sapi_module_struct *sf) sapi_module = *sf; #ifdef ZTS - ts_allocate_fast_id(&sapi_globals_id, &sapi_globals_offset, sizeof(sapi_globals_struct), (ts_allocate_ctor) sapi_globals_ctor, (ts_allocate_dtor) sapi_globals_dtor); + ts_allocate_tls_id(&sapi_globals_id, sapi_globals_tls_addr, sizeof(sapi_globals_struct), (ts_allocate_ctor) sapi_globals_ctor, (ts_allocate_dtor) sapi_globals_dtor); # ifdef PHP_WIN32 _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); # endif diff --git a/main/SAPI.h b/main/SAPI.h index 3d7f662b30f4..95a0b86341e4 100644 --- a/main/SAPI.h +++ b/main/SAPI.h @@ -149,9 +149,13 @@ typedef struct _sapi_globals_struct { BEGIN_EXTERN_C() #ifdef ZTS -# define SG(v) ZEND_TSRMG_FAST(sapi_globals_offset, sapi_globals_struct *, v) SAPI_API extern int sapi_globals_id; -SAPI_API extern size_t sapi_globals_offset; +# ifdef ZEND_TLS_DIRECT +# define SG(v) (sapi_globals.v) +extern ZEND_TLS_API TSRM_TLS TSRM_TLS_MODEL_ATTR sapi_globals_struct sapi_globals; +# else +# define SG(v) ZEND_TSRMG(sapi_globals_id, sapi_globals_struct *, v) +# endif #else # define SG(v) (sapi_globals.v) extern SAPI_API sapi_globals_struct sapi_globals; diff --git a/main/main.c b/main/main.c index a8cdff9ff688..4c14090bca56 100644 --- a/main/main.c +++ b/main/main.c @@ -96,7 +96,8 @@ PHPAPI int (*php_register_internal_extensions_func)(void) = php_register_interna php_core_globals core_globals; #else PHPAPI int core_globals_id; -PHPAPI size_t core_globals_offset; +ZEND_TLS_API TSRM_TLS TSRM_TLS_MODEL_ATTR php_core_globals core_globals; +static void *core_globals_tls_addr(void) { return &core_globals; } #endif #define SAFE_FILENAME(f) ((f)?(f):"-") @@ -2214,7 +2215,7 @@ zend_result php_module_startup(sapi_module_struct *sf, zend_module_entry *additi php_output_startup(); #ifdef ZTS - ts_allocate_fast_id(&core_globals_id, &core_globals_offset, sizeof(php_core_globals), (ts_allocate_ctor) core_globals_ctor, (ts_allocate_dtor) core_globals_dtor); + ts_allocate_tls_id(&core_globals_id, core_globals_tls_addr, sizeof(php_core_globals), (ts_allocate_ctor) core_globals_ctor, (ts_allocate_dtor) core_globals_dtor); #ifdef PHP_WIN32 ts_allocate_id(&php_win32_core_globals_id, sizeof(php_win32_core_globals), (ts_allocate_ctor) php_win32_core_globals_ctor, (ts_allocate_dtor) php_win32_core_globals_dtor); #endif @@ -2797,22 +2798,8 @@ PHPAPI zend_result php_lint_script(zend_file_handle *file) /* {{{ php_reserve_tsrm_memory */ PHPAPI void php_reserve_tsrm_memory(void) { - /* CG/EG/GC globals live in native __thread storage and need no - * reserved TSRM space. */ - tsrm_reserve( - TSRM_ALIGNED_SIZE(sizeof(zend_ini_scanner_globals)) + - TSRM_ALIGNED_SIZE(sizeof(virtual_cwd_globals)) + -#ifdef ZEND_SIGNALS - TSRM_ALIGNED_SIZE(sizeof(zend_signal_globals_t)) + -#endif - TSRM_ALIGNED_SIZE(sizeof(php_core_globals)) + - TSRM_ALIGNED_SIZE(sizeof(sapi_globals_struct)) + - TSRM_ALIGNED_SIZE(sizeof(zend_accel_globals)) + -#ifdef HAVE_JIT - TSRM_ALIGNED_SIZE(sizeof(zend_jit_globals)) + -#endif - 0 - ); + /* Core fast globals use native TLS and need no reserved TSRM space. */ + tsrm_reserve(0); } /* }}} */ diff --git a/main/php_globals.h b/main/php_globals.h index e3cfe38a63fd..6bfdef2b9d1a 100644 --- a/main/php_globals.h +++ b/main/php_globals.h @@ -22,9 +22,13 @@ typedef struct _php_core_globals php_core_globals; #ifdef ZTS -# define PG(v) ZEND_TSRMG_FAST(core_globals_offset, php_core_globals *, v) extern PHPAPI int core_globals_id; -extern PHPAPI size_t core_globals_offset; +# ifdef ZEND_TLS_DIRECT +# define PG(v) (core_globals.v) +extern ZEND_TLS_API TSRM_TLS TSRM_TLS_MODEL_ATTR php_core_globals core_globals; +# else +# define PG(v) ZEND_TSRMG(core_globals_id, php_core_globals *, v) +# endif #else # define PG(v) (core_globals.v) extern ZEND_API struct _php_core_globals core_globals; From aa2898d1496b123c494f4a256cb9434574998401 Mon Sep 17 00:00:00 2001 From: henderkes Date: Sat, 7 Nov 2026 17:18:17 +0700 Subject: [PATCH 2/2] remove php_reserve_tsrm_memory --- UPGRADING.INTERNALS | 1 + main/main.c | 9 --------- main/php_main.h | 1 - 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index e9ae569a884d..4391e78e7479 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -57,6 +57,7 @@ PHP 8.7 INTERNALS UPGRADE NOTES The core_globals_offset, sapi_globals_offset, cwd_globals_offset, zend_signal_globals_offset, accel_globals_offset, jit_globals_offset and ini_scanner_globals_offset symbols have been removed. +- php_reserve_tsrm_memory() has been removed. - Removed zend_error_noreturn_unchecked(). ======================== diff --git a/main/main.c b/main/main.c index 4c14090bca56..1bda5e59ce9b 100644 --- a/main/main.c +++ b/main/main.c @@ -2795,18 +2795,9 @@ PHPAPI zend_result php_lint_script(zend_file_handle *file) /* }}} */ #ifdef ZTS -/* {{{ php_reserve_tsrm_memory */ -PHPAPI void php_reserve_tsrm_memory(void) -{ - /* Core fast globals use native TLS and need no reserved TSRM space. */ - tsrm_reserve(0); -} -/* }}} */ - PHPAPI bool php_tsrm_startup_ex(int expected_threads) { bool ret = tsrm_startup(expected_threads, 1, 0, NULL); - php_reserve_tsrm_memory(); (void)ts_resource(0); return ret; } diff --git a/main/php_main.h b/main/php_main.h index de2ace1c25ed..aa5e579257ab 100644 --- a/main/php_main.h +++ b/main/php_main.h @@ -72,7 +72,6 @@ extern int php_init_environ(void); extern int php_shutdown_environ(void); #ifdef ZTS -PHPAPI void php_reserve_tsrm_memory(void); PHPAPI bool php_tsrm_startup_ex(int expected_threads); PHPAPI bool php_tsrm_startup(void);