diff options
Diffstat (limited to 'Zend/zend_string.c')
-rw-r--r-- | Zend/zend_string.c | 57 |
1 files changed, 51 insertions, 6 deletions
diff --git a/Zend/zend_string.c b/Zend/zend_string.c index 03d77e1293..612c8049ef 100644 --- a/Zend/zend_string.c +++ b/Zend/zend_string.c @@ -42,6 +42,42 @@ static void _str_dtor(zval *zv) } #endif +/* Readonly, so assigned also per thread. */ +static const zend_string **known_interned_strings = NULL; +static uint32_t known_interned_strings_count = 0; + +ZEND_API uint32_t zend_intern_known_strings(const char **strings, uint32_t count) +{ + uint32_t i, old_count = known_interned_strings_count; + + known_interned_strings = perealloc(known_interned_strings, sizeof(char*) * (old_count + count), 1); + for (i = 0; i < count; i++) { +#ifndef ZTS + zend_string *str = zend_string_init(strings[i], strlen(strings[i]), 1); + known_interned_strings[known_interned_strings_count + i] = + zend_new_interned_string_int(str); +#else + known_interned_strings[known_interned_strings_count + i] = + zend_zts_interned_string_init(strings[i], strlen(strings[i])); +#endif + } + known_interned_strings_count = old_count + count; + return old_count; +} + +static const char *known_strings[] = { +#define _ZEND_STR_DSC(id, str) str, +ZEND_KNOWN_STRINGS(_ZEND_STR_DSC) +#undef _ZEND_STR_DSC + NULL +}; + +void zend_known_interned_strings_init(zend_string ***strings, uint32_t *count) +{ + *strings = (zend_string **)known_interned_strings; + *count = known_interned_strings_count; +} + void zend_interned_strings_init(void) { #ifndef ZTS @@ -63,6 +99,10 @@ void zend_interned_strings_init(void) /* one char strings (the actual interned strings are going to be created by ext/opcache) */ memset(CG(one_char_string), 0, sizeof(CG(one_char_string))); + /* known strings */ + zend_intern_known_strings(known_strings, (sizeof(known_strings) / sizeof(known_strings[0])) - 1); + zend_known_interned_strings_init(&CG(known_strings), &CG(known_strings_count)); + zend_new_interned_string = zend_new_interned_string_int; zend_interned_strings_snapshot = zend_interned_strings_snapshot_int; zend_interned_strings_restore = zend_interned_strings_restore_int; @@ -72,7 +112,18 @@ void zend_interned_strings_dtor(void) { #ifndef ZTS zend_hash_destroy(&CG(interned_strings)); +#else + uint32_t i; + + for (i = 0; i < CG(known_strings_count); i++) { + zend_zts_interned_string_free(&CG(known_strings)[i]); + } #endif + free(CG(known_strings)); + CG(known_strings) = NULL; + CG(known_strings_count) = 0; + known_interned_strings = NULL; + known_interned_strings_count = 0; } static zend_string *zend_new_interned_string_int(zend_string *str) @@ -110,7 +161,6 @@ static zend_string *zend_new_interned_string_int(zend_string *str) void *old_data = HT_GET_DATA_ADDR(&CG(interned_strings)); Bucket *old_buckets = CG(interned_strings).arData; - HANDLE_BLOCK_INTERRUPTIONS(); CG(interned_strings).nTableSize += CG(interned_strings).nTableSize; CG(interned_strings).nTableMask = -CG(interned_strings).nTableSize; new_data = malloc(HT_SIZE(&CG(interned_strings))); @@ -124,12 +174,9 @@ static zend_string *zend_new_interned_string_int(zend_string *str) CG(interned_strings).nTableSize = CG(interned_strings).nTableSize >> 1; CG(interned_strings).nTableMask = -CG(interned_strings).nTableSize; } - HANDLE_UNBLOCK_INTERRUPTIONS(); } } - HANDLE_BLOCK_INTERRUPTIONS(); - idx = CG(interned_strings).nNumUsed++; CG(interned_strings).nNumOfElements++; p = CG(interned_strings).arData + idx; @@ -141,8 +188,6 @@ static zend_string *zend_new_interned_string_int(zend_string *str) Z_NEXT(p->val) = HT_HASH(&CG(interned_strings), nIndex); HT_HASH(&CG(interned_strings), nIndex) = HT_IDX_TO_HASH(idx); - HANDLE_UNBLOCK_INTERRUPTIONS(); - return str; #else return str; |