]> granicus.if.org Git - php/commitdiff
Optimize $name/$class property population in reflection
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 8 May 2019 13:30:53 +0000 (15:30 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 8 May 2019 13:43:42 +0000 (15:43 +0200)
Instead of going through write_property, directly assign to the
respective property slot.

ext/reflection/php_reflection.c

index 3fbe78d382671401bbe921764c7ee4788642bfae..7b7afa9547baa6f7f4fe9993e690dd4997cfa6bd 100644 (file)
@@ -54,19 +54,17 @@ ZEND_DECLARE_MODULE_GLOBALS(reflection)
 
 #define REFLECTION_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(reflection, v)
 
-#define reflection_update_property(object, name, value) do { \
-               zval member; \
-               ZVAL_STR(&member, name); \
-               zend_std_write_property(object, &member, value, NULL); \
-               Z_TRY_DELREF_P(value); \
-               zval_ptr_dtor(&member); \
-       } while (0)
-
-#define reflection_update_property_name(object, value) \
-       reflection_update_property(object, ZSTR_KNOWN(ZEND_STR_NAME), value)
+static zend_always_inline zval *reflection_prop_name(zval *object) {
+       /* $name is always in the first property slot. */
+       ZEND_ASSERT(Z_OBJCE_P(object)->default_properties_count >= 1);
+       return &Z_OBJ_P(object)->properties_table[0];
+}
 
-#define reflection_update_property_class(object, value) \
-       reflection_update_property(object, ZSTR_KNOWN(ZEND_STR_CLASS), value)
+static zend_always_inline zval *reflection_prop_class(zval *object) {
+       /* $class is always in the second property slot. */
+       ZEND_ASSERT(Z_OBJCE_P(object)->default_properties_count >= 2);
+       return &Z_OBJ_P(object)->properties_table[1];
+}
 
 /* Class entry pointers */
 PHPAPI zend_class_entry *reflector_ptr;
@@ -1071,15 +1069,13 @@ static void _function_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
 PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object)
 {
        reflection_object *intern;
-       zval name;
 
-       ZVAL_STR_COPY(&name, ce->name);
        reflection_instantiate(reflection_class_ptr, object);
        intern = Z_REFLECTION_P(object);
        intern->ptr = ce;
        intern->ref_type = REF_TYPE_OTHER;
        intern->ce = ce;
-       reflection_update_property_name(object, &name);
+       ZVAL_STR_COPY(reflection_prop_name(object), ce->name);
 }
 /* }}} */
 
@@ -1087,7 +1083,6 @@ PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object)
 static void reflection_extension_factory(zval *object, const char *name_str)
 {
        reflection_object *intern;
-       zval name;
        size_t name_len = strlen(name_str);
        zend_string *lcname;
        struct _zend_module_entry *module;
@@ -1102,11 +1097,10 @@ static void reflection_extension_factory(zval *object, const char *name_str)
 
        reflection_instantiate(reflection_extension_ptr, object);
        intern = Z_REFLECTION_P(object);
-       ZVAL_STRINGL(&name, module->name, name_len);
        intern->ptr = module;
        intern->ref_type = REF_TYPE_OTHER;
        intern->ce = NULL;
-       reflection_update_property_name(object, &name);
+       ZVAL_STRINGL(reflection_prop_name(object), module->name, name_len);
 }
 /* }}} */
 
