while (ptr->fname) {
fname_len = strlen(ptr->fname);
internal_function->handler = ptr->handler;
- internal_function->function_name = zend_new_interned_string(zend_string_init(ptr->fname, fname_len, 1));
+ internal_function->function_name = zend_string_init_interned(ptr->fname, fname_len, 1);
internal_function->scope = scope;
internal_function->prototype = NULL;
if (ptr->flags) {
class_name++;
allow_null = 1;
}
- str = zend_new_interned_string(zend_string_init(class_name, strlen(class_name), 1));
+ str = zend_string_init_interned(class_name, strlen(class_name), 1);
new_arg_info[i].type = ZEND_TYPE_ENCODE_CLASS(str, allow_null);
}
}
{
int ret;
- zend_string *key = zend_string_init(name, name_length, ce->type & ZEND_INTERNAL_CLASS);
+ zend_string *key;
+
if (ce->type == ZEND_INTERNAL_CLASS) {
- key = zend_new_interned_string(key);
+ key = zend_string_init_interned(name, name_length, 1);
+ } else {
+ key = zend_string_init(name, name_length, 0);
}
ret = zend_declare_class_constant_ex(ce, key, value, ZEND_ACC_PUBLIC, NULL);
zend_string_release(key);
#define INIT_OVERLOADED_CLASS_ENTRY_EX(class_container, class_name, class_name_len, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) \
{ \
- zend_string *cl_name; \
- cl_name = zend_string_init(class_name, class_name_len, 1); \
- class_container.name = zend_new_interned_string(cl_name); \
+ class_container.name = zend_string_init_interned(class_name, class_name_len, 1); \
INIT_CLASS_ENTRY_INIT_METHODS(class_container, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) \
}
#include "zend_globals.h"
ZEND_API zend_string *(*zend_new_interned_string)(zend_string *str);
+ZEND_API zend_string *(*zend_string_init_interned)(const char *str, size_t size, int permanent);
static zend_string *zend_new_interned_string_permanent(zend_string *str);
static zend_string *zend_new_interned_string_request(zend_string *str);
+static zend_string *zend_string_init_interned_permanent(const char *str, size_t size, int permanent);
+static zend_string *zend_string_init_interned_request(const char *str, size_t size, int permanent);
/* Any strings interned in the startup phase. Common to all the threads,
won't be free'd until process exit. If we want an ability to
static HashTable interned_strings_permanent;
static zend_new_interned_string_func_t interned_string_request_handler = zend_new_interned_string_request;
+static zend_string_init_interned_func_t interned_string_init_request_handler = zend_string_init_interned_request;
static zend_string_copy_storage_func_t interned_string_copy_storage = NULL;
ZEND_API zend_string *zend_empty_string = NULL;
zend_init_interned_strings_ht(&interned_strings_permanent, 1);
zend_new_interned_string = zend_new_interned_string_permanent;
+ zend_string_init_interned = zend_string_init_interned_permanent;
/* interned empty string */
str = zend_string_alloc(sizeof("")-1, 1);
zend_known_strings = NULL;
}
-static zend_always_inline zend_string *zend_interned_string_ht_lookup(zend_string *str, HashTable *interned_strings)
+static zend_always_inline zend_string *zend_interned_string_ht_lookup_ex(zend_ulong h, const char *str, size_t size, HashTable *interned_strings)
{
- zend_ulong h;
uint32_t nIndex;
uint32_t idx;
Bucket *p;
- h = zend_string_hash_val(str);
nIndex = h | interned_strings->nTableMask;
idx = HT_HASH(interned_strings, nIndex);
while (idx != HT_INVALID_IDX) {
p = HT_HASH_TO_BUCKET(interned_strings, idx);
- if ((p->h == h) && (ZSTR_LEN(p->key) == ZSTR_LEN(str))) {
- if (!memcmp(ZSTR_VAL(p->key), ZSTR_VAL(str), ZSTR_LEN(str))) {
+ if ((p->h == h) && (ZSTR_LEN(p->key) == size)) {
+ if (!memcmp(ZSTR_VAL(p->key), str, size)) {
return p->key;
}
}
return NULL;
}
+static zend_always_inline zend_string *zend_interned_string_ht_lookup(zend_string *str, HashTable *interned_strings)
+{
+ return zend_interned_string_ht_lookup_ex(ZSTR_H(str), ZSTR_VAL(str), ZSTR_LEN(str), interned_strings);
+}
+
/* This function might be not thread safe at least because it would update the
hash val in the passed string. Be sure it is called in the appropriate context. */
static zend_always_inline zend_string *zend_add_interned_string(zend_string *str, HashTable *interned_strings, uint32_t flags)
ZEND_API zend_string *zend_interned_string_find_permanent(zend_string *str)
{
+ zend_string_hash_val(str);
return zend_interned_string_ht_lookup(str, &interned_strings_permanent);
}
-
static zend_string *zend_new_interned_string_permanent(zend_string *str)
{
zend_string *ret;
return str;
}
+ zend_string_hash_val(str);
ret = zend_interned_string_ht_lookup(str, &interned_strings_permanent);
if (ret) {
zend_string_release(str);
return str;
}
+ zend_string_hash_val(str);
+
/* Check for permanent strings, the table is readonly at this point. */
ret = zend_interned_string_ht_lookup(str, &interned_strings_permanent);
if (ret) {
return ret;
}
+static zend_string *zend_string_init_interned_permanent(const char *str, size_t size, int permanent)
+{
+ zend_string *ret;
+ zend_long h = zend_inline_hash_func(str, size);
+
+ ret = zend_interned_string_ht_lookup_ex(h, str, size, &interned_strings_permanent);
+ if (ret) {
+ return ret;
+ }
+
+ ret = zend_string_init(str, size, permanent);
+ ZSTR_H(ret) = h;
+ return zend_add_interned_string(ret, &interned_strings_permanent, IS_STR_PERMANENT);
+}
+
+static zend_string *zend_string_init_interned_request(const char *str, size_t size, int permanent)
+{
+ zend_string *ret;
+ zend_long h = zend_inline_hash_func(str, size);
+
+ /* Check for permanent strings, the table is readonly at this point. */
+ ret = zend_interned_string_ht_lookup_ex(h, str, size, &interned_strings_permanent);
+ if (ret) {
+ return ret;
+ }
+
+ ret = zend_interned_string_ht_lookup_ex(h, str, size, &CG(interned_strings));
+ if (ret) {
+ return ret;
+ }
+
+ ret = zend_string_init(str, size, permanent);
+ ZSTR_H(ret) = h;
+
+ /* Create a short living interned, freed after the request. */
+ return zend_add_interned_string(ret, &CG(interned_strings), 0);
+}
+
ZEND_API void zend_interned_strings_activate(void)
{
zend_init_interned_strings_ht(&CG(interned_strings), 0);
zend_hash_destroy(&CG(interned_strings));
}
-ZEND_API void zend_interned_strings_set_request_storage_handler(zend_new_interned_string_func_t handler)
+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)
{
interned_string_request_handler = handler;
+ interned_string_init_request_handler = init_handler;
}
ZEND_API void zend_interned_strings_set_permanent_storage_copy_handler(zend_string_copy_storage_func_t handler)
interned_string_copy_storage();
}
zend_new_interned_string = interned_string_request_handler;
+ zend_string_init_interned = interned_string_init_request_handler;
}
/*
typedef void (*zend_string_copy_storage_func_t)(void);
typedef zend_string *(*zend_new_interned_string_func_t)(zend_string *str);
+typedef zend_string *(*zend_string_init_interned_func_t)(const char *str, size_t size, int permanent);
ZEND_API extern zend_new_interned_string_func_t zend_new_interned_string;
+ZEND_API extern zend_string_init_interned_func_t zend_string_init_interned;
ZEND_API zend_ulong zend_hash_func(const char *str, size_t len);
ZEND_API void zend_interned_strings_init(void);
ZEND_API void zend_interned_strings_activate(void);
ZEND_API void zend_interned_strings_deactivate(void);
ZEND_API zend_string *zend_interned_string_find_permanent(zend_string *str);
-ZEND_API void zend_interned_strings_set_request_storage_handler(zend_new_interned_string_func_t handler);
+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_API void zend_interned_strings_set_permanent_storage_copy_handler(zend_string_copy_storage_func_t handler);
ZEND_API void zend_interned_strings_switch_storage(void);
return ret;
}
-static zend_always_inline zend_string *zend_string_init_interned(const char *str, size_t len, int persistent)
-{
- zend_string *ret = zend_string_init(str, len, persistent);
-
- return zend_new_interned_string(ret);
-}
-
static zend_always_inline zend_string *zend_string_copy(zend_string *s)
{
if (!ZSTR_IS_INTERNED(s)) {
meta->root_len = total_len;
if (meta->name != mysqlnd_empty_string) {
- meta->sname = zend_new_interned_string(zend_string_init(meta->name, meta->name_length, packet->persistent_alloc));
+ meta->sname = zend_string_init_interned(meta->name, meta->name_length, packet->persistent_alloc);
} else {
meta->sname = ZSTR_EMPTY_ALLOC();
}
return str;
}
+static zend_string *accel_find_interned_string_ex(zend_ulong h, const char *str, size_t size)
+{
+ uint32_t nIndex;
+ uint32_t idx;
+ Bucket *arData, *p;
+
+ nIndex = h | ZCSG(interned_strings).nTableMask;
+
+ /* check for existing interned string */
+ idx = HT_HASH(&ZCSG(interned_strings), nIndex);
+ arData = ZCSG(interned_strings).arData;
+ while (idx != HT_INVALID_IDX) {
+ p = HT_HASH_TO_BUCKET_EX(arData, idx);
+ if ((p->h == h) && (ZSTR_LEN(p->key) == size)) {
+ if (!memcmp(ZSTR_VAL(p->key), str, size)) {
+ return p->key;
+ }
+ }
+ idx = Z_NEXT(p->val);
+ }
+
+ return NULL;
+}
+
+static zend_string *accel_init_interned_string_for_php(const char *str, size_t size, int permanent)
+{
+ if (ZCG(counted)) {
+ zend_ulong h = zend_inline_hash_func(str, size);
+ zend_string *ret = accel_find_interned_string_ex(h, str, size);
+
+ if (!ret) {
+ ret = zend_string_init(str, size, permanent);
+ ZSTR_H(ret) = h;
+ }
+
+ return ret;
+ }
+
+ return zend_string_init(str, size, permanent);
+}
+
/* Copy PHP interned strings from PHP process memory into the shared memory */
static void accel_copy_permanent_strings(zend_new_interned_string_func_t new_interned_string)
{
zend_interned_strings_set_permanent_storage_copy_handler(accel_use_shm_interned_strings);
}
- zend_interned_strings_set_request_storage_handler(accel_new_interned_string_for_php);
+ zend_interned_strings_set_request_storage_handlers(accel_new_interned_string_for_php, accel_init_interned_string_for_php);
zend_reset_cache_vars();
if (ZCG(accel_directives).interned_strings_buffer) {
zend_interned_strings_set_permanent_storage_copy_handler(accel_use_shm_interned_strings);
}
- zend_interned_strings_set_request_storage_handler(accel_new_interned_string_for_php);
+ zend_interned_strings_set_request_storage_handlers(accel_new_interned_string_for_php, accel_init_interned_string_for_php);
zend_shared_alloc_unlock();
break;
case FAILED_REATTACHED: