From: Dmitry Stogov Date: Thu, 16 Apr 2015 11:45:08 +0000 (+0300) Subject: Changed zend_smart_str allocation granularity to do the better job together with... X-Git-Tag: PRE_PHP7_NSAPI_REMOVAL~261 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e38ed4c28ffe56f910626870667b374ac5ad1481;p=php Changed zend_smart_str allocation granularity to do the better job together with Zend MM and avoid useless calls to erealloc(). The actual reallocation routiones are seprated from inlined code to reduce code size. --- diff --git a/Zend/Makefile.am b/Zend/Makefile.am index fedbffe4ce..5f7f25df67 100644 --- a/Zend/Makefile.am +++ b/Zend/Makefile.am @@ -18,7 +18,7 @@ libZend_la_SOURCES=\ zend_default_classes.c \ zend_iterators.c zend_interfaces.c zend_exceptions.c \ zend_strtod.c zend_closures.c zend_float.c zend_string.c zend_signal.c \ - zend_generators.c zend_virtual_cwd.c zend_ast.c + zend_generators.c zend_virtual_cwd.c zend_ast.c zend_smart_str.c libZend_la_CFLAGS = -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 libZend_la_LDFLAGS = diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 6701ca4902..16fd42e80f 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -287,16 +287,6 @@ struct _zend_mm_bin { char bytes[ZEND_MM_PAGE_SIZE * 8]; }; -#if ZEND_DEBUG -typedef struct _zend_mm_debug_info { - size_t size; - const char *filename; - const char *orig_filename; - uint lineno; - uint orig_lineno; -} zend_mm_debug_info; -#endif - struct _zend_mm_free_slot { zend_mm_free_slot *next_free_slot; }; diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h index 6d89884f0d..0cb3a71d34 100644 --- a/Zend/zend_alloc.h +++ b/Zend/zend_alloc.h @@ -50,6 +50,20 @@ typedef struct _zend_leak_info { uint orig_lineno; } zend_leak_info; +#if ZEND_DEBUG +typedef struct _zend_mm_debug_info { + size_t size; + const char *filename; + const char *orig_filename; + uint lineno; + uint orig_lineno; +} zend_mm_debug_info; + +# define ZEND_MM_OVERHEAD ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)) +#else +# define ZEND_MM_OVERHEAD 0 +#endif + BEGIN_EXTERN_C() ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length) ZEND_ATTRIBUTE_MALLOC; diff --git a/Zend/zend_smart_str.c b/Zend/zend_smart_str.c new file mode 100644 index 0000000000..d0d3689cd0 --- /dev/null +++ b/Zend/zend_smart_str.c @@ -0,0 +1,61 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 7 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2015 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Dmitry Stogov | + +----------------------------------------------------------------------+ + */ + +#include +#include "zend_smart_str_public.h" + +#define SMART_STR_OVERHEAD (ZEND_MM_OVERHEAD + _STR_HEADER_SIZE) + +#ifndef SMART_STR_PAGE +# define SMART_STR_PAGE 4096 +#endif + +#ifndef SMART_STR_START_SIZE +# define SMART_STR_START_SIZE (256 - SMART_STR_OVERHEAD - 1) +#endif + +#define SMART_STR_NEW_SIZE(len) \ + (((len + SMART_STR_OVERHEAD + SMART_STR_PAGE) & ~(SMART_STR_PAGE - 1)) - SMART_STR_OVERHEAD - 1) + +ZEND_API void ZEND_FASTCALL smart_str_erealloc(smart_str *str, size_t len) +{ + if (UNEXPECTED(!str->s)) { + str->a = len < SMART_STR_START_SIZE + ? SMART_STR_START_SIZE + : SMART_STR_NEW_SIZE(len); + str->s = zend_string_alloc(str->a, 0); + str->s->len = 0; + } else { + str->a = SMART_STR_NEW_SIZE(len); + str->s = (zend_string *) erealloc2(str->s, _STR_HEADER_SIZE + str->a + 1, _STR_HEADER_SIZE + str->s->len + 1); + } +} + +ZEND_API void ZEND_FASTCALL smart_str_realloc(smart_str *str, size_t len) +{ + if (UNEXPECTED(!str->s)) { + str->a = len < SMART_STR_START_SIZE + ? SMART_STR_START_SIZE + : SMART_STR_NEW_SIZE(len); + str->s = zend_string_alloc(str->a, 1); + str->s->len = 0; + } else { + str->a = SMART_STR_NEW_SIZE(len); + str->s = (zend_string *) realloc(str->s, _STR_HEADER_SIZE + str->a + 1); + } +} diff --git a/Zend/zend_smart_str.h b/Zend/zend_smart_str.h index c18b133dfe..7eae04e892 100644 --- a/Zend/zend_smart_str.h +++ b/Zend/zend_smart_str.h @@ -22,14 +22,6 @@ #include #include "zend_smart_str_public.h" -#ifndef SMART_STR_PREALLOC -#define SMART_STR_PREALLOC 128 -#endif - -#ifndef SMART_STR_START_SIZE -#define SMART_STR_START_SIZE 78 -#endif - #define smart_str_appends_ex(dest, src, what) \ smart_str_appendl_ex((dest), (src), strlen(src), (what)) #define smart_str_appends(dest, src) \ @@ -49,23 +41,28 @@ #define smart_str_append_unsigned(dest, val) \ smart_str_append_unsigned_ex((dest), (val), 0) +BEGIN_EXTERN_C() + +ZEND_API void ZEND_FASTCALL smart_str_erealloc(smart_str *str, size_t len); +ZEND_API void ZEND_FASTCALL smart_str_realloc(smart_str *str, size_t len); + +END_EXTERN_C() + static zend_always_inline size_t smart_str_alloc(smart_str *str, size_t len, zend_bool persistent) { - size_t newlen; - if (!str->s) { - newlen = len; - str->a = newlen < SMART_STR_START_SIZE - ? SMART_STR_START_SIZE - : newlen + SMART_STR_PREALLOC; - str->s = zend_string_alloc(str->a, persistent); - str->s->len = 0; + if (UNEXPECTED(!str->s)) { + goto do_smart_str_realloc; } else { - newlen = str->s->len + len; - if (newlen >= str->a) { - str->a = newlen + SMART_STR_PREALLOC; - str->s = (zend_string *) perealloc(str->s, _STR_HEADER_SIZE + str->a + 1, persistent); + len += str->s->len; + if (UNEXPECTED(len >= str->a)) { +do_smart_str_realloc: + if (persistent) { + smart_str_realloc(str, len); + } else { + smart_str_erealloc(str, len); + } } } - return newlen; + return len; } static zend_always_inline void smart_str_free(smart_str *str) { diff --git a/configure.in b/configure.in index 4575405403..ffc714ff5f 100644 --- a/configure.in +++ b/configure.in @@ -1494,7 +1494,7 @@ PHP_ADD_SOURCES(Zend, \ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \ zend_closures.c zend_float.c zend_string.c zend_signal.c zend_generators.c \ zend_virtual_cwd.c zend_ast.c zend_objects.c zend_object_handlers.c zend_objects_API.c \ - zend_default_classes.c zend_inheritance.c, \ + zend_default_classes.c zend_inheritance.c zend_smart_str.c, \ -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) dnl Selectively disable optimization due to high RAM usage during