@@ -1115,18 +1109,8 @@ static void reflection_parameter_factory(zend_function *fptr, zval *closure_obje
 {
        reflection_object *intern;
        parameter_reference *reference;
-       zval name;
+       zval *prop_name;
 
-       if (arg_info->name) {
-               if (fptr->type == ZEND_INTERNAL_FUNCTION &&
-                   !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
-                       ZVAL_STRING(&name, ((zend_internal_arg_info*)arg_info)->name);
-               } else {
-                       ZVAL_STR_COPY(&name, arg_info->name);
-               }
-       } else {
-               ZVAL_NULL(&name);
-       }
        reflection_instantiate(reflection_parameter_ptr, object);
        intern = Z_REFLECTION_P(object);
        reference = (parameter_reference*) emalloc(sizeof(parameter_reference));
@@ -1141,7 +1125,18 @@ static void reflection_parameter_factory(zend_function *fptr, zval *closure_obje
                Z_ADDREF_P(closure_object);
                ZVAL_COPY_VALUE(&intern->obj, closure_object);
        }
-       reflection_update_property_name(object, &name);
+
+       prop_name = reflection_prop_name(object);
+       if (arg_info->name) {
+               if (fptr->type == ZEND_INTERNAL_FUNCTION &&
+                   !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
+                       ZVAL_STRING(prop_name, ((zend_internal_arg_info*)arg_info)->name);
+               } else {
+                       ZVAL_STR_COPY(prop_name, arg_info->name);
+               }
+       } else {
+               ZVAL_NULL(prop_name);
+       }
 }
 /* }}} */
 
@@ -1164,10 +1159,6 @@ static void reflection_type_factory(zend_type type, zval *object)
 static void reflection_function_factory(zend_function *function, zval *closure_object, zval *object)
 {
        reflection_object *intern;
-       zval name;
-
-       ZVAL_STR_COPY(&name, function->common.function_name);
-
        reflection_instantiate(reflection_function_ptr, object);
        intern = Z_REFLECTION_P(object);
        intern->ptr = function;
@@ -1177,7 +1168,7 @@ static void reflection_function_factory(zend_function *function, zval *closure_o
                Z_ADDREF_P(closure_object);
                ZVAL_COPY_VALUE(&intern->obj, closure_object);
        }
-       reflection_update_property_name(object, &name);
+       ZVAL_STR_COPY(reflection_prop_name(object), function->common.function_name);
 }
 /* }}} */
 
@@ -1185,12 +1176,7 @@ static void reflection_function_factory(zend_function *function, zval *closure_o
 static void reflection_method_factory(zend_class_entry *ce, zend_function *method, zval *closure_object, zval *object)
 {
        reflection_object *intern;
-       zval name;
-       zval classname;
 
-       ZVAL_STR_COPY(&name, (method->common.scope && method->common.scope->trait_aliases)?
-                       zend_resolve_method_name(ce, method) : method->common.function_name);
-       ZVAL_STR_COPY(&classname, method->common.scope->name);
        reflection_instantiate(reflection_method_ptr, object);
        intern = Z_REFLECTION_P(object);
        intern->ptr = method;
@@ -1200,8 +1186,11 @@ static void reflection_method_factory(zend_class_entry *ce, zend_function *metho
                Z_ADDREF_P(closure_object);
                ZVAL_COPY_VALUE(&intern->obj, closure_object);
        }
-       reflection_update_property_name(object, &name);
-       reflection_update_property_class(object, &classname);
+
+       ZVAL_STR_COPY(reflection_prop_name(object),
+               (method->common.scope && method->common.scope->trait_aliases)
+                       ? zend_resolve_method_name(ce, method) : method->common.function_name);
+       ZVAL_STR_COPY(reflection_prop_class(object), method->common.scope->name);
 }
 /* }}} */
 
@@ -1209,8 +1198,6 @@ static void reflection_method_factory(zend_class_entry *ce, zend_function *metho
 static void reflection_property_factory(zend_class_entry *ce, zend_string *name, zend_property_info *prop, zval *object, zend_bool dynamic)
 {
        reflection_object *intern;
-       zval propname;
-       zval classname;
        property_reference *reference;
 
        if (!(prop->flags & ZEND_ACC_PRIVATE)) {
@@ -1230,9 +1217,6 @@ static void reflection_property_factory(zend_class_entry *ce, zend_string *name,
                }
        }
 
-       ZVAL_STR_COPY(&propname, name);
-       ZVAL_STR_COPY(&classname, prop->ce->name);
-
        reflection_instantiate(reflection_property_ptr, object);
        intern = Z_REFLECTION_P(object);
        reference = (property_reference*) emalloc(sizeof(property_reference));
@@ -1243,8 +1227,8 @@ static void reflection_property_factory(zend_class_entry *ce, zend_string *name,
        intern->ref_type = REF_TYPE_PROPERTY;
        intern->ce = ce;
        intern->ignore_visibility = 0;
-       reflection_update_property_name(object, &propname);
-       reflection_update_property_class(object, &classname);
+       ZVAL_STR_COPY(reflection_prop_name(object), name);
+       ZVAL_STR_COPY(reflection_prop_class(object), prop->ce->name);
 }
 /* }}} */
 
@@ -1259,11 +1243,6 @@ static void reflection_property_factory_str(zend_class_entry *ce, const char *na
 static void reflection_class_constant_factory(zend_class_entry *ce, zend_string *name_str, zend_class_constant *constant, zval *object)
 {
        reflection_object *intern;
-       zval name;
-       zval classname;
-
-       ZVAL_STR_COPY(&name, name_str);
-       ZVAL_STR_COPY(&classname, ce->name);
 
        reflection_instantiate(reflection_class_constant_ptr, object);
        intern = Z_REFLECTION_P(object);
@@ -1271,8 +1250,9 @@ static void reflection_class_constant_factory(zend_class_entry *ce, zend_string
        intern->ref_type = REF_TYPE_CLASS_CONSTANT;
        intern->ce = constant->ce;
        intern->ignore_visibility = 0;
-       reflection_update_property_name(object, &name);
-       reflection_update_property_class(object, &classname);
+
+       ZVAL_STR_COPY(reflection_prop_name(object), name_str);
+       ZVAL_STR_COPY(reflection_prop_class(object), ce->name);
 }
 /* }}} */
 
@@ -1510,7 +1490,6 @@ ZEND_METHOD(reflection_function, export)
    Constructor. Throws an Exception in case the given function does not exist */
 ZEND_METHOD(reflection_function, __construct)
 {
-       zval name;
        zval *object;
        zval *closure = NULL;
        reflection_object *intern;
@@ -1549,8 +1528,7 @@ ZEND_METHOD(reflection_function, __construct)
                }
        }
 
-       ZVAL_STR_COPY(&name, fptr->common.function_name);
-       reflection_update_property_name(object, &name);
+       ZVAL_STR_COPY(reflection_prop_name(object), fptr->common.function_name);
        intern->ptr = fptr;
        intern->ref_type = REF_TYPE_FUNCTION;
        if (closure) {
@@ -2247,7 +2225,7 @@ ZEND_METHOD(reflection_parameter, __construct)
        parameter_reference *ref;
        zval *reference, *parameter;
        zval *object;
-       zval name;
+       zval *prop_name;
        reflection_object *intern;
        zend_function *fptr;
        struct _zend_arg_info *arg_info;
@@ -2401,18 +2379,6 @@ ZEND_METHOD(reflection_parameter, __construct)
                }
        }
 
-       if (arg_info[position].name) {
-               if (fptr->type == ZEND_INTERNAL_FUNCTION &&
-                   !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
-                       ZVAL_STRING(&name, ((zend_internal_arg_info*)arg_info)[position].name);
-               } else {
-                       ZVAL_STR_COPY(&name, arg_info[position].name);
-               }
-       } else {
-               ZVAL_NULL(&name);
-       }
-       reflection_update_property_name(object, &name);
-
        ref = (parameter_reference*) emalloc(sizeof(parameter_reference));
        ref->arg_info = &arg_info[position];
        ref->offset = (uint32_t)position;
@@ -2425,6 +2391,18 @@ ZEND_METHOD(reflection_parameter, __construct)
        if (reference && is_closure) {
                ZVAL_COPY_VALUE(&intern->obj, reference);
        }
+
+       prop_name = reflection_prop_name(object);
+       if (arg_info[position].name) {
+               if (fptr->type == ZEND_INTERNAL_FUNCTION &&
+                   !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
+                       ZVAL_STRING(prop_name, ((zend_internal_arg_info*)arg_info)[position].name);
+               } else {
+                       ZVAL_STR_COPY(prop_name, arg_info[position].name);
+               }
+       } else {
+               ZVAL_NULL(prop_name);
+       }
 }
 /* }}} */
 
@@ -2923,7 +2901,7 @@ ZEND_METHOD(reflection_method, export)
    Constructor. Throws an Exception in case the given method does not exist */
 ZEND_METHOD(reflection_method, __construct)
 {
-       zval name, *classname;
+       zval *classname;
        zval *object, *orig_obj;
        reflection_object *intern;
        char *lcname;
@@ -3004,10 +2982,8 @@ ZEND_METHOD(reflection_method, __construct)
        }
        efree(lcname);
 
-       ZVAL_STR_COPY(&name, mptr->common.scope->name);
-       reflection_update_property_class(object, &name);
-       ZVAL_STR_COPY(&name, mptr->common.function_name);
-       reflection_update_property_name(object, &name);
+       ZVAL_STR_COPY(reflection_prop_name(object), mptr->common.function_name);
+       ZVAL_STR_COPY(reflection_prop_class(object), mptr->common.scope->name);
        intern->ptr = mptr;
        intern->ref_type = REF_TYPE_FUNCTION;
        intern->ce = ce;
@@ -3493,7 +3469,7 @@ ZEND_METHOD(reflection_method, setAccessible)
    Constructor. Throws an Exception in case the given class constant does not exist */
 ZEND_METHOD(reflection_class_constant, __construct)
 {
-       zval *classname, *object, name, cname;
+       zval *classname, *object;
        zend_string *constname;
        reflection_object *intern;
        zend_class_entry *ce;
@@ -3530,15 +3506,12 @@ ZEND_METHOD(reflection_class_constant, __construct)
                return;
        }
 
-       ZVAL_STR_COPY(&name, constname);
-       ZVAL_STR_COPY(&cname, ce->name);
-
        intern->ptr = constant;
        intern->ref_type = REF_TYPE_CLASS_CONSTANT;
        intern->ce = constant->ce;
        intern->ignore_visibility = 0;
-       reflection_update_property_name(object, &name);
-       reflection_update_property_class(object, &cname);
+       ZVAL_STR_COPY(reflection_prop_name(object), constname);
+       ZVAL_STR_COPY(reflection_prop_class(object), ce->name);
 }
 /* }}} */
 
@@ -3692,7 +3665,6 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob
 {
        zval *argument;
        zval *object;
-       zval classname;
        reflection_object *intern;
        zend_class_entry *ce;
 
@@ -3710,8 +3682,7 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob
        intern = Z_REFLECTION_P(object);
 
        if (Z_TYPE_P(argument) == IS_OBJECT) {
-               ZVAL_STR_COPY(&classname, Z_OBJCE_P(argument)->name);
-               reflection_update_property_name(object, &classname);
+               ZVAL_STR_COPY(reflection_prop_name(object), Z_OBJCE_P(argument)->name);
                intern->ptr = Z_OBJCE_P(argument);
                if (is_object) {
                        ZVAL_COPY(&intern->obj, argument);
@@ -3725,9 +3696,7 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob
                        return;
                }
 
-               ZVAL_STR_COPY(&classname, ce->name);
-               reflection_update_property_name(object, &classname);
-
+               ZVAL_STR_COPY(reflection_prop_name(object), ce->name);
                intern->ptr = ce;
        }
        intern->ref_type = REF_TYPE_OTHER;
@@ -5230,7 +5199,7 @@ ZEND_METHOD(reflection_class_constant, export)
    Constructor. Throws an Exception in case the given property does not exist */
 ZEND_METHOD(reflection_property, __construct)
 {
-       zval propname, cname, *classname;
+       zval *classname;
        zend_string *name;
        int dynam_prop = 0;
        zval *object;
@@ -5293,15 +5262,12 @@ ZEND_METHOD(reflection_property, __construct)
                }
        }
 
+       ZVAL_STR_COPY(reflection_prop_name(object), name);
        if (dynam_prop == 0) {
-               ZVAL_STR_COPY(&cname, property_info->ce->name);
+               ZVAL_STR_COPY(reflection_prop_class(object), property_info->ce->name);
        } else {
-               ZVAL_STR_COPY(&cname, ce->name);
+               ZVAL_STR_COPY(reflection_prop_class(object), ce->name);
        }
-       reflection_update_property_class(object, &cname);
-
-       ZVAL_STR_COPY(&propname, name);
-       reflection_update_property_name(object, &propname);
 
        reference = (property_reference*) emalloc(sizeof(property_reference));
        if (dynam_prop) {
@@ -5678,7 +5644,6 @@ ZEND_METHOD(reflection_extension, export)
    Constructor. Throws an Exception in case the given extension does not exist */
 ZEND_METHOD(reflection_extension, __construct)
 {
-       zval name;
        zval *object;
        char *lcname;
        reflection_object *intern;
@@ -5702,8 +5667,7 @@ ZEND_METHOD(reflection_extension, __construct)
                return;
        }
        free_alloca(lcname, use_heap);
-       ZVAL_STRING(&name, module->name);
-       reflection_update_property_name(object, &name);
+       ZVAL_STRING(reflection_prop_name(object), module->name);
        intern->ptr = module;
        intern->ref_type = REF_TYPE_OTHER;
        intern->ce = NULL;
@@ -6036,7 +6000,6 @@ ZEND_METHOD(reflection_zend_extension, export)
        Constructor. Throws an Exception in case the given Zend extension does not exist */
 ZEND_METHOD(reflection_zend_extension, __construct)
 {
-       zval name;
        zval *object;
        reflection_object *intern;
        zend_extension *extension;
@@ -6056,8 +6019,7 @@ ZEND_METHOD(reflection_zend_extension, __construct)
                                "Zend Extension %s does not exist", name_str);
                return;
        }
-       ZVAL_STRING(&name, extension->name);
-       reflection_update_property_name(object, &name);
+       ZVAL_STRING(reflection_prop_name(object), extension->name);
        intern->ptr = extension;
        intern->ref_type = REF_TYPE_OTHER;
        intern->ce = NULL;