Skip to content

Commit bddb085

Browse files
committed
Store unmangled name in ReflectionProperty
Avoid redundant unmangles and string copies, where possible.
1 parent ce7fc2e commit bddb085

File tree

1 file changed

+37
-47
lines changed

1 file changed

+37
-47
lines changed

ext/reflection/php_reflection.c

Lines changed: 37 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ PHPAPI zend_class_entry *reflection_zend_extension_ptr;
114114
typedef struct _property_reference {
115115
zend_class_entry *ce;
116116
zend_property_info prop;
117+
zend_string *unmangled_name;
117118
} property_reference;
118119

119120
/* Struct for parameters */
@@ -137,7 +138,6 @@ typedef enum {
137138
REF_TYPE_PARAMETER,
138139
REF_TYPE_TYPE,
139140
REF_TYPE_PROPERTY,
140-
REF_TYPE_DYNAMIC_PROPERTY,
141141
REF_TYPE_CLASS_CONSTANT
142142
} reflection_type_t;
143143

@@ -229,11 +229,8 @@ static void reflection_free_objects_storage(zend_object *object) /* {{{ */
229229
_free_function(intern->ptr);
230230
break;
231231
case REF_TYPE_PROPERTY:
232-
efree(intern->ptr);
233-
break;
234-
case REF_TYPE_DYNAMIC_PROPERTY:
235232
prop_reference = (property_reference*)intern->ptr;
236-
zend_string_release_ex(prop_reference->prop.name, 0);
233+
zend_string_release_ex(prop_reference->unmangled_name, 0);
237234
efree(intern->ptr);
238235
break;
239236
case REF_TYPE_GENERATOR:
@@ -277,7 +274,7 @@ static zval *reflection_instantiate(zend_class_entry *pce, zval *object) /* {{{
277274

278275
static void _const_string(smart_str *str, char *name, zval *value, char *indent);
279276
static void _function_string(smart_str *str, zend_function *fptr, zend_class_entry *scope, char* indent);
280-
static void _property_string(smart_str *str, zend_property_info *prop, char *prop_name, char* indent);
277+
static void _property_string(smart_str *str, zend_property_info *prop, const char *prop_name, char* indent);
281278
static void _class_const_string(smart_str *str, char *name, zend_class_constant *c, char* indent);
282279
static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char *indent);
283280
static void _extension_string(smart_str *str, zend_module_entry *module, char *indent);
@@ -832,10 +829,8 @@ static void _function_string(smart_str *str, zend_function *fptr, zend_class_ent
832829
/* }}} */
833830

