Skip to content

Commit 9b2d708

Browse files
committed
Reduce spl_autoload() overhead
1 parent bb2f1a6 commit 9b2d708

File tree

1 file changed

+37
-11
lines changed

1 file changed

+37
-11
lines changed

ext/spl/php_spl.c

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ ZEND_DECLARE_MODULE_GLOBALS(spl)
5050

5151
#define SPL_DEFAULT_FILE_EXTENSIONS ".inc,.php"
5252

53+
static zend_function *spl_autoload_fn = NULL;
54+
static zend_function *spl_autoload_call_fn = NULL;
55+
5356
/* {{{ PHP_GINIT_FUNCTION
5457
*/
5558
static PHP_GINIT_FUNCTION(spl)
@@ -461,7 +464,23 @@ PHP_FUNCTION(spl_autoload_call)
461464
SPL_G(autoload_running) = l_autoload_running;
462465
} else {
463466
/* do not use or overwrite &EG(autoload_func) here */
464-
zend_call_method_with_1_params(NULL, NULL, NULL, "spl_autoload", NULL, class_name);
467+
zend_fcall_info fcall_info;
468+
zend_fcall_info_cache fcall_cache;
469+
470+
fcall_info.size = sizeof(fcall_info);
471+
ZVAL_STR_COPY(&fcall_info.function_name, spl_autoload_fn->common.function_name);
472+
fcall_info.retval = NULL;
473+
fcall_info.param_count = 1;
474+
fcall_info.params = class_name;
475+
fcall_info.object = NULL;
476+
fcall_info.no_separation = 1;
477+
478+
fcall_cache.function_handler = spl_autoload_fn;
479+
fcall_cache.called_scope = NULL;
480+
fcall_cache.object = NULL;
481+
482+
zend_call_function(&fcall_info, &fcall_cache);
483+
zval_ptr_dtor(&fcall_info.function_name);
465484
}
466485
} /* }}} */
467486

@@ -595,7 +614,7 @@ PHP_FUNCTION(spl_autoload_register)
595614
zend_hash_init(SPL_G(autoload_functions), 1, NULL, autoload_func_info_dtor, 0);
596615
}
597616

598-
spl_func_ptr = zend_hash_str_find_ptr(EG(function_table), "spl_autoload", sizeof("spl_autoload") - 1);
617+
spl_func_ptr = spl_autoload_fn;
599618

600619
if (EG(autoload_func) == spl_func_ptr) { /* registered already, so we insert that first */
601620
autoload_func_info spl_alfi;
@@ -604,7 +623,7 @@ PHP_FUNCTION(spl_autoload_register)
604623
ZVAL_UNDEF(&spl_alfi.obj);
605624
ZVAL_UNDEF(&spl_alfi.closure);
606625
spl_alfi.ce = NULL;
607-
zend_hash_str_add_mem(SPL_G(autoload_functions), "spl_autoload", sizeof("spl_autoload") - 1,
626+
zend_hash_add_mem(SPL_G(autoload_functions), spl_autoload_fn->common.function_name,
608627
&spl_alfi, sizeof(autoload_func_info));
609628
if (prepend && SPL_G(autoload_functions)->nNumOfElements > 1) {
610629
/* Move the newly created element to the head of the hashtable */
@@ -640,9 +659,9 @@ PHP_FUNCTION(spl_autoload_register)
640659
}
641660

642661
if (SPL_G(autoload_functions)) {
643-
EG(autoload_func) = zend_hash_str_find_ptr(EG(function_table), "spl_autoload_call", sizeof("spl_autoload_call") - 1);
662+
EG(autoload_func) = spl_autoload_call_fn;
644663
} else {
645-
EG(autoload_func) = zend_hash_str_find_ptr(EG(function_table), "spl_autoload", sizeof("spl_autoload") - 1);
664+
EG(autoload_func) = spl_autoload_fn;
646665
}
647666

648667
RETURN_TRUE;
@@ -697,7 +716,7 @@ PHP_FUNCTION(spl_autoload_unregister)
697716
zend_string_release_ex(func_name, 0);
698717

699718
if (SPL_G(autoload_functions)) {
700-
if (ZSTR_LEN(lc_name) == sizeof("spl_autoload_call") - 1 && !strcmp(ZSTR_VAL(lc_name), "spl_autoload_call")) {
719+
if (zend_string_equals(lc_name, spl_autoload_call_fn->common.function_name)) {
701720
/* remove all */
702721
if (!SPL_G(autoload_running)) {
703722
zend_hash_destroy(SPL_G(autoload_functions));
@@ -718,9 +737,9 @@ PHP_FUNCTION(spl_autoload_unregister)
718737
success = zend_hash_del(SPL_G(autoload_functions), lc_name);
719738
}
720739
}
721-
} else if (ZSTR_LEN(lc_name) == sizeof("spl_autoload")-1 && !strcmp(ZSTR_VAL(lc_name), "spl_autoload")) {
740+
} else if (zend_string_equals(lc_name, spl_autoload_fn->common.function_name)) {
722741
/* register single spl_autoload() */
723-
spl_func_ptr = zend_hash_str_find_ptr(EG(function_table), "spl_autoload", sizeof("spl_autoload") - 1);
742+
spl_func_ptr = spl_autoload_fn;
724743

725744
if (EG(autoload_func) == spl_func_ptr) {
726745
success = SUCCESS;
@@ -744,15 +763,18 @@ PHP_FUNCTION(spl_autoload_functions)
744763
}
745764

746765
if (!EG(autoload_func)) {
747-
if ((fptr = zend_hash_str_find_ptr(EG(function_table), ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1))) {
766+
if ((fptr = zend_hash_find_ptr(EG(function_table), ZSTR_KNOWN(ZEND_STR_MAGIC_AUTOLOAD)))) {
767+
zval tmp;
768+
748769
array_init(return_value);
749-
add_next_index_stringl(return_value, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME)-1);
770+
ZVAL_STR_COPY(&tmp, ZSTR_KNOWN(ZEND_STR_MAGIC_AUTOLOAD));
771+
zend_hash_next_index_insert_new(Z_ARR_P(return_value), &tmp);
750772
return;
751773
}
752774
RETURN_FALSE;
753775
}
754776

755-
fptr = zend_hash_str_find_ptr(EG(function_table), "spl_autoload_call", sizeof("spl_autoload_call") - 1);
777+
fptr = spl_autoload_call_fn;
756778

757779
if (EG(autoload_func) == fptr) {
758780
zend_string *key;
@@ -980,6 +1002,10 @@ PHP_MINIT_FUNCTION(spl)
9801002
PHP_MINIT(spl_fixedarray)(INIT_FUNC_ARGS_PASSTHRU);
9811003
PHP_MINIT(spl_observer)(INIT_FUNC_ARGS_PASSTHRU);
9821004

1005+
spl_autoload_fn = zend_hash_str_find_ptr(CG(function_table), "spl_autoload", sizeof("spl_autoload") - 1);
1006+
spl_autoload_call_fn = zend_hash_str_find_ptr(CG(function_table), "spl_autoload_call", sizeof("spl_autoload_call") - 1);
1007+
ZEND_ASSERT(spl_autoload_fn != NULL && spl_autoload_call_fn != NULL);
1008+
9831009
return SUCCESS;
9841010
}
9851011
/* }}} */

0 commit comments

Comments
 (0)