Skip to content

Commit 691c93f

Browse files
committed
Avoid duplicate work
* Don't iterate trait methods if they don't contain an abstract method * Don't build the exclude and alias table twice
1 parent 172515b commit 691c93f

File tree

1 file changed

+26
-26
lines changed

1 file changed

+26
-26
lines changed

Zend/zend_inheritance.c

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2612,7 +2612,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce, zend_class_e
26122612
}
26132613
/* }}} */
26142614

2615-
static void zend_do_traits_method_binding(zend_class_entry *ce, zend_class_entry **traits, HashTable **exclude_tables, zend_class_entry **aliases, bool verify_abstract) /* {{{ */
2615+
static void zend_do_traits_method_binding(zend_class_entry *ce, zend_class_entry **traits, HashTable **exclude_tables, zend_class_entry **aliases, bool verify_abstract, bool *contains_abstract_methods) /* {{{ */
26162616
{
26172617
uint32_t i;
26182618
zend_string *key;
@@ -2624,6 +2624,7 @@ static void zend_do_traits_method_binding(zend_class_entry *ce, zend_class_entry
26242624
/* copies functions, applies defined aliasing, and excludes unused trait methods */
26252625
ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&traits[i]->function_table, key, fn) {
26262626
if (verify_abstract != (bool) (fn->common.fn_flags & ZEND_ACC_ABSTRACT)) {
2627+
*contains_abstract_methods = true;
26272628
continue;
26282629
}
26292630
zend_traits_copy_functions(key, fn, ce, exclude_tables[i], aliases);
@@ -2641,6 +2642,7 @@ static void zend_do_traits_method_binding(zend_class_entry *ce, zend_class_entry
26412642
if (traits[i]) {
26422643
ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&traits[i]->function_table, key, fn) {
26432644
if (verify_abstract != (bool) (fn->common.fn_flags & ZEND_ACC_ABSTRACT)) {
2645+
*contains_abstract_methods = true;
26442646
continue;
26452647
}
26462648
zend_traits_copy_functions(key, fn, ce, NULL, aliases);
@@ -2929,29 +2931,6 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
29292931
}
29302932
/* }}} */
29312933

2932-
static void zend_do_bind_traits(zend_class_entry *ce, zend_class_entry **traits, bool verify_abstract) /* {{{ */
2933-
{
2934-
HashTable **exclude_tables;
2935-
zend_class_entry **aliases;
2936-
2937-
ZEND_ASSERT(ce->num_traits > 0);
2938-
2939-
/* complete initialization of trait structures in ce */
2940-
zend_traits_init_trait_structures(ce, traits, &exclude_tables, &aliases);
2941-
2942-
/* Flatten all methods into the class */
2943-
zend_do_traits_method_binding(ce, traits, exclude_tables, aliases, verify_abstract);
2944-
2945-
if (aliases) {
2946-
efree(aliases);
2947-
}
2948-
2949-
if (exclude_tables) {
2950-
efree(exclude_tables);
2951-
}
2952-
}
2953-
/* }}} */
2954-
29552934
#define MAX_ABSTRACT_INFO_CNT 3
29562935
#define MAX_ABSTRACT_INFO_FMT "%s%s%s%s"
29572936
#define DISPLAY_ABSTRACT_FN(idx) \
@@ -3560,8 +3539,12 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
35603539
zend_enum_register_funcs(ce);
35613540
}
35623541

3542+
HashTable **trait_exclude_tables;
3543+
zend_class_entry **trait_aliases;
3544+
bool trait_contains_abstract_methods = false;
35633545
if (ce->num_traits) {
3564-
zend_do_bind_traits(ce, traits_and_interfaces, false);
3546+
zend_traits_init_trait_structures(ce, traits_and_interfaces, &trait_exclude_tables, &trait_aliases);
3547+
zend_do_traits_method_binding(ce, traits_and_interfaces, trait_exclude_tables, trait_aliases, false, &trait_contains_abstract_methods);
35653548
zend_do_traits_constant_binding(ce, traits_and_interfaces);
35663549
zend_do_traits_property_binding(ce, traits_and_interfaces);
35673550
}
@@ -3572,7 +3555,24 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
35723555
zend_do_inheritance(ce, parent);
35733556
}
35743557
if (ce->num_traits) {
3575-
zend_do_bind_traits(ce, traits_and_interfaces, true);
3558+
if (trait_contains_abstract_methods) {
3559+
zend_do_traits_method_binding(ce, traits_and_interfaces, trait_exclude_tables, trait_aliases, true, &trait_contains_abstract_methods);
3560+
}
3561+
3562+
if (trait_exclude_tables) {
3563+
for (i = 0; i < ce->num_traits; i++) {
3564+
if (traits_and_interfaces[i]) {
3565+
if (trait_exclude_tables[i]) {
3566+
zend_hash_destroy(trait_exclude_tables[i]);
3567+
FREE_HASHTABLE(trait_exclude_tables[i]);
3568+
}
3569+
}
3570+
}
3571+
efree(trait_exclude_tables);
3572+
}
3573+
if (trait_aliases) {
3574+
efree(trait_aliases);
3575+
}
35763576

35773577
zend_function *fn;
35783578
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, fn) {

0 commit comments

Comments
 (0)