summaryrefslogtreecommitdiff
path: root/ext/reflection/php_reflection.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-05-08 15:30:53 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-05-08 15:43:42 +0200
commitee0fc1b5ae9470e7edd43b608d43a8bea93188d2 (patch)
tree2e22f722bd72ff004111f1ba1ba17dc8fb963967 /ext/reflection/php_reflection.c
parentf778e1a0b2b2535398bd37cb2e63ad06c82f8cd7 (diff)
downloadphp-git-ee0fc1b5ae9470e7edd43b608d43a8bea93188d2.tar.gz
Optimize $name/$class property population in reflection
Instead of going through write_property, directly assign to the respective property slot.
Diffstat (limited to 'ext/reflection/php_reflection.c')
-rw-r--r--ext/reflection/php_reflection.c166
1 files changed, 64 insertions, 102 deletions
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;