Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 234 lines (194 sloc) 6.998 kb
dd5c478 Added concept of interned strings. All strings constants known at compil...
Dmitry Stogov authored
1 /*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
a666285 @laruence Happy New Year
laruence authored
5 | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) |
dd5c478 Added concept of interned strings. All strings constants known at compil...
Dmitry Stogov authored
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 2.00 of the Zend 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.zend.com/license/2_00.txt. |
11 | If you did not receive a copy of the Zend license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@zend.com so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Dmitry Stogov <dmitry@zend.com> |
16 +----------------------------------------------------------------------+
17 */
18
19 /* $Id: $ */
20
21 #include "zend.h"
22 #include "zend_globals.h"
23
24 #ifndef ZEND_DEBUG_INTERNED_STRINGS
25 # define ZEND_DEBUG_INTERNED_STRINGS 0
26 #endif
27
28 #if ZEND_DEBUG_INTERNED_STRINGS
29 # include <sys/mman.h>
30 #endif
31
aaa2f1c marked char pointer arguments as const in lots of
Hartmut Holzgraefe authored
32 ZEND_API const char *(*zend_new_interned_string)(const char *str, int len, int free_src TSRMLS_DC);
f7ce695 - Interned string related callbacks moved turned from compiler_globals i...
Dmitry Stogov authored
33 ZEND_API void (*zend_interned_strings_snapshot)(TSRMLS_D);
34 ZEND_API void (*zend_interned_strings_restore)(TSRMLS_D);
35
aaa2f1c marked char pointer arguments as const in lots of
Hartmut Holzgraefe authored
36 static const char *zend_new_interned_string_int(const char *str, int len, int free_src TSRMLS_DC);
f7ce695 - Interned string related callbacks moved turned from compiler_globals i...
Dmitry Stogov authored
37 static void zend_interned_strings_snapshot_int(TSRMLS_D);
38 static void zend_interned_strings_restore_int(TSRMLS_D);
dd5c478 Added concept of interned strings. All strings constants known at compil...
Dmitry Stogov authored
39
40 void zend_interned_strings_init(TSRMLS_D)
41 {
42 #ifndef ZTS
43 size_t size = 1024 * 1024;
44
45 #if ZEND_DEBUG_INTERNED_STRINGS
46 CG(interned_strings_start) = valloc(size);
47 #else
48 CG(interned_strings_start) = malloc(size);
49 #endif
50
51 CG(interned_strings_top) = CG(interned_strings_start);
52 CG(interned_strings_snapshot_top) = CG(interned_strings_start);
53 CG(interned_strings_end) = CG(interned_strings_start) + size;
54
55 zend_hash_init(&CG(interned_strings), 0, NULL, NULL, 1);
56
57 CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1;
58 CG(interned_strings).arBuckets = (Bucket **) pecalloc(CG(interned_strings).nTableSize, sizeof(Bucket *), CG(interned_strings).persistent);
59
60 #if ZEND_DEBUG_INTERNED_STRINGS
61 mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
62 #endif
63
64 #endif
65
f7ce695 - Interned string related callbacks moved turned from compiler_globals i...
Dmitry Stogov authored
66 zend_new_interned_string = zend_new_interned_string_int;
67 zend_interned_strings_snapshot = zend_interned_strings_snapshot_int;
68 zend_interned_strings_restore = zend_interned_strings_restore_int;
dd5c478 Added concept of interned strings. All strings constants known at compil...
Dmitry Stogov authored
69 }
70
71 void zend_interned_strings_dtor(TSRMLS_D)
72 {
73 #ifndef ZTS
74 #if ZEND_DEBUG_INTERNED_STRINGS
75 mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_WRITE | PROT_READ);
76 #endif
77 free(CG(interned_strings).arBuckets);
78 free(CG(interned_strings_start));
79 #endif
80 }
81
aaa2f1c marked char pointer arguments as const in lots of
Hartmut Holzgraefe authored
82 static const char *zend_new_interned_string_int(const char *arKey, int nKeyLength, int free_src TSRMLS_DC)
dd5c478 Added concept of interned strings. All strings constants known at compil...
Dmitry Stogov authored
83 {
84 #ifndef ZTS
85 ulong h;
86 uint nIndex;
87 Bucket *p;
88
89 if (IS_INTERNED(arKey)) {
90 return arKey;
91 }
92
93 h = zend_inline_hash_func(arKey, nKeyLength);
94 nIndex = h & CG(interned_strings).nTableMask;
95 p = CG(interned_strings).arBuckets[nIndex];
96 while (p != NULL) {
97 if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
98 if (!memcmp(p->arKey, arKey, nKeyLength)) {
99 if (free_src) {
aaa2f1c marked char pointer arguments as const in lots of
Hartmut Holzgraefe authored
100 efree((void *)arKey);
dd5c478 Added concept of interned strings. All strings constants known at compil...
Dmitry Stogov authored
101 }
102 return p->arKey;
103 }
104 }
105 p = p->pNext;
106 }
107
108 if (CG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength) >=
109 CG(interned_strings_end)) {
110 /* no memory */
111 return arKey;
112 }
113
114 p = (Bucket *) CG(interned_strings_top);
115 CG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength);
116
117 #if ZEND_DEBUG_INTERNED_STRINGS
118 mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ | PROT_WRITE);
119 #endif
120
121 p->arKey = (char*)(p+1);
e43ff13 Fixed ZE specific compile warnings (Bug #55629)
Dmitry Stogov authored
122 memcpy((char*)p->arKey, arKey, nKeyLength);
dd5c478 Added concept of interned strings. All strings constants known at compil...
Dmitry Stogov authored
123 if (free_src) {
aaa2f1c marked char pointer arguments as const in lots of
Hartmut Holzgraefe authored
124 efree((void *)arKey);
dd5c478 Added concept of interned strings. All strings constants known at compil...
Dmitry Stogov authored
125 }
126 p->nKeyLength = nKeyLength;
127 p->h = h;
128 p->pData = &p->pDataPtr;
129 p->pDataPtr = p;
130
131 p->pNext = CG(interned_strings).arBuckets[nIndex];
132 p->pLast = NULL;
133 if (p->pNext) {
134 p->pNext->pLast = p;
135 }
136
137 HANDLE_BLOCK_INTERRUPTIONS();
138
139 p->pListLast = CG(interned_strings).pListTail;
140 CG(interned_strings).pListTail = p;
141 p->pListNext = NULL;
142 if (p->pListLast != NULL) {
143 p->pListLast->pListNext = p;
144 }
145 if (!CG(interned_strings).pListHead) {
146 CG(interned_strings).pListHead = p;
147 }
148
149 CG(interned_strings).arBuckets[nIndex] = p;
150
151 HANDLE_UNBLOCK_INTERRUPTIONS();
152
153 CG(interned_strings).nNumOfElements++;
154
155 if (CG(interned_strings).nNumOfElements > CG(interned_strings).nTableSize) {
156 if ((CG(interned_strings).nTableSize << 1) > 0) { /* Let's double the table size */
157 Bucket **t = (Bucket **) perealloc_recoverable(CG(interned_strings).arBuckets, (CG(interned_strings).nTableSize << 1) * sizeof(Bucket *), CG(interned_strings).persistent);
158
159 if (t) {
160 HANDLE_BLOCK_INTERRUPTIONS();
161 CG(interned_strings).arBuckets = t;
162 CG(interned_strings).nTableSize = (CG(interned_strings).nTableSize << 1);
163 CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1;
164 zend_hash_rehash(&CG(interned_strings));
165 HANDLE_UNBLOCK_INTERRUPTIONS();
166 }
167 }
168 }
169
170 #if ZEND_DEBUG_INTERNED_STRINGS
171 mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
172 #endif
173
174 return p->arKey;
175 #else
176 return arKey;
177 #endif
178 }
179
f7ce695 - Interned string related callbacks moved turned from compiler_globals i...
Dmitry Stogov authored
180 static void zend_interned_strings_snapshot_int(TSRMLS_D)
dd5c478 Added concept of interned strings. All strings constants known at compil...
Dmitry Stogov authored
181 {
182 CG(interned_strings_snapshot_top) = CG(interned_strings_top);
183 }
184
f7ce695 - Interned string related callbacks moved turned from compiler_globals i...
Dmitry Stogov authored
185 static void zend_interned_strings_restore_int(TSRMLS_D)
dd5c478 Added concept of interned strings. All strings constants known at compil...
Dmitry Stogov authored
186 {
187 #ifndef ZTS
188 Bucket *p;
189 int i;
190 #endif
191
192 CG(interned_strings_top) = CG(interned_strings_snapshot_top);
193
194 #ifndef ZTS
195 #if ZEND_DEBUG_INTERNED_STRINGS
196 mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_WRITE | PROT_READ);
197 #endif
198
199 for (i = 0; i < CG(interned_strings).nTableSize; i++) {
200 p = CG(interned_strings).arBuckets[i];
201 while (p && p->arKey > CG(interned_strings_top)) {
202 CG(interned_strings).nNumOfElements--;
203 if (p->pListLast != NULL) {
204 p->pListLast->pListNext = p->pListNext;
205 } else {
206 CG(interned_strings).pListHead = p->pListNext;
207 }
208 if (p->pListNext != NULL) {
209 p->pListNext->pListLast = p->pListLast;
210 } else {
211 CG(interned_strings).pListTail = p->pListLast;
212 }
213 p = p->pNext;
214 }
215 if (p) {
216 p->pLast = NULL;
217 }
218 CG(interned_strings).arBuckets[i] = p;
219 }
220
221 #if ZEND_DEBUG_INTERNED_STRINGS
222 mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
223 #endif
224 #endif
225 }
226
227 /*
228 * Local variables:
229 * tab-width: 4
230 * c-basic-offset: 4
231 * indent-tabs-mode: t
232 * End:
233 */
Something went wrong with that request. Please try again.