The actual reallocation routiones are seprated from inlined code to reduce code size.
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 =
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;
};
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;
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | 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);
+ }
+}
#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) {
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