25
25
26
26
ZEND_API zend_new_interned_string_func_t zend_new_interned_string ;
27
27
ZEND_API zend_string_init_interned_func_t zend_string_init_interned ;
28
+ ZEND_API zend_string_init_existing_interned_func_t zend_string_init_existing_interned ;
28
29
29
30
static zend_string * ZEND_FASTCALL zend_new_interned_string_permanent (zend_string * str );
30
31
static zend_string * ZEND_FASTCALL zend_new_interned_string_request (zend_string * str );
31
32
static zend_string * ZEND_FASTCALL zend_string_init_interned_permanent (const char * str , size_t size , bool permanent );
33
+ static zend_string * ZEND_FASTCALL zend_string_init_existing_interned_permanent (const char * str , size_t size , bool permanent );
32
34
static zend_string * ZEND_FASTCALL zend_string_init_interned_request (const char * str , size_t size , bool permanent );
35
+ static zend_string * ZEND_FASTCALL zend_string_init_existing_interned_request (const char * str , size_t size , bool permanent );
33
36
34
37
/* Any strings interned in the startup phase. Common to all the threads,
35
38
won't be free'd until process exit. If we want an ability to
@@ -39,6 +42,7 @@ static HashTable interned_strings_permanent;
39
42
40
43
static zend_new_interned_string_func_t interned_string_request_handler = zend_new_interned_string_request ;
41
44
static zend_string_init_interned_func_t interned_string_init_request_handler = zend_string_init_interned_request ;
45
+ static zend_string_init_existing_interned_func_t interned_string_init_existing_request_handler = zend_string_init_existing_interned_request ;
42
46
43
47
ZEND_API zend_string * zend_empty_string = NULL ;
44
48
ZEND_API zend_string * zend_one_char_string [256 ];
@@ -83,6 +87,7 @@ ZEND_API void zend_interned_strings_init(void)
83
87
84
88
interned_string_request_handler = zend_new_interned_string_request ;
85
89
interned_string_init_request_handler = zend_string_init_interned_request ;
90
+ interned_string_init_existing_request_handler = zend_string_init_existing_interned_request ;
86
91
87
92
zend_empty_string = NULL ;
88
93
zend_known_strings = NULL ;
@@ -91,6 +96,7 @@ ZEND_API void zend_interned_strings_init(void)
91
96
92
97
zend_new_interned_string = zend_new_interned_string_permanent ;
93
98
zend_string_init_interned = zend_string_init_interned_permanent ;
99
+ zend_string_init_existing_interned = zend_string_init_existing_interned_permanent ;
94
100
95
101
/* interned empty string */
96
102
str = zend_string_alloc (sizeof ("" )- 1 , 1 );
@@ -267,6 +273,20 @@ static zend_string* ZEND_FASTCALL zend_string_init_interned_permanent(const char
267
273
return zend_add_interned_string (ret , & interned_strings_permanent , IS_STR_PERMANENT );
268
274
}
269
275
276
+ static zend_string * ZEND_FASTCALL zend_string_init_existing_interned_permanent (const char * str , size_t size , bool permanent )
277
+ {
278
+ zend_ulong h = zend_inline_hash_func (str , size );
279
+ zend_string * ret = zend_interned_string_ht_lookup_ex (h , str , size , & interned_strings_permanent );
280
+ if (ret ) {
281
+ return ret ;
282
+ }
283
+
284
+ ZEND_ASSERT (permanent );
285
+ ret = zend_string_init (str , size , permanent );
286
+ ZSTR_H (ret ) = h ;
287
+ return ret ;
288
+ }
289
+
270
290
static zend_string * ZEND_FASTCALL zend_string_init_interned_request (const char * str , size_t size , bool permanent )
271
291
{
272
292
zend_string * ret ;
@@ -297,6 +317,25 @@ static zend_string* ZEND_FASTCALL zend_string_init_interned_request(const char *
297
317
return zend_add_interned_string (ret , & CG (interned_strings ), 0 );
298
318
}
299
319
320
+ static zend_string * ZEND_FASTCALL zend_string_init_existing_interned_request (const char * str , size_t size , bool permanent )
321
+ {
322
+ zend_ulong h = zend_inline_hash_func (str , size );
323
+ zend_string * ret = zend_interned_string_ht_lookup_ex (h , str , size , & interned_strings_permanent );
324
+ if (ret ) {
325
+ return ret ;
326
+ }
327
+
328
+ ret = zend_interned_string_ht_lookup_ex (h , str , size , & CG (interned_strings ));
329
+ if (ret ) {
330
+ return ret ;
331
+ }
332
+
333
+ ZEND_ASSERT (!permanent );
334
+ ret = zend_string_init (str , size , permanent );
335
+ ZSTR_H (ret ) = h ;
336
+ return ret ;
337
+ }
338
+
300
339
ZEND_API void zend_interned_strings_activate (void )
301
340
{
302
341
zend_init_interned_strings_ht (& CG (interned_strings ), 0 );
@@ -307,20 +346,23 @@ ZEND_API void zend_interned_strings_deactivate(void)
307
346
zend_hash_destroy (& CG (interned_strings ));
308
347
}
309
348
310
- ZEND_API void zend_interned_strings_set_request_storage_handlers (zend_new_interned_string_func_t handler , zend_string_init_interned_func_t init_handler )
349
+ ZEND_API void zend_interned_strings_set_request_storage_handlers (zend_new_interned_string_func_t handler , zend_string_init_interned_func_t init_handler , zend_string_init_existing_interned_func_t init_existing_handler )
311
350
{
312
351
interned_string_request_handler = handler ;
313
352
interned_string_init_request_handler = init_handler ;
353
+ interned_string_init_existing_request_handler = init_existing_handler ;
314
354
}
315
355
316
356
ZEND_API void zend_interned_strings_switch_storage (bool request )
317
357
{
318
358
if (request ) {
319
359
zend_new_interned_string = interned_string_request_handler ;
320
360
zend_string_init_interned = interned_string_init_request_handler ;
361
+ zend_string_init_existing_interned = interned_string_init_existing_request_handler ;
321
362
} else {
322
363
zend_new_interned_string = zend_new_interned_string_permanent ;
323
364
zend_string_init_interned = zend_string_init_interned_permanent ;
365
+ zend_string_init_existing_interned = zend_string_init_existing_interned_permanent ;
324
366
}
325
367
}
326
368
0 commit comments