From 03a37de9b3c4b9dc02aeeb5c5331ff89eac62515 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 26 Dec 2013 14:47:13 +0400 Subject: [PATCH] Improved empty string handling. Now ZE uses an interned string instead of allocation new empty string each time. (Some extensions might need to be fixed using str_efree() instead of efree() to support interned strings). --- NEWS | 2 ++ Zend/zend.h | 4 ++++ Zend/zend_compile.c | 4 ++-- Zend/zend_extensions.h | 2 +- Zend/zend_globals.h | 3 +++ Zend/zend_modules.h | 2 +- Zend/zend_string.c | 2 ++ ext/opcache/ZendAccelerator.c | 3 +++ ext/session/mod_user_class.c | 2 +- ext/session/session.c | 4 ++-- ext/spl/spl_iterators.c | 2 +- 11 files changed, 22 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 536ab75ada..384faecfba 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ PHP NEWS - Core: . Improved IS_VAR operands fetching. (Laruence, Dmitry) + . Improved empty string handling. Now ZE uses an interned string instead of + allocation new empty string each time. (Laruence, Dmitry) . Implemented internal operator overloading (RFC: https://wiki.php.net/rfc/operator_overloading_gmp). (Nikita) . Made calls from incompatible context issue an E_DEPRECATED warning instead diff --git a/Zend/zend.h b/Zend/zend.h index 3ac559e05c..cb55871342 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -680,7 +680,11 @@ END_EXTERN_C() #define STR_FREE(ptr) if (ptr) { str_efree(ptr); } #define STR_FREE_REL(ptr) if (ptr) { str_efree_rel(ptr); } +#ifndef ZTS +#define STR_EMPTY_ALLOC() CG(interned_empty_string)? CG(interned_empty_string) : estrndup("", sizeof("")-1) +#else #define STR_EMPTY_ALLOC() estrndup("", sizeof("")-1) +#endif #define STR_REALLOC(ptr, size) \ ptr = (char *) erealloc(ptr, size); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index c61f3a26f6..a0ea594560 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2461,14 +2461,14 @@ void zend_do_build_full_name(znode *result, znode *prefix, znode *name, int is_c if (is_class_member) { length = sizeof("::")-1 + Z_STRLEN(result->u.constant) + Z_STRLEN(name->u.constant); - Z_STRVAL(result->u.constant) = erealloc(Z_STRVAL(result->u.constant), length+1); + Z_STRVAL(result->u.constant) = str_erealloc(Z_STRVAL(result->u.constant), length+1); memcpy(&Z_STRVAL(result->u.constant)[Z_STRLEN(result->u.constant)], "::", sizeof("::")-1); memcpy(&Z_STRVAL(result->u.constant)[Z_STRLEN(result->u.constant) + sizeof("::")-1], Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant)+1); str_efree(Z_STRVAL(name->u.constant)); Z_STRLEN(result->u.constant) = length; } else { length = sizeof("\\")-1 + Z_STRLEN(result->u.constant) + Z_STRLEN(name->u.constant); - Z_STRVAL(result->u.constant) = erealloc(Z_STRVAL(result->u.constant), length+1); + Z_STRVAL(result->u.constant) = str_erealloc(Z_STRVAL(result->u.constant), length+1); memcpy(&Z_STRVAL(result->u.constant)[Z_STRLEN(result->u.constant)], "\\", sizeof("\\")-1); memcpy(&Z_STRVAL(result->u.constant)[Z_STRLEN(result->u.constant) + sizeof("\\")-1], Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant)+1); str_efree(Z_STRVAL(name->u.constant)); diff --git a/Zend/zend_extensions.h b/Zend/zend_extensions.h index e59c9ade8b..44e516a37e 100644 --- a/Zend/zend_extensions.h +++ b/Zend/zend_extensions.h @@ -28,7 +28,7 @@ /* The first number is the engine version and the rest is the date. * This way engine 2/3 API no. is always greater than engine 1 API no.. */ -#define ZEND_EXTENSION_API_NO 220131107 +#define ZEND_EXTENSION_API_NO 220131226 typedef struct _zend_extension_version_info { int zend_extension_api_no; diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 27d471fa06..363f4ee7cb 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -146,6 +146,9 @@ struct _zend_compiler_globals { char *interned_strings_end; char *interned_strings_top; char *interned_strings_snapshot_top; +#ifndef ZTS + char *interned_empty_string; +#endif HashTable interned_strings; diff --git a/Zend/zend_modules.h b/Zend/zend_modules.h index 00209a0ddc..6be24f25eb 100644 --- a/Zend/zend_modules.h +++ b/Zend/zend_modules.h @@ -33,7 +33,7 @@ #define ZEND_MODULE_INFO_FUNC_ARGS zend_module_entry *zend_module TSRMLS_DC #define ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU zend_module TSRMLS_CC -#define ZEND_MODULE_API_NO 20131106 +#define ZEND_MODULE_API_NO 20131226 #ifdef ZTS #define USING_ZTS 1 #else diff --git a/Zend/zend_string.c b/Zend/zend_string.c index ff7ee3fd81..6ecb42b7ac 100644 --- a/Zend/zend_string.c +++ b/Zend/zend_string.c @@ -61,6 +61,8 @@ void zend_interned_strings_init(TSRMLS_D) mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ); #endif + /* interned empty string */ + CG(interned_empty_string) = zend_new_interned_string_int("", sizeof(""), 0 TSRMLS_CC); #endif zend_new_interned_string = zend_new_interned_string_int; diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index ac6ee1e0bd..e12f0b981a 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -387,6 +387,9 @@ static void accel_use_shm_interned_strings(TSRMLS_D) { Bucket *p, *q; + /* empty string */ + CG(interned_empty_string) = accel_new_interned_string("", sizeof(""), 0 TSRMLS_CC); + /* function table hash keys */ p = CG(function_table)->pListHead; while (p) { diff --git a/ext/session/mod_user_class.c b/ext/session/mod_user_class.c index ea53af9ebe..3f97f7c830 100644 --- a/ext/session/mod_user_class.c +++ b/ext/session/mod_user_class.c @@ -86,7 +86,7 @@ PHP_METHOD(SessionHandler, read) } RETVAL_STRINGL(val, val_len, 1); - efree(val); + str_efree(val); return; } /* }}} */ diff --git a/ext/session/session.c b/ext/session/session.c index 5b4820a65c..a3d565d895 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -513,9 +513,9 @@ static void php_session_initialize(TSRMLS_D) /* {{{ */ PHP_MD5Final(PS(session_data_hash), &context); php_session_decode(val, vallen TSRMLS_CC); - efree(val); + str_efree(val); } else { - memset(PS(session_data_hash),'\0', 16); + memset(PS(session_data_hash),'\0', 16); } if (!PS(use_cookies) && PS(send_cookie)) { diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 30532756cb..b79312e019 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -2059,7 +2059,7 @@ SPL_METHOD(RegexIterator, accept) } if (use_copy) { - efree(subject); + str_efree(subject); } } /* }}} */ -- 2.40.0