com php-src: Add STR_ALLOCA_* API, use in get_m ethod and verify_arg: Zend/zend_execute.c Zend/ zend_object_handlers.c Zend/zend_string.h
| From: | Dmitry Stogov | Date: | Sat, 03 May 2014 08:43:45 +0000 |
| Subject: | com php-src: Add STR_ALLOCA_* API, use in get_m ethod and verify_arg: Zend/zend_execute.c Zend/ zend_object_handlers.c Zend/zend_string.h | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-77260@lists.php.net to get a copy of this message | ||
Commit: 65f488ece3f946d53b12b8c265185a483b079dfb
Author: Nikita Popov <nikic@php.net> Fri, 2 May 2014 17:01:36 +0200
Parents: d8651fbe1c4caaaedc42cef1dee0dd3b3f1e447e
Branches: phpng
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=65f488ece3f946d53b12b8c265185a483b079dfb
Log:
Add STR_ALLOCA_* API, use in get_method and verify_arg
This avoid unnecessary allocations when using dynamic method
dispatch and class typehints.
Probably there are other places where this should be done as well,
those just stood out for my usage.
Changed paths:
M Zend/zend_execute.c
M Zend/zend_object_handlers.c
M Zend/zend_string.h
Diff:
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 5ed4678..1979f59 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -519,9 +519,13 @@ static inline zval* make_real_object(zval *object_ptr TSRMLS_DC)
ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, ulong fetch_type,
char **class_name, zend_class_entry **pce TSRMLS_DC)
{
- zend_string *key = STR_INIT(cur_arg_info->class_name, cur_arg_info->class_name_len, 0);
+ zend_string *key;
+ ALLOCA_FLAG(use_heap);
+
+ STR_ALLOCA_INIT(key, cur_arg_info->class_name, cur_arg_info->class_name_len, use_heap);
*pce = zend_fetch_class(key, (fetch_type | ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD)
TSRMLS_CC);
- STR_FREE(key);
+ STR_ALLOCA_FREE(key, use_heap);
+
*class_name = (*pce) ? (*pce)->name->val : (char*)cur_arg_info->class_name;
if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
return "implement interface ";
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 64ef01b..2459746 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -1046,17 +1046,18 @@ static union _zend_function *zend_std_get_method(zend_object **obj_ptr,
zend_str
zval *func;
zend_function *fbc;
zend_string *lc_method_name;
+ ALLOCA_FLAG(use_heap);
if (EXPECTED(key != NULL)) {
lc_method_name = Z_STR_P(key);
} else {
- lc_method_name = STR_ALLOC(method_name->len, 0);
+ STR_ALLOCA_ALLOC(lc_method_name, method_name->len, use_heap);
zend_str_tolower_copy(lc_method_name->val, method_name->val, method_name->len);
}
if (UNEXPECTED((func = zend_hash_find(&zobj->ce->function_table, lc_method_name)) ==
NULL)) {
if (UNEXPECTED(!key)) {
- STR_FREE(lc_method_name);
+ STR_ALLOCA_FREE(lc_method_name, use_heap);
}
if (zobj->ce->__call) {
return zend_get_user_call_function(zobj->ce, method_name);
@@ -1113,7 +1114,7 @@ static union _zend_function *zend_std_get_method(zend_object **obj_ptr,
zend_str
}
if (UNEXPECTED(!key)) {
- STR_FREE(lc_method_name);
+ STR_ALLOCA_FREE(lc_method_name, use_heap);
}
return fbc;
}
diff --git a/Zend/zend_string.h b/Zend/zend_string.h
index af83d4d..dfdc74e 100644
--- a/Zend/zend_string.h
+++ b/Zend/zend_string.h
@@ -56,6 +56,20 @@ END_EXTERN_C()
#define _STR_HEADER_SIZE XtOffsetOf(zend_string, val)
+#define STR_ALLOCA_ALLOC(str, _len, use_heap) do { \
+ (str) = do_alloca(_STR_HEADER_SIZE + (_len) + 1, (use_heap)); \
+ GC_REFCOUNT(str) = 1; \
+ (str)->h = 0; \
+ (str)->len = (_len); \
+} while (0)
+#define STR_ALLOCA_INIT(str, s, len, use_heap) do { \
+ STR_ALLOCA_ALLOC(str, len, use_heap); \
+ memcpy((str)->val, (s), (len)); \
+ (str)->val[(len)] = '\0'; \
+} while (0)
+
+#define STR_ALLOCA_FREE(str, use_heap) free_alloca(str, use_heap)
+
static zend_always_inline zend_ulong zend_str_hash_val(zend_string *s)
{
if (!s->h) {