]> granicus.if.org Git - php/commitdiff
Changed zend_smart_str allocation granularity to do the better job together with...
authorDmitry Stogov <dmitry@zend.com>
Thu, 16 Apr 2015 11:45:08 +0000 (14:45 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 16 Apr 2015 11:45:08 +0000 (14:45 +0300)
The actual reallocation routiones are seprated from inlined code to reduce code size.

Zend/Makefile.am
Zend/zend_alloc.c
Zend/zend_alloc.h
Zend/zend_smart_str.c [new file with mode: 0644]
Zend/zend_smart_str.h
configure.in

index fedbffe4ce71848b11802dee28883b738b189db1..5f7f25df677e05f5eb0564ef5750503cfcc2386d 100644 (file)
@@ -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 =
index 6701ca49028b55e33893fc2ae8fee56d0a66ce5f..16fd42e80f1ebc3388ca84ea68498c7604225ef2 100644 (file)
@@ -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;
 };
index 6d89884f0dbd1de457b540e8cfd5af926d2669e3..0cb3a71d345f94e3cf6ebf55dd30c31d5aedb845 100644 (file)
@@ -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 (file)
index 0000000..d0d3689
--- /dev/null
@@ -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 <dmitry@zend.com>                              |
+   +----------------------------------------------------------------------+
+ */
+
+#include <zend.h>
+#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);
+       }
+}
index c18b133dfec3461502ba41aa0ab9647fcabadc58..7eae04e8924753dda72a9233a14f7ce45b2b1a21 100644 (file)
 #include <zend.h>
 #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) \
 #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) {
index 457540540318341c7ce0837763291aaba3c63c08..ffc714ff5ff7a7e02d5f19567b44b76feac8c6d5 100644 (file)
@@ -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