Commit 915318ed9c5 for php.net
commit 915318ed9c51e9f3e95566f9bf9e14f01744b74b
Author: henderkes <m@pyc.ac>
Date: Thu Jun 11 01:35:26 2026 +0000
make all static extensions use TSRMG_STATIC
Closes GH-22277
diff --git a/NEWS b/NEWS
index 9d38664136a..2462f0a73cc 100644
--- a/NEWS
+++ b/NEWS
@@ -33,6 +33,7 @@ PHP NEWS
. Fixed GH-22422 (zend_arena layout mismatch leaked memory in separately
built extensions under AddressSanitizer). (iliaal)
. TSRM: use local-exec TLS in PIE executables. (henderkes)
+ . perf: make all static extensions use TSRMG_STATIC. (henderkes)
- BCMath:
. Added NUL-byte validation to BCMath functions. (jorgsowa)
diff --git a/UPGRADING b/UPGRADING
index 58bf1f9c9a1..15c1aad15db 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -490,7 +490,7 @@ PHP 8.6 UPGRADE NOTES
. The performance of the TAILCALL VM has been improved.
. The TAILCALL VM is now enabled on Windows when compiling with Clang >= 19
x86_64.
- . The performance of ZTS+PIE builds has been improved.
+ . The performance of ZTS builds has been improved.
- DOM:
. Made splitText() faster and consume less memory.
diff --git a/build/php.m4 b/build/php.m4
index 83375bec5aa..6d9e3e21387 100644
--- a/build/php.m4
+++ b/build/php.m4
@@ -938,10 +938,14 @@ AC_DEFUN([PHP_NEW_EXTENSION],[
ifelse($5,,ac_extra=,[ac_extra=$(echo "m4_normalize(m4_expand([$5]))"|$SED s#@ext_srcdir@#$ext_srcdir#g|$SED s#@ext_builddir@#$ext_builddir#g)])
+ dnl Statically linked extensions share the engine's _tsrm_ls_cache symbol,
+ dnl so in ZTS builds they can read the TSRMLS cache directly.
+ ac_extra_static="$ac_extra -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"
+
if test "$3" != "shared" && test "$3" != "yes" && test "$4" != "cli"; then
dnl ---------------------------------------------- Static module
[PHP_]translit($1,a-z_-,A-Z__)[_SHARED]=no
- PHP_ADD_SOURCES($ext_dir,$2,$ac_extra,)
+ PHP_ADD_SOURCES($ext_dir,$2,$ac_extra_static,)
EXT_STATIC="$EXT_STATIC $1;$ext_dir"
if test "$3" != "nocli"; then
EXT_CLI_STATIC="$EXT_CLI_STATIC $1;$ext_dir"
@@ -962,11 +966,11 @@ dnl ---------------------------------------------- CLI static module
[PHP_]translit($1,a-z_-,A-Z__)[_SHARED]=no
case "$PHP_SAPI" in
cgi|embed|phpdbg[)]
- PHP_ADD_SOURCES($ext_dir,$2,$ac_extra,)
+ PHP_ADD_SOURCES($ext_dir,$2,$ac_extra_static,)
EXT_STATIC="$EXT_STATIC $1;$ext_dir"
;;
*[)]
- PHP_ADD_SOURCES($ext_dir,$2,$ac_extra,cli)
+ PHP_ADD_SOURCES($ext_dir,$2,$ac_extra_static,cli)
;;
esac
EXT_CLI_STATIC="$EXT_CLI_STATIC $1;$ext_dir"
diff --git a/ext/date/config.w32 b/ext/date/config.w32
index b053e27aae3..150fb1498f3 100644
--- a/ext/date/config.w32
+++ b/ext/date/config.w32
@@ -1,6 +1,6 @@
// vim:ft=javascript
-EXTENSION("date", "php_date.c", false, "/Iext/date/lib /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 /DHAVE_TIMELIB_CONFIG_H=1");
+EXTENSION("date", "php_date.c", false, "/Iext/date/lib /DHAVE_TIMELIB_CONFIG_H=1");
PHP_DATE = "yes";
ADD_SOURCES("ext/date/lib", "astro.c timelib.c dow.c parse_date.c parse_posix.c parse_tz.c tm2unixtime.c unixtime2tm.c parse_iso_intervals.c interval.c", "date");
diff --git a/ext/date/config0.m4 b/ext/date/config0.m4
index c78fcb78e15..5018f258ab2 100644
--- a/ext/date/config0.m4
+++ b/ext/date/config0.m4
@@ -9,7 +9,7 @@ AX_CHECK_COMPILE_FLAG([-Wno-implicit-fallthrough],
PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -DHAVE_TIMELIB_CONFIG_H=1"
PHP_TIMELIB_CFLAGS="$PHP_DATE_CFLAGS"
-PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -I@ext_builddir@/lib -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"
+PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -I@ext_builddir@/lib"
AX_CHECK_COMPILE_FLAG([-fwrapv],
[PHP_TIMELIB_CFLAGS="$PHP_TIMELIB_CFLAGS -fwrapv"])
diff --git a/ext/hash/config.m4 b/ext/hash/config.m4
index 2da44c503a6..72b7db8f9de 100644
--- a/ext/hash/config.m4
+++ b/ext/hash/config.m4
@@ -57,7 +57,7 @@ PHP_NEW_EXTENSION([hash], m4_normalize([
murmur/PMurHash128.c
]),
[no],,
- [$PHP_HASH_CFLAGS -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1])
+ [$PHP_HASH_CFLAGS])
PHP_ADD_BUILD_DIR([$ext_builddir/murmur])
AS_VAR_IF([SHA3_DIR],,, [PHP_ADD_BUILD_DIR([$ext_builddir/$SHA3_DIR])])
PHP_INSTALL_HEADERS([ext/hash], m4_normalize([
diff --git a/ext/hash/config.w32 b/ext/hash/config.w32
index e63efcfd84c..347dbddea6b 100644
--- a/ext/hash/config.w32
+++ b/ext/hash/config.w32
@@ -27,7 +27,7 @@ if (!CHECK_HEADER('KeccakHash.h', 'CFLAGS_HASH', hash_sha3_dir)) {
ERROR('Unable to locate SHA3 headers');
}
-ADD_FLAG('CFLAGS_HASH', '/DKeccakP200_excluded /DKeccakP400_excluded /DKeccakP800_excluded /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1');
+ADD_FLAG('CFLAGS_HASH', '/DKeccakP200_excluded /DKeccakP400_excluded /DKeccakP800_excluded');
ADD_SOURCES('ext/hash/murmur', 'PMurHash.c PMurHash128.c', 'hash');
diff --git a/ext/json/config.m4 b/ext/json/config.m4
index 5697dbff8d2..a3ae54a7ac2 100644
--- a/ext/json/config.m4
+++ b/ext/json/config.m4
@@ -4,8 +4,7 @@ PHP_NEW_EXTENSION([json], m4_normalize([
json_scanner.c
json.c
]),
- [no],,
- [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1])
+ [no])
PHP_INSTALL_HEADERS([ext/json], m4_normalize([
php_json_parser.h
php_json_scanner.h
diff --git a/ext/json/config.w32 b/ext/json/config.w32
index 84f77b6f8c9..9d9a37df08a 100644
--- a/ext/json/config.w32
+++ b/ext/json/config.w32
@@ -1,6 +1,6 @@
// vim:ft=javascript
-EXTENSION('json', 'json.c', false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
+EXTENSION('json', 'json.c', false /* never shared */);
PHP_JSON="yes";
ADD_SOURCES(configure_module_dirname, "json_encoder.c json_parser.tab.c json_scanner.c", "json");
diff --git a/ext/lexbor/config.m4 b/ext/lexbor/config.m4
index a75f490e77c..43123578a72 100644
--- a/ext/lexbor/config.m4
+++ b/ext/lexbor/config.m4
@@ -192,7 +192,7 @@ PHP_NEW_EXTENSION([lexbor], m4_normalize([
$LEXBOR_DIR/url/url.c
]),
[no],,
- [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 $PHP_LEXBOR_CFLAGS])
+ [$PHP_LEXBOR_CFLAGS])
PHP_ADD_BUILD_DIR([
$ext_builddir/
diff --git a/ext/lexbor/config.w32 b/ext/lexbor/config.w32
index e75798e0618..403c3b98afb 100644
--- a/ext/lexbor/config.w32
+++ b/ext/lexbor/config.w32
@@ -1,6 +1,6 @@
// vim:ft=javascript
-EXTENSION("lexbor", "php_lexbor.c", false, "/I " + configure_module_dirname + " /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
+EXTENSION("lexbor", "php_lexbor.c", false, "/I " + configure_module_dirname);
PHP_LEXBOR="yes";
ADD_SOURCES("ext/lexbor/lexbor/ports/windows_nt/lexbor/core", "memory.c", "lexbor");
ADD_SOURCES("ext/lexbor/lexbor/core", "array_obj.c array.c avl.c bst.c diyfp.c conv.c dobject.c dtoa.c hash.c mem.c mraw.c plog.c print.c serialize.c shs.c str.c strtod.c", "lexbor");
diff --git a/ext/opcache/config.m4 b/ext/opcache/config.m4
index 70138726c56..3798499a451 100644
--- a/ext/opcache/config.m4
+++ b/ext/opcache/config.m4
@@ -339,7 +339,7 @@ PHP_NEW_EXTENSION([opcache], m4_normalize([
$ZEND_JIT_SRC
]),
[no],,
- [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 $JIT_CFLAGS],,
+ [$JIT_CFLAGS],,
[yes])
PHP_ADD_EXTENSION_DEP(opcache, date)
diff --git a/ext/opcache/config.w32 b/ext/opcache/config.w32
index 397fa1bdd87..1ad346b4da3 100644
--- a/ext/opcache/config.w32
+++ b/ext/opcache/config.w32
@@ -14,7 +14,7 @@ ZEND_EXTENSION('opcache', "\
zend_persist_calc.c \
zend_file_cache.c \
zend_shared_alloc.c \
- shared_alloc_win32.c", false, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
+ shared_alloc_win32.c", false);
ADD_EXTENSION_DEP('opcache', 'date');
ADD_EXTENSION_DEP('opcache', 'hash');
diff --git a/ext/pcre/config.w32 b/ext/pcre/config.w32
index 7c09456b896..93d9df201d5 100644
--- a/ext/pcre/config.w32
+++ b/ext/pcre/config.w32
@@ -1,7 +1,7 @@
// vim:ft=javascript
EXTENSION("pcre", "php_pcre.c", false /* never shared */,
- "-Iext/pcre/pcre2lib -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
+ "-Iext/pcre/pcre2lib");
ADD_SOURCES("ext/pcre/pcre2lib", "pcre2_auto_possess.c pcre2_chartables.c pcre2_compile.c pcre2_config.c pcre2_context.c pcre2_chkdint.c pcre2_dfa_match.c pcre2_error.c pcre2_jit_compile.c pcre2_maketables.c pcre2_match.c pcre2_match_data.c pcre2_newline.c pcre2_ord2utf.c pcre2_pattern_info.c pcre2_serialize.c pcre2_string_utils.c pcre2_study.c pcre2_substitute.c pcre2_substring.c pcre2_tables.c pcre2_ucd.c pcre2_valid_utf.c pcre2_xclass.c pcre2_find_bracket.c pcre2_convert.c pcre2_extuni.c pcre2_script_run.c", "pcre");
ADD_DEF_FILE("ext\\pcre\\php_pcre.def");
diff --git a/ext/pcre/config0.m4 b/ext/pcre/config0.m4
index e71d9a79557..025b54eb780 100644
--- a/ext/pcre/config0.m4
+++ b/ext/pcre/config0.m4
@@ -57,8 +57,7 @@ if test "$PHP_EXTERNAL_PCRE" != "no"; then
PHP_NEW_EXTENSION([pcre],
[php_pcre.c],
- [no],,
- [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1])
+ [no])
PHP_INSTALL_HEADERS([ext/pcre], [php_pcre.h])
else
AC_MSG_CHECKING([for PCRE library to use])
@@ -101,7 +100,6 @@ else
$PHP_PCRE_CFLAGS
-DHAVE_CONFIG_H
-DHAVE_MEMMOVE
- -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1
-I@ext_srcdir@/pcre2lib
"])
diff --git a/ext/random/config.m4 b/ext/random/config.m4
index 484f0549e01..3561d502e70 100644
--- a/ext/random/config.m4
+++ b/ext/random/config.m4
@@ -32,8 +32,7 @@ PHP_NEW_EXTENSION([random], m4_normalize([
randomizer.c
zend_utils.c
]),
- [no],,
- [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1])
+ [no])
PHP_INSTALL_HEADERS([ext/random], m4_normalize([
php_random_csprng.h
php_random_uint128.h
diff --git a/ext/random/config.w32 b/ext/random/config.w32
index bb0badbd183..fa6788803f0 100644
--- a/ext/random/config.w32
+++ b/ext/random/config.w32
@@ -1,4 +1,4 @@
-EXTENSION("random", "random.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
+EXTENSION("random", "random.c", false /* never shared */);
PHP_RANDOM="yes";
ADD_SOURCES(configure_module_dirname, "csprng.c engine_mt19937.c engine_pcgoneseq128xslrr64.c engine_xoshiro256starstar.c engine_secure.c engine_user.c gammasection.c randomizer.c zend_utils.c", "random");
PHP_INSTALL_HEADERS("ext/random", "php_random.h php_random_csprng.h php_random_uint128.h random_decl.h");
diff --git a/ext/reflection/config.m4 b/ext/reflection/config.m4
index 10ce256f01a..cd287c14064 100644
--- a/ext/reflection/config.m4
+++ b/ext/reflection/config.m4
@@ -1,4 +1,3 @@
PHP_NEW_EXTENSION([reflection],
[php_reflection.c],
- [no],,
- [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1])
+ [no])
diff --git a/ext/reflection/config.w32 b/ext/reflection/config.w32
index 7f000b02ab6..f305095405d 100644
--- a/ext/reflection/config.w32
+++ b/ext/reflection/config.w32
@@ -1,4 +1,4 @@
// vim:ft=javascript
-EXTENSION("reflection", "php_reflection.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
+EXTENSION("reflection", "php_reflection.c", false /* never shared */);
PHP_REFLECTION="yes";
diff --git a/ext/spl/config.m4 b/ext/spl/config.m4
index f15e124ba3f..39e320049c3 100644
--- a/ext/spl/config.m4
+++ b/ext/spl/config.m4
@@ -10,8 +10,7 @@ PHP_NEW_EXTENSION([spl], m4_normalize([
spl_iterators.c
spl_observer.c
]),
- [no],,
- [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1])
+ [no])
PHP_INSTALL_HEADERS([ext/spl], m4_normalize([
php_spl.h
spl_array.h
diff --git a/ext/spl/config.w32 b/ext/spl/config.w32
index 06e87c66335..4044e05ecb4 100644
--- a/ext/spl/config.w32
+++ b/ext/spl/config.w32
@@ -1,5 +1,5 @@
// vim:ft=javascript
-EXTENSION("spl", "php_spl.c spl_functions.c spl_iterators.c spl_array.c spl_directory.c spl_exceptions.c spl_observer.c spl_dllist.c spl_heap.c spl_fixedarray.c", false /*never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
+EXTENSION("spl", "php_spl.c spl_functions.c spl_iterators.c spl_array.c spl_directory.c spl_exceptions.c spl_observer.c spl_dllist.c spl_heap.c spl_fixedarray.c", false /*never shared */);
PHP_SPL="yes";
PHP_INSTALL_HEADERS("ext/spl", "php_spl.h spl_array.h spl_directory.h spl_exceptions.h spl_functions.h spl_iterators.h spl_observer.h spl_dllist.h spl_heap.h spl_fixedarray.h");
diff --git a/ext/standard/config.m4 b/ext/standard/config.m4
index 67c36b93ba3..7edfcf1da1f 100644
--- a/ext/standard/config.m4
+++ b/ext/standard/config.m4
@@ -453,8 +453,7 @@ PHP_NEW_EXTENSION([standard], m4_normalize([
versioning.c
$php_ext_standard_sources
]),
- [no],,
- [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1])
+ [no])
PHP_ADD_BUILD_DIR([$ext_builddir/libavifinfo])
diff --git a/ext/standard/config.w32 b/ext/standard/config.w32
index 50031ac3b8a..56096097620 100644
--- a/ext/standard/config.w32
+++ b/ext/standard/config.w32
@@ -36,8 +36,7 @@ EXTENSION("standard", "array.c base64.c basic_functions.c browscap.c \
php_fopen_wrapper.c credits.c css.c var_unserializer.c ftok.c sha1.c \
user_filters.c uuencode.c filters.c proc_open.c password.c \
streamsfuncs.c http.c flock_compat.c hrtime.c",
- false /* never shared */,
- '/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1');
+ false /* never shared */);
ADD_SOURCES("ext/standard/libavifinfo", "avifinfo.c", "standard");
PHP_STANDARD = "yes";
ADD_MAKEFILE_FRAGMENT();
diff --git a/ext/uri/config.m4 b/ext/uri/config.m4
index 31d6c0e10c8..a518cf84b3b 100644
--- a/ext/uri/config.m4
+++ b/ext/uri/config.m4
@@ -39,7 +39,7 @@ else
PHP_EVAL_INCLINE([$LIBURIPARSER_CFLAGS])
fi
-PHP_NEW_EXTENSION(uri, [php_uri.c php_uri_common.c uri_parser_rfc3986.c uri_parser_whatwg.c uri_parser_php_parse_url.c $URIPARSER_SOURCES], [no],,[$URI_CFLAGS -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1])
+PHP_NEW_EXTENSION(uri, [php_uri.c php_uri_common.c uri_parser_rfc3986.c uri_parser_whatwg.c uri_parser_php_parse_url.c $URIPARSER_SOURCES], [no],,[$URI_CFLAGS])
PHP_ADD_EXTENSION_DEP(uri, lexbor)
if test "$PHP_EXTERNAL_URIPARSER" = "no"; then
diff --git a/ext/uri/config.w32 b/ext/uri/config.w32
index 2bed937a737..597ffb9fa03 100644
--- a/ext/uri/config.w32
+++ b/ext/uri/config.w32
@@ -1,4 +1,4 @@
-EXTENSION("uri", "php_uri.c php_uri_common.c uri_parser_rfc3986.c uri_parser_whatwg.c uri_parser_php_parse_url.c", false /* never shared */, "/I ext/lexbor /I ext/uri/uriparser/include /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
+EXTENSION("uri", "php_uri.c php_uri_common.c uri_parser_rfc3986.c uri_parser_whatwg.c uri_parser_php_parse_url.c", false /* never shared */, "/I ext/lexbor /I ext/uri/uriparser/include");
AC_DEFINE("URI_ENABLE_ANSI", 1, "Define to 1 for enabling ANSI support of uriparser.")
AC_DEFINE("URI_NO_UNICODE", 1, "Define to 1 for disabling unicode support of uriparser.")
diff --git a/win32/build/confutils.js b/win32/build/confutils.js
index b7289bbcb27..3751101daa4 100644
--- a/win32/build/confutils.js
+++ b/win32/build/confutils.js
@@ -1494,6 +1494,9 @@ function EXTENSION(extname, file_list, shared, cflags, dllname, obj_dir)
ADD_FLAG("CFLAGS_PHP", "/D COMPILE_DL_" + EXT);
} else {
STDOUT.WriteLine("Enabling extension " + extname_for_printing);
+ /* Statically linked extensions share the engine's _tsrm_ls_cache symbol,
+ * so in ZTS builds they can read the TSRMLS cache directly. */
+ cflags = "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 " + cflags;
}
MFO.WriteBlankLines(1);