diff options
Diffstat (limited to 'Zend/zend_string.h')
-rw-r--r-- | Zend/zend_string.h | 115 |
1 files changed, 67 insertions, 48 deletions
diff --git a/Zend/zend_string.h b/Zend/zend_string.h index 784b88ea6a..c95578d4a5 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -12,12 +12,10 @@ | obtain it through the world-wide-web, please send a note to | | license@zend.com so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Dmitry Stogov <dmitry@zend.com> | + | Authors: Dmitry Stogov <dmitry@php.net> | +----------------------------------------------------------------------+ */ -/* $Id: $ */ - #ifndef ZEND_STRING_H #define ZEND_STRING_H @@ -26,19 +24,23 @@ BEGIN_EXTERN_C() 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_FASTCALL *zend_new_interned_string_func_t)(zend_string *str); +typedef zend_string *(ZEND_FASTCALL *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_FASTCALL zend_string_hash_func(zend_string *str); +ZEND_API zend_ulong ZEND_FASTCALL zend_hash_func(const char *str, size_t len); +ZEND_API zend_string* ZEND_FASTCALL zend_interned_string_find_permanent(zend_string *str); -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_dtor(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_permanent_storage_copy_handler(zend_string_copy_storage_func_t handler); -ZEND_API void zend_interned_strings_switch_storage(void); +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_handlers(zend_string_copy_storage_func_t copy_handler, zend_string_copy_storage_func_t restore_handler); +ZEND_API void zend_interned_strings_switch_storage(zend_bool request); ZEND_API extern zend_string *zend_empty_string; ZEND_API extern zend_string *zend_one_char_string[256]; @@ -76,7 +78,7 @@ END_EXTERN_C() #define ZSTR_ALLOCA_ALLOC(str, _len, use_heap) do { \ (str) = (zend_string *)do_alloca(ZEND_MM_ALIGNED_SIZE_EX(_ZSTR_STRUCT_SIZE(_len), 8), (use_heap)); \ - GC_REFCOUNT(str) = 1; \ + GC_SET_REFCOUNT(str, 1); \ GC_TYPE_INFO(str) = IS_STRING; \ zend_string_forget_hash_val(str); \ ZSTR_LEN(str) = _len; \ @@ -94,10 +96,7 @@ END_EXTERN_C() static zend_always_inline zend_ulong zend_string_hash_val(zend_string *s) { - if (!ZSTR_H(s)) { - ZSTR_H(s) = zend_hash_func(ZSTR_VAL(s), ZSTR_LEN(s)); - } - return ZSTR_H(s); + return ZSTR_H(s) ? ZSTR_H(s) : zend_string_hash_func(s); } static zend_always_inline void zend_string_forget_hash_val(zend_string *s) @@ -116,7 +115,7 @@ static zend_always_inline uint32_t zend_string_refcount(const zend_string *s) static zend_always_inline uint32_t zend_string_addref(zend_string *s) { if (!ZSTR_IS_INTERNED(s)) { - return ++GC_REFCOUNT(s); + return GC_ADDREF(s); } return 1; } @@ -124,7 +123,7 @@ static zend_always_inline uint32_t zend_string_addref(zend_string *s) static zend_always_inline uint32_t zend_string_delref(zend_string *s) { if (!ZSTR_IS_INTERNED(s)) { - return --GC_REFCOUNT(s); + return GC_DELREF(s); } return 1; } @@ -133,15 +132,8 @@ static zend_always_inline zend_string *zend_string_alloc(size_t len, int persist { zend_string *ret = (zend_string *)pemalloc(ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(len)), persistent); - GC_REFCOUNT(ret) = 1; -#if 1 - /* optimized single assignment */ - GC_TYPE_INFO(ret) = IS_STRING | ((persistent ? IS_STR_PERSISTENT : 0) << 8); -#else - GC_TYPE(ret) = IS_STRING; - GC_FLAGS(ret) = (persistent ? IS_STR_PERSISTENT : 0); - GC_INFO(ret) = 0; -#endif + GC_SET_REFCOUNT(ret, 1); + GC_TYPE_INFO(ret) = IS_STRING | ((persistent ? IS_STR_PERSISTENT : 0) << GC_FLAGS_SHIFT); zend_string_forget_hash_val(ret); ZSTR_LEN(ret) = len; return ret; @@ -151,15 +143,8 @@ static zend_always_inline zend_string *zend_string_safe_alloc(size_t n, size_t m { zend_string *ret = (zend_string *)safe_pemalloc(n, m, ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(l)), persistent); - GC_REFCOUNT(ret) = 1; -#if 1 - /* optimized single assignment */ - GC_TYPE_INFO(ret) = IS_STRING | ((persistent ? IS_STR_PERSISTENT : 0) << 8); -#else - GC_TYPE(ret) = IS_STRING; - GC_FLAGS(ret) = (persistent ? IS_STR_PERSISTENT : 0); - GC_INFO(ret) = 0; -#endif + GC_SET_REFCOUNT(ret, 1); + GC_TYPE_INFO(ret) = IS_STRING | ((persistent ? IS_STR_PERSISTENT : 0) << GC_FLAGS_SHIFT); zend_string_forget_hash_val(ret); ZSTR_LEN(ret) = (n * m) + l; return ret; @@ -174,17 +159,10 @@ static zend_always_inline zend_string *zend_string_init(const char *str, size_t 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)) { - GC_REFCOUNT(s)++; + GC_ADDREF(s); } return s; } @@ -209,7 +187,7 @@ static zend_always_inline zend_string *zend_string_realloc(zend_string *s, size_ zend_string_forget_hash_val(ret); return ret; } else { - GC_REFCOUNT(s)--; + GC_DELREF(s); } } ret = zend_string_alloc(len, persistent); @@ -229,7 +207,7 @@ static zend_always_inline zend_string *zend_string_extend(zend_string *s, size_t zend_string_forget_hash_val(ret); return ret; } else { - GC_REFCOUNT(s)--; + GC_DELREF(s); } } ret = zend_string_alloc(len, persistent); @@ -249,7 +227,7 @@ static zend_always_inline zend_string *zend_string_truncate(zend_string *s, size zend_string_forget_hash_val(ret); return ret; } else { - GC_REFCOUNT(s)--; + GC_DELREF(s); } } ret = zend_string_alloc(len, persistent); @@ -268,7 +246,7 @@ static zend_always_inline zend_string *zend_string_safe_realloc(zend_string *s, zend_string_forget_hash_val(ret); return ret; } else { - GC_REFCOUNT(s)--; + GC_DELREF(s); } } ret = zend_string_safe_alloc(n, m, l, persistent); @@ -284,19 +262,57 @@ static zend_always_inline void zend_string_free(zend_string *s) } } +static zend_always_inline void zend_string_efree(zend_string *s) +{ + ZEND_ASSERT(!ZSTR_IS_INTERNED(s)); + ZEND_ASSERT(GC_REFCOUNT(s) <= 1); + ZEND_ASSERT(!(GC_FLAGS(s) & IS_STR_PERSISTENT)); + efree(s); +} + static zend_always_inline void zend_string_release(zend_string *s) { if (!ZSTR_IS_INTERNED(s)) { - if (--GC_REFCOUNT(s) == 0) { + if (GC_DELREF(s) == 0) { pefree(s, GC_FLAGS(s) & IS_STR_PERSISTENT); } } } +static zend_always_inline void zend_string_release_ex(zend_string *s, int persistent) +{ + if (!ZSTR_IS_INTERNED(s)) { + if (GC_DELREF(s) == 0) { + if (persistent) { + ZEND_ASSERT(GC_FLAGS(s) & IS_STR_PERSISTENT); + free(s); + } else { + ZEND_ASSERT(!(GC_FLAGS(s) & IS_STR_PERSISTENT)); + efree(s); + } + } + } +} + +#if defined(__GNUC__) && (defined(__i386__) || (defined(__x86_64__) && !defined(__ILP32__))) +BEGIN_EXTERN_C() +ZEND_API zend_bool ZEND_FASTCALL zend_string_equal_val(zend_string *s1, zend_string *s2); +END_EXTERN_C() +#else +static zend_always_inline zend_bool zend_string_equal_val(zend_string *s1, zend_string *s2) +{ + return !memcmp(ZSTR_VAL(s1), ZSTR_VAL(s2), ZSTR_LEN(s1)); +} +#endif + +static zend_always_inline zend_bool zend_string_equal_content(zend_string *s1, zend_string *s2) +{ + return ZSTR_LEN(s1) == ZSTR_LEN(s2) && zend_string_equal_val(s1, s2); +} static zend_always_inline zend_bool zend_string_equals(zend_string *s1, zend_string *s2) { - return s1 == s2 || (ZSTR_LEN(s1) == ZSTR_LEN(s2) && !memcmp(ZSTR_VAL(s1), ZSTR_VAL(s2), ZSTR_LEN(s1))); + return s1 == s2 || zend_string_equal_content(s1, s2); } #define zend_string_equals_ci(s1, s2) \ @@ -423,6 +439,9 @@ EMPTY_SWITCH_DEFAULT_CASE() _(ZEND_STR_ARRAY, "array") \ _(ZEND_STR_RESOURCE, "resource") \ _(ZEND_STR_CLOSED_RESOURCE, "resource (closed)") \ + _(ZEND_STR_NAME, "name") \ + _(ZEND_STR_ARGV, "argv") \ + _(ZEND_STR_ARGC, "argc") \ typedef enum _zend_known_string_id { |