Skip to content

Commit e38ed4c

Browse files
committed
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.
1 parent 05232cc commit e38ed4c

File tree

6 files changed

+95
-33
lines changed

6 files changed

+95
-33
lines changed

Zend/Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ libZend_la_SOURCES=\
1818
zend_default_classes.c \
1919
zend_iterators.c zend_interfaces.c zend_exceptions.c \
2020
zend_strtod.c zend_closures.c zend_float.c zend_string.c zend_signal.c \
21-
zend_generators.c zend_virtual_cwd.c zend_ast.c
21+
zend_generators.c zend_virtual_cwd.c zend_ast.c zend_smart_str.c
2222

2323
libZend_la_CFLAGS = -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1
2424
libZend_la_LDFLAGS =

Zend/zend_alloc.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -287,16 +287,6 @@ struct _zend_mm_bin {
287287
char bytes[ZEND_MM_PAGE_SIZE * 8];
288288
};
289289

290-
#if ZEND_DEBUG
291-
typedef struct _zend_mm_debug_info {
292-
size_t size;
293-
const char *filename;
294-
const char *orig_filename;
295-
uint lineno;
296-
uint orig_lineno;
297-
} zend_mm_debug_info;
298-
#endif
299-
300290
struct _zend_mm_free_slot {
301291
zend_mm_free_slot *next_free_slot;
302292
};

Zend/zend_alloc.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,20 @@ typedef struct _zend_leak_info {
5050
uint orig_lineno;
5151
} zend_leak_info;
5252

53+
#if ZEND_DEBUG
54+
typedef struct _zend_mm_debug_info {
55+
size_t size;
56+
const char *filename;
57+
const char *orig_filename;
58+
uint lineno;
59+
uint orig_lineno;
60+
} zend_mm_debug_info;
61+
62+
# define ZEND_MM_OVERHEAD ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info))
63+
#else
64+
# define ZEND_MM_OVERHEAD 0
65+
#endif
66+
5367
BEGIN_EXTERN_C()
5468

5569
ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length) ZEND_ATTRIBUTE_MALLOC;

Zend/zend_smart_str.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| PHP Version 7 |
4+
+----------------------------------------------------------------------+
5+
| Copyright (c) 1997-2015 The PHP Group |
6+
+----------------------------------------------------------------------+
7+
| This source file is subject to version 3.01 of the PHP license, |
8+
| that is bundled with this package in the file LICENSE, and is |
9+
| available through the world-wide-web at the following url: |
10+
| http://www.php.net/license/3_01.txt |
11+
| If you did not receive a copy of the PHP license and are unable to |
12+
| obtain it through the world-wide-web, please send a note to |
13+
| license@php.net so we can mail you a copy immediately. |
14+
+----------------------------------------------------------------------+
15+
| Author: Dmitry Stogov <dmitry@zend.com> |
16+
+----------------------------------------------------------------------+
17+
*/
18+
19+
#include <zend.h>
20+
#include "zend_smart_str_public.h"
21+
22+
#define SMART_STR_OVERHEAD (ZEND_MM_OVERHEAD + _STR_HEADER_SIZE)
23+
24+
#ifndef SMART_STR_PAGE
25+
# define SMART_STR_PAGE 4096
26+
#endif
27+
28+
#ifndef SMART_STR_START_SIZE
29+
# define SMART_STR_START_SIZE (256 - SMART_STR_OVERHEAD - 1)
30+
#endif
31+
32+
#define SMART_STR_NEW_SIZE(len) \
33+
(((len + SMART_STR_OVERHEAD + SMART_STR_PAGE) & ~(SMART_STR_PAGE - 1)) - SMART_STR_OVERHEAD - 1)
34+
35+
ZEND_API void ZEND_FASTCALL smart_str_erealloc(smart_str *str, size_t len)
36+
{
37+
if (UNEXPECTED(!str->s)) {
38+
str->a = len < SMART_STR_START_SIZE
39+
? SMART_STR_START_SIZE
40+
: SMART_STR_NEW_SIZE(len);
41+
str->s = zend_string_alloc(str->a, 0);
42+
str->s->len = 0;
43+
} else {
44+
str->a = SMART_STR_NEW_SIZE(len);
45+
str->s = (zend_string *) erealloc2(str->s, _STR_HEADER_SIZE + str->a + 1, _STR_HEADER_SIZE + str->s->len + 1);
46+
}
47+
}
48+
49+
ZEND_API void ZEND_FASTCALL smart_str_realloc(smart_str *str, size_t len)
50+
{
51+
if (UNEXPECTED(!str->s)) {
52+
str->a = len < SMART_STR_START_SIZE
53+
? SMART_STR_START_SIZE
54+
: SMART_STR_NEW_SIZE(len);
55+
str->s = zend_string_alloc(str->a, 1);
56+
str->s->len = 0;
57+
} else {
58+
str->a = SMART_STR_NEW_SIZE(len);
59+
str->s = (zend_string *) realloc(str->s, _STR_HEADER_SIZE + str->a + 1);
60+
}
61+
}

Zend/zend_smart_str.h

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,6 @@
2222
#include <zend.h>
2323
#include "zend_smart_str_public.h"
2424

25-
#ifndef SMART_STR_PREALLOC
26-
#define SMART_STR_PREALLOC 128
27-
#endif
28-
29-
#ifndef SMART_STR_START_SIZE
30-
#define SMART_STR_START_SIZE 78
31-
#endif
32-
3325
#define smart_str_appends_ex(dest, src, what) \
3426
smart_str_appendl_ex((dest), (src), strlen(src), (what))
3527
#define smart_str_appends(dest, src) \
@@ -49,23 +41,28 @@
4941
#define smart_str_append_unsigned(dest, val) \
5042
smart_str_append_unsigned_ex((dest), (val), 0)
5143

44+
BEGIN_EXTERN_C()
45+
46+
ZEND_API void ZEND_FASTCALL smart_str_erealloc(smart_str *str, size_t len);
47+
ZEND_API void ZEND_FASTCALL smart_str_realloc(smart_str *str, size_t len);
48+
49+
END_EXTERN_C()
50+
5251
static zend_always_inline size_t smart_str_alloc(smart_str *str, size_t len, zend_bool persistent) {
53-
size_t newlen;
54-
if (!str->s) {
55-
newlen = len;
56-
str->a = newlen < SMART_STR_START_SIZE
57-
? SMART_STR_START_SIZE
58-
: newlen + SMART_STR_PREALLOC;
59-
str->s = zend_string_alloc(str->a, persistent);
60-
str->s->len = 0;
52+
if (UNEXPECTED(!str->s)) {
53+
goto do_smart_str_realloc;
6154
} else {
62-
newlen = str->s->len + len;
63-
if (newlen >= str->a) {
64-
str->a = newlen + SMART_STR_PREALLOC;
65-
str->s = (zend_string *) perealloc(str->s, _STR_HEADER_SIZE + str->a + 1, persistent);
55+
len += str->s->len;
56+
if (UNEXPECTED(len >= str->a)) {
57+
do_smart_str_realloc:
58+
if (persistent) {
59+
smart_str_realloc(str, len);
60+
} else {
61+
smart_str_erealloc(str, len);
62+
}
6663
}
6764
}
68-
return newlen;
65+
return len;
6966
}
7067

7168
static zend_always_inline void smart_str_free(smart_str *str) {

configure.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1494,7 +1494,7 @@ PHP_ADD_SOURCES(Zend, \
14941494
zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \
14951495
zend_closures.c zend_float.c zend_string.c zend_signal.c zend_generators.c \
14961496
zend_virtual_cwd.c zend_ast.c zend_objects.c zend_object_handlers.c zend_objects_API.c \
1497-
zend_default_classes.c zend_inheritance.c, \
1497+
zend_default_classes.c zend_inheritance.c zend_smart_str.c, \
14981498
-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
14991499

15001500
dnl Selectively disable optimization due to high RAM usage during

0 commit comments

Comments
 (0)