From: Nikita Popov Date: Wed, 8 May 2019 13:30:53 +0000 (+0200) Subject: Optimize $name/$class property population in reflection X-Git-Tag: php-7.4.0alpha1~333 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ee0fc1b5ae9470e7edd43b608d43a8bea93188d2;p=php Optimize $name/$class property population in reflection Instead of going through write_property, directly assign to the respective property slot. --- diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 3fbe78d382..7b7afa9547 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -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;