From 33ae76405fcad4b5b545d03cbe4f4754007490c2 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 26 Apr 2025 14:30:59 +0200 Subject: [PATCH] Use zend_string for arg_separators This allows us to avoid a call to `zend_ini_str` which took 6% of the profile on my i7-4790 for a call to `http_build_query`. Now we can just grab the value from the globals. In other files this can avoid some length recomputations. --- UPGRADING.INTERNALS | 4 ++++ ext/mbstring/mb_gpc.c | 2 +- ext/mbstring/mbstring.c | 2 +- ext/standard/http.c | 2 +- ext/standard/url_scanner_ex.re | 14 +++++++------- main/main.c | 4 ++-- main/php_globals.h | 4 ++-- main/php_variables.c | 2 +- sapi/cgi/cgi_main.c | 4 ++-- 9 files changed, 21 insertions(+), 17 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 2ed9c251052..4516cb2c688 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -14,6 +14,10 @@ PHP 8.5 INTERNALS UPGRADE NOTES 1. Internal API changes ======================== +- Core + . PG(arg_separator).input and PG(arg_separator).output are now `zend_string*` + instead of `char*`. + - Zend . Added zend_safe_assign_to_variable_noref() function to safely assign a value to a non-reference zval. diff --git a/ext/mbstring/mb_gpc.c b/ext/mbstring/mb_gpc.c index f90d86974fb..5851cf1dd4e 100644 --- a/ext/mbstring/mb_gpc.c +++ b/ext/mbstring/mb_gpc.c @@ -100,7 +100,7 @@ MBSTRING_API SAPI_TREAT_DATA_FUNC(mbstr_treat_data) case PARSE_POST: case PARSE_GET: case PARSE_STRING: - separator = (char *) estrdup(PG(arg_separator).input); + separator = (char *) estrndup(ZSTR_VAL(PG(arg_separator).input), ZSTR_LEN(PG(arg_separator).input)); break; case PARSE_COOKIE: separator = ";\0"; diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 7f0cbaeb346..cbed77a2713 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -1537,7 +1537,7 @@ PHP_FUNCTION(mb_parse_str) encstr = estrndup(encstr, encstr_len); info.data_type = PARSE_STRING; - info.separator = PG(arg_separator).input; + info.separator = ZSTR_VAL(PG(arg_separator).input); info.report_errors = true; info.to_encoding = MBSTRG(current_internal_encoding); info.from_encodings = MBSTRG(http_input_list); diff --git a/ext/standard/http.c b/ext/standard/http.c index 5411fb3a862..c9dfb5220a6 100644 --- a/ext/standard/http.c +++ b/ext/standard/http.c @@ -124,7 +124,7 @@ PHPAPI void php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, } if (!arg_sep) { - arg_sep = zend_ini_str("arg_separator.output", strlen("arg_separator.output"), false); + arg_sep = PG(arg_separator).output; if (ZSTR_LEN(arg_sep) == 0) { arg_sep = ZSTR_CHAR('&'); } diff --git a/ext/standard/url_scanner_ex.re b/ext/standard/url_scanner_ex.re index 1ce7521d7fa..e3c4477cde3 100644 --- a/ext/standard/url_scanner_ex.re +++ b/ext/standard/url_scanner_ex.re @@ -188,7 +188,7 @@ alphadash = ([a-zA-Z] | "-"); #define YYLIMIT q #define YYMARKER r -static inline void append_modified_url(smart_str *url, smart_str *dest, smart_str *url_app, const char *separator, int type) +static inline void append_modified_url(smart_str *url, smart_str *dest, smart_str *url_app, const zend_string *separator, int type) { php_url *url_parts; @@ -271,7 +271,7 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st smart_str_appendc(dest, '?'); if (url_parts->query) { smart_str_appends(dest, ZSTR_VAL(url_parts->query)); - smart_str_appends(dest, separator); + smart_str_append(dest, separator); smart_str_append_smart_str(dest, url_app); } else { smart_str_append_smart_str(dest, url_app); @@ -757,7 +757,7 @@ static inline void php_url_scanner_add_var_impl(const char *name, size_t name_le } if (url_state->url_app.s && ZSTR_LEN(url_state->url_app.s) != 0) { - smart_str_appends(&url_state->url_app, PG(arg_separator).output); + smart_str_append(&url_state->url_app, PG(arg_separator).output); } if (encode) { @@ -902,9 +902,9 @@ static inline zend_result php_url_scanner_reset_var_impl(zend_string *name, int /* Get end of url var */ limit = ZSTR_VAL(url_state->url_app.s) + ZSTR_LEN(url_state->url_app.s); end = start + ZSTR_LEN(url_app.s); - separator_len = strlen(PG(arg_separator).output); + separator_len = ZSTR_LEN(PG(arg_separator).output); while (end < limit) { - if (!memcmp(end, PG(arg_separator).output, separator_len)) { + if (!memcmp(end, ZSTR_VAL(PG(arg_separator).output), separator_len)) { end += separator_len; sep_removed = 1; break; @@ -918,8 +918,8 @@ static inline zend_result php_url_scanner_reset_var_impl(zend_string *name, int } /* Check preceding separator */ if (!sep_removed - && (size_t)(start - PG(arg_separator).output) >= separator_len - && !memcmp(start - separator_len, PG(arg_separator).output, separator_len)) { + && (size_t)(start - ZSTR_VAL(PG(arg_separator).output)) >= separator_len + && !memcmp(start - separator_len, ZSTR_VAL(PG(arg_separator).output), separator_len)) { start -= separator_len; } /* Remove partially */ diff --git a/main/main.c b/main/main.c index 50894939782..18c8e2dfac7 100644 --- a/main/main.c +++ b/main/main.c @@ -771,8 +771,8 @@ PHP_INI_BEGIN() STD_PHP_INI_ENTRY("unserialize_callback_func", NULL, PHP_INI_ALL, OnUpdateString, unserialize_callback_func, php_core_globals, core_globals) STD_PHP_INI_ENTRY("serialize_precision", "-1", PHP_INI_ALL, OnSetSerializePrecision, serialize_precision, php_core_globals, core_globals) - STD_PHP_INI_ENTRY("arg_separator.output", "&", PHP_INI_ALL, OnUpdateStringUnempty, arg_separator.output, php_core_globals, core_globals) - STD_PHP_INI_ENTRY("arg_separator.input", "&", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateStringUnempty, arg_separator.input, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("arg_separator.output", "&", PHP_INI_ALL, OnUpdateStrNotEmpty, arg_separator.output, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("arg_separator.input", "&", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateStrNotEmpty, arg_separator.input, php_core_globals, core_globals) STD_PHP_INI_ENTRY("auto_append_file", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateString, auto_append_file, php_core_globals, core_globals) STD_PHP_INI_ENTRY("auto_prepend_file", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateString, auto_prepend_file, php_core_globals, core_globals) diff --git a/main/php_globals.h b/main/php_globals.h index b2f2696c2db..ab7a9a00b2f 100644 --- a/main/php_globals.h +++ b/main/php_globals.h @@ -48,8 +48,8 @@ extern ZEND_API struct _php_core_globals core_globals; struct _php_tick_function_entry; typedef struct _arg_separators { - char *output; - char *input; + zend_string *output; + zend_string *input; } arg_separators; struct _php_core_globals { diff --git a/main/php_variables.c b/main/php_variables.c index 7569fd43e90..b81c049f6c5 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -527,7 +527,7 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) switch (arg) { case PARSE_GET: case PARSE_STRING: - separator = PG(arg_separator).input; + separator = ZSTR_VAL(PG(arg_separator).input); break; case PARSE_COOKIE: separator = ";\0"; diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 392a95d25ea..e3cd6f49b9f 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -2420,7 +2420,7 @@ do_repeat: * test.php v1=test "v2=hello world!" */ if (!SG(request_info).query_string && argc > php_optind) { - size_t slen = strlen(PG(arg_separator).input); + size_t slen = ZSTR_LEN(PG(arg_separator).input); len = 0; for (i = php_optind; i < argc; i++) { if (i < (argc - 1)) { @@ -2436,7 +2436,7 @@ do_repeat: for (i = php_optind; i < argc; i++) { strlcat(s, argv[i], len); if (i < (argc - 1)) { - strlcat(s, PG(arg_separator).input, len); + strlcat(s, ZSTR_VAL(PG(arg_separator).input), len); } } SG(request_info).query_string = s;