834831
/* {{{ _property_string */
835-
static void _property_string(smart_str *str, zend_property_info *prop, char *prop_name, char* indent)
832+
static void _property_string(smart_str *str, zend_property_info *prop, const char *prop_name, char* indent)
836833
{
837-
const char *class_name;
838-
839834
smart_str_append_printf(str, "%sProperty [ ", indent);
840835
if (!prop) {
841836
smart_str_append_printf(str, "<dynamic> public $%s", prop_name);
@@ -860,11 +855,13 @@ static void _property_string(smart_str *str, zend_property_info *prop, char *pro
860855
smart_str_appends(str, "protected ");
861856
break;
862857
}
863-
if(prop->flags & ZEND_ACC_STATIC) {
858+
if (prop->flags & ZEND_ACC_STATIC) {
864859
smart_str_appends(str, "static ");
865860
}
866-
867-
zend_unmangle_property_name(prop->name, &class_name, (const char**)&prop_name);
861+
if (!prop_name) {
862+
const char *class_name;
863+
zend_unmangle_property_name(prop->name, &class_name, &prop_name);
864+
}
868865
smart_str_append_printf(str, "$%s", prop_name);
869866
}
870867

@@ -1235,23 +1232,19 @@ static void reflection_method_factory(zend_class_entry *ce, zend_function *metho
12351232
/* }}} */
12361233

12371234
/* {{{ reflection_property_factory */
1238-
static void reflection_property_factory(zend_class_entry *ce, zend_property_info *prop, zval *object)
1235+
static void reflection_property_factory(zend_class_entry *ce, zend_string *name, zend_property_info *prop, zval *object)
12391236
{
12401237
reflection_object *intern;
1241-
zval name;
1238+
zval propname;
12421239
zval classname;
12431240
property_reference *reference;
1244-
const char *class_name, *prop_name;
1245-
size_t prop_name_len;
1246-
1247-
zend_unmangle_property_name_ex(prop->name, &class_name, &prop_name, &prop_name_len);
12481241

12491242
if (!(prop->flags & ZEND_ACC_PRIVATE)) {
12501243
/* we have to search the class hierarchy for this (implicit) public or protected property */
12511244
zend_class_entry *tmp_ce = ce, *store_ce = ce;
12521245
zend_property_info *tmp_info = NULL;
12531246

1254-
while (tmp_ce && (tmp_info = zend_hash_str_find_ptr(&tmp_ce->properties_info, prop_name, prop_name_len)) == NULL) {
1247+
while (tmp_ce && (tmp_info = zend_hash_find_ptr(&tmp_ce->properties_info, name)) == NULL) {
12551248
ce = tmp_ce;
12561249
tmp_ce = tmp_ce->parent;
12571250
}
@@ -1263,23 +1256,31 @@ static void reflection_property_factory(zend_class_entry *ce, zend_property_info
12631256
}
12641257
}
12651258

1266-
ZVAL_STRINGL(&name, prop_name, prop_name_len);
1259+
ZVAL_STR_COPY(&propname, name);
12671260
ZVAL_STR_COPY(&classname, prop->ce->name);
12681261

12691262
reflection_instantiate(reflection_property_ptr, object);
12701263
intern = Z_REFLECTION_P(object);
12711264
reference = (property_reference*) emalloc(sizeof(property_reference));
12721265
reference->ce = ce;
12731266
reference->prop = *prop;
1267+
reference->unmangled_name = zend_string_copy(name);
12741268
intern->ptr = reference;
12751269
intern->ref_type = REF_TYPE_PROPERTY;
12761270
intern->ce = ce;
12771271
intern->ignore_visibility = 0;
1278-
reflection_update_property_name(object, &name);
1272+
reflection_update_property_name(object, &propname);
12791273
reflection_update_property_class(object, &classname);
12801274
}
12811275
/* }}} */
12821276

1277+
static void reflection_property_factory_str(zend_class_entry *ce, const char *name_str, size_t name_len, zend_property_info *prop, zval *object)
1278+
{
1279+
zend_string *name = zend_string_init(name_str, name_len, 0);
1280+
reflection_property_factory(ce, name, prop, object);
1281+
zend_string_release(name);
1282+
}
1283+
12831284
/* {{{ reflection_class_constant_factory */
12841285
static void reflection_class_constant_factory(zend_class_entry *ce, zend_string *name_str, zend_class_constant *constant, zval *object)
12851286
{
@@ -4289,21 +4290,19 @@ ZEND_METHOD(reflection_class, getProperty)
42894290
GET_REFLECTION_OBJECT_PTR(ce);
42904291
if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL) {
42914292
if ((property_info->flags & ZEND_ACC_SHADOW) == 0) {
4292-
reflection_property_factory(ce, property_info, return_value);
4293+
reflection_property_factory(ce, name, property_info, return_value);
42934294
return;
42944295
}
42954296
} else if (Z_TYPE(intern->obj) != IS_UNDEF) {
42964297
/* Check for dynamic properties */
42974298
if (zend_hash_exists(Z_OBJ_HT(intern->obj)->get_properties(&intern->obj), name)) {
42984299
zend_property_info property_info_tmp;
42994300
property_info_tmp.flags = ZEND_ACC_IMPLICIT_PUBLIC;
4300-
property_info_tmp.name = zend_string_copy(name);
4301+
property_info_tmp.name = name;
43014302
property_info_tmp.doc_comment = NULL;
43024303
property_info_tmp.ce = ce;
43034304

4304-
reflection_property_factory(ce, &property_info_tmp, return_value);
4305-
intern = Z_REFLECTION_P(return_value);
4306-
intern->ref_type = REF_TYPE_DYNAMIC_PROPERTY;
4305+
reflection_property_factory(ce, name, &property_info_tmp, return_value);
43074306
return;
43084307
}
43094308
}
@@ -4333,7 +4332,7 @@ ZEND_METHOD(reflection_class, getProperty)
43334332
ce = ce2;
43344333

43354334
if ((property_info = zend_hash_str_find_ptr(&ce->properties_info, str_name, str_name_len)) != NULL && (property_info->flags & ZEND_ACC_SHADOW) == 0) {
4336-
reflection_property_factory(ce, property_info, return_value);
4335+
reflection_property_factory_str(ce, str_name, str_name_len, property_info, return_value);
43374336
return;
43384337
}
43394338
}
@@ -4356,7 +4355,10 @@ static int _addproperty(zval *el, int num_args, va_list args, zend_hash_key *has
43564355
}
43574356

43584357
if (pptr->flags & filter) {
4359-
reflection_property_factory(ce, pptr, &property);
4358+
const char *class_name, *prop_name;
4359+
size_t prop_name_len;
4360+
zend_unmangle_property_name_ex(pptr->name, &class_name, &prop_name, &prop_name_len);
4361+
reflection_property_factory_str(ce, prop_name, prop_name_len, pptr, &property);
43604362
add_next_index_zval(retval, &property);
43614363
}
43624364
return 0;
@@ -4389,7 +4391,7 @@ static int _adddynproperty(zval *ptr, int num_args, va_list args, zend_hash_key
43894391
property_info.name = hash_key->key;
43904392
property_info.ce = ce;
43914393
property_info.offset = -1;
4392-
reflection_property_factory(ce, &property_info, &property);
4394+
reflection_property_factory(ce, hash_key->key, &property_info, &property);
43934395
add_next_index_zval(retval, &property);
43944396
}
43954397
return 0;
@@ -5361,13 +5363,14 @@ ZEND_METHOD(reflection_property, __construct)
53615363
reference = (property_reference*) emalloc(sizeof(property_reference));
53625364
if (dynam_prop) {
53635365
reference->prop.flags = ZEND_ACC_IMPLICIT_PUBLIC;
5364-
reference->prop.name = Z_STR(propname);
5366+
reference->prop.name = name;
53655367
reference->prop.doc_comment = NULL;
53665368
reference->prop.ce = ce;
53675369
} else {
53685370
reference->prop = *property_info;
53695371
}
53705372
reference->ce = ce;
5373+
reference->unmangled_name = zend_string_copy(name);
53715374
intern->ptr = reference;
53725375
intern->ref_type = REF_TYPE_PROPERTY;
53735376
intern->ce = ce;
@@ -5387,7 +5390,7 @@ ZEND_METHOD(reflection_property, __toString)
53875390
return;
53885391
}
53895392
GET_REFLECTION_OBJECT_PTR(ref);
5390-
_property_string(&str, &ref->prop, NULL, "");
5393+
_property_string(&str, &ref->prop, ZSTR_VAL(ref->unmangled_name), "");
53915394
RETURN_STR(smart_str_extract(&str));
53925395
}
53935396
/* }}} */
@@ -5505,8 +5508,6 @@ ZEND_METHOD(reflection_property, getValue)
55055508
ZVAL_DEREF(member_p);
55065509
ZVAL_COPY(return_value, member_p);
55075510
} else {
5508-
const char *class_name, *prop_name;
5509-
size_t prop_name_len;
55105511
zval rv;
55115512

55125513
if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &object) == FAILURE) {
@@ -5518,8 +5519,7 @@ ZEND_METHOD(reflection_property, getValue)
55185519
/* Returns from this function */
55195520
}
55205521

5521-
zend_unmangle_property_name_ex(ref->prop.name, &class_name, &prop_name, &prop_name_len);
5522-
member_p = zend_read_property(ref->ce, object, prop_name, prop_name_len, 0, &rv);
5522+
member_p = zend_read_property_ex(ref->ce, object, ref->unmangled_name, 0, &rv);
55235523
if (member_p != &rv) {
55245524
ZVAL_DEREF(member_p);
55255525
ZVAL_COPY(return_value, member_p);
@@ -5583,15 +5583,11 @@ ZEND_METHOD(reflection_property, setValue)
55835583
zval_ptr_dtor(&garbage);
55845584
}
55855585
} else {
5586-
const char *class_name, *prop_name;
5587-
size_t prop_name_len;
5588-
55895586
if (zend_parse_parameters(ZEND_NUM_ARGS(), "oz", &object, &value) == FAILURE) {
55905587
return;
55915588
}
55925589

5593-
zend_unmangle_property_name_ex(ref->prop.name, &class_name, &prop_name, &prop_name_len);
5594-
zend_update_property(ref->ce, object, prop_name, prop_name_len, value);
5590+
zend_update_property_ex(ref->ce, object, ref->unmangled_name, value);
55955591
}
55965592
}
55975593
/* }}} */
@@ -5604,20 +5600,14 @@ ZEND_METHOD(reflection_property, getDeclaringClass)
56045600
property_reference *ref;
56055601
zend_class_entry *tmp_ce, *ce;
56065602
zend_property_info *tmp_info;
5607-
const char *prop_name, *class_name;
5608-
size_t prop_name_len;
56095603

56105604
if (zend_parse_parameters_none() == FAILURE) {
56115605
return;
56125606
}
56135607
GET_REFLECTION_OBJECT_PTR(ref);
56145608

5615-
if (zend_unmangle_property_name_ex(ref->prop.name, &class_name, &prop_name, &prop_name_len) != SUCCESS) {
5616-
RETURN_FALSE;
5617-
}
5618-
56195609
ce = tmp_ce = ref->ce;
5620-
while (tmp_ce && (tmp_info = zend_hash_str_find_ptr(&tmp_ce->properties_info, prop_name, prop_name_len)) != NULL) {
5610+
while (tmp_ce && (tmp_info = zend_hash_find_ptr(&tmp_ce->properties_info, ref->unmangled_name)) != NULL) {
56215611
if (tmp_info->flags & ZEND_ACC_PRIVATE || tmp_info->flags & ZEND_ACC_SHADOW) {
56225612
/* it's a private property, so it can't be inherited */
56235613
break;

0 commit comments

Comments
 (0)