]> granicus.if.org Git - php/commitdiff
Cache the class_name typehint key in arg_info
authorBob Weinand <bobwei9@hotmail.com>
Fri, 12 Jun 2015 15:26:41 +0000 (17:26 +0200)
committerBob Weinand <bobwei9@hotmail.com>
Fri, 12 Jun 2015 15:26:53 +0000 (17:26 +0200)
This leads to up to 2% improvement on one tested real world application by not having to always recalculate the lowercased string and its hash

Zend/zend_API.h
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c
Zend/zend_opcode.c
ext/opcache/zend_file_cache.c
ext/opcache/zend_persist.c
ext/opcache/zend_persist_calc.c

index b01b041859f7146d747765ef0bda593a25369887..83e5265fd4e9b7c6e52b7176cf83840e7ae9df7b 100644 (file)
@@ -68,9 +68,9 @@ typedef struct _zend_fcall_info_cache {
 #define ZEND_FUNCTION(name)                            ZEND_NAMED_FUNCTION(ZEND_FN(name))
 #define ZEND_METHOD(classname, name)   ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name))
 
-#define ZEND_FENTRY(zend_name, name, arg_info, flags)  { #zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags },
+#define ZEND_FENTRY(zend_name, name, arg_info, flags)  { #zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_internal_arg_info)-1), flags },
 
-#define ZEND_RAW_FENTRY(zend_name, name, arg_info, flags)   { zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags },
+#define ZEND_RAW_FENTRY(zend_name, name, arg_info, flags)   { zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_internal_arg_info)-1), flags },
 #define ZEND_RAW_NAMED_FE(zend_name, name, arg_info) ZEND_RAW_FENTRY(#zend_name, name, arg_info, 0)
 
 #define ZEND_NAMED_FE(zend_name, name, arg_info)       ZEND_FENTRY(zend_name, name, arg_info, 0)
index 902d37c5038910956ece0b3883be1131f939ef57..a649f8fcaf3585035c6da332ef6198e8db39ddcc 100644 (file)
@@ -4238,9 +4238,11 @@ static void zend_compile_typename(zend_ast *ast, zend_arg_info *arg_info) /* {{{
                        if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) {
                                class_name = zend_resolve_class_name_ast(ast);
                                zend_assert_valid_class_name(class_name);
+                               arg_info->lower_class_name = zend_string_tolower(class_name);
                        } else {
                                zend_ensure_valid_class_fetch_type(fetch_type);
                                zend_string_addref(class_name);
+                               arg_info->lower_class_name = NULL;
                        }
 
                        arg_info->type_hint = IS_OBJECT;
index d258289a13594004d475ebc93bcc971529a49bc8..eccbb84affce30c65e1d0f0205184288bbc0732b 100644 (file)
@@ -297,6 +297,7 @@ typedef struct _zend_internal_arg_info {
        zend_uchar pass_by_reference;
        zend_bool allow_null;
        zend_bool is_variadic;
+       void *reserved; /* to align with zend_arg_info */
 } zend_internal_arg_info;
 
 /* arg_info for user functions */
@@ -307,6 +308,7 @@ typedef struct _zend_arg_info {
        zend_uchar pass_by_reference;
        zend_bool allow_null;
        zend_bool is_variadic;
+       zend_string *lower_class_name;
 } zend_arg_info;
 
 /* the following structure repeats the layout of zend_internal_arg_info,
index 386ddf398913dab4dfd0e873c8f529e17b724dab..e63fc2dd321b67845a8ef5e907cb023f900f29e1 100644 (file)
@@ -587,7 +587,12 @@ ZEND_API char * zend_verify_internal_arg_class_kind(const zend_internal_arg_info
 
 ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, char **class_name, zend_class_entry **pce)
 {
-       *pce = zend_fetch_class(cur_arg_info->class_name, (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
+       /* optimization to not always recalculate the lowercase name and hash */
+       if (cur_arg_info->lower_class_name) {
+               *pce = zend_hash_find_ptr(EG(class_table), cur_arg_info->lower_class_name);
+       } else { /* "extra" fetch type */
+               *pce = zend_fetch_class(cur_arg_info->class_name, (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
+       }
 
        *class_name = (*pce) ? (*pce)->name->val : cur_arg_info->class_name->val;
        if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
index 1c760c5902ec346ea7cb79102f59787d2c799fb4..abb91b1ee3e778b751f1258e2ae0bf6022afc589 100644 (file)
@@ -410,6 +410,10 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
                        }
                        if (arg_info[i].class_name) {
                                zend_string_release(arg_info[i].class_name);
+
+                               if (arg_info[i].lower_class_name) {
+                                       zend_string_release(arg_info[i].lower_class_name);
+                               }
                        }
                }
                efree(arg_info);
index 219bb508208ea8b0a6c5de6bc3c79652de8b3171..10a149c9f68ecda4bd164fad6bd61aba81148548 100644 (file)
@@ -438,6 +438,9 @@ static void zend_file_cache_serialize_op_array(zend_op_array            *op_arra
                                if (!IS_SERIALIZED(p->class_name)) {
                                        SERIALIZE_STR(p->class_name);
                                }
+                               if (p->class_name && !IS_SERIALIZED(p->lower_class_name)) {
+                                       SERIALIZE_STR(p->lower_class_name);
+                               }
                                p++;
                        }
                }
@@ -962,6 +965,9 @@ static void zend_file_cache_unserialize_op_array(zend_op_array           *op_arr
                                if (!IS_UNSERIALIZED(p->class_name)) {
                                        UNSERIALIZE_STR(p->class_name);
                                }
+                               if (p->class_name && !IS_UNSERIALIZED(p->lower_class_name)) {
+                                       UNSERIALIZE_STR(p->lower_class_name);
+                               }
                                p++;
                        }
                }
index 09eebe0d02523252ec8c30780893e0a24f47905f..585c34f46e238ba653c009892ea51b934c16a7ec 100644 (file)
@@ -581,6 +581,9 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
                                }
                                if (arg_info[i].class_name) {
                                        zend_accel_store_interned_string(arg_info[i].class_name);
+                                       if (arg_info[i].lower_class_name) {
+                                               zend_accel_store_interned_string(arg_info[i].lower_class_name);
+                                       }
                                }
                        }
                }
index 98412109a5ca0f6fa08803a22148fb00eeeeff98..d721db2febfbc2a02a34aab36ea3f7c843c03d3f 100644 (file)
@@ -225,6 +225,9 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array)
                        }
                        if (arg_info[i].class_name) {
                                ADD_INTERNED_STRING(arg_info[i].class_name, 1);
+                               if (arg_info[i].lower_class_name) {
+                                       ADD_INTERNED_STRING(arg_info[i].lower_class_name, 1);
+                               }
                        }
                }
        }