com php-src: spl_autoload_call() optimization: ex t/spl/php_spl.c

[email protected] (Dmitry Stogov)
Newsgroups php.cvs
Message-ID <[email protected]>
Commit:    c01afdb68cbee48aed3b5b0937ce5b469258d4f6
Author:    Dmitry Stogov <[email protected]>         Wed, 10 May 2017 13:27:49 +0300
Parents:   c8f073d0d73b822c3190484be5a9053a92027015
Branches:  master

Link:       http://git.php.net/?p=php-src.git;a=commitdiff;h=c01afdb68cbee48aed3b5b0937ce5b469258d4f6

Log:
spl_autoload_call() optimization

Changed paths:
  M  ext/spl/php_spl.c


Diff:
diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c
index 3858890..092fc54 100644
--- a/ext/spl/php_spl.c
+++ b/ext/spl/php_spl.c
@@ -392,7 +392,7 @@ static void autoload_func_info_dtor(zval *element)
  Try all registerd autoload function to load the requested class */
 PHP_FUNCTION(spl_autoload_call)
 {
-	zval *class_name, *retval = NULL;
+	zval *class_name, retval;
 	zend_string *lc_name, *func_name;
 	autoload_func_info *alfi;
 
@@ -403,34 +403,64 @@ PHP_FUNCTION(spl_autoload_call)
 	if (SPL_G(autoload_functions)) {
 		HashPosition pos;
 		zend_ulong num_idx;
+		zend_function *func;
+		zend_fcall_info fci;
+		zend_fcall_info_cache fcic;
+		zend_class_entry *called_scope = zend_get_called_scope(execute_data);
 		int l_autoload_running = SPL_G(autoload_running);
+
 		SPL_G(autoload_running) = 1;
-		lc_name = zend_string_alloc(Z_STRLEN_P(class_name), 0);
-		zend_str_tolower_copy(ZSTR_VAL(lc_name), Z_STRVAL_P(class_name), Z_STRLEN_P(class_name));
+		lc_name = zend_string_tolower(Z_STR_P(class_name));
+
+		fci.size = sizeof(fci);
+		fci.retval = &retval;
+		fci.param_count = 1;
+		fci.params = class_name;
+		fci.no_separation = 1;
+
+		ZVAL_UNDEF(&fci.function_name); /* Unused */
+		fcic.initialized = 1;
+
 		zend_hash_internal_pointer_reset_ex(SPL_G(autoload_functions), &pos);
 		while (zend_hash_get_current_key_ex(SPL_G(autoload_functions), &func_name, &num_idx, &pos) == HASH_KEY_IS_STRING) {
 			alfi = zend_hash_get_current_data_ptr_ex(SPL_G(autoload_functions), &pos);
-			if (UNEXPECTED(alfi->func_ptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
-				zend_function *copy = emalloc(sizeof(zend_op_array));
-
-				memcpy(copy, alfi->func_ptr, sizeof(zend_op_array));
-				copy->op_array.function_name = zend_string_copy(alfi->func_ptr->op_array.function_name);
-				zend_call_method(Z_ISUNDEF(alfi->obj)? NULL : &alfi->obj, alfi->ce, &copy, ZSTR_VAL(func_name), ZSTR_LEN(func_name), retval, 1, class_name, NULL);
+			func = alfi->func_ptr;
+			if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
+				func = emalloc(sizeof(zend_op_array));
+				memcpy(func, alfi->func_ptr, sizeof(zend_op_array));
+				zend_string_addref(func->op_array.function_name);
+			}
+			ZVAL_UNDEF(&retval);
+			fcic.function_handler = func;
+			if (Z_ISUNDEF(alfi->obj)) {
+				fci.object = NULL;
+				fcic.object = NULL;
+				fcic.calling_scope = alfi->ce;
+				if (alfi->ce &&
+				    (!called_scope ||
+				     !instanceof_function(called_scope, alfi->ce))) {
+					fcic.called_scope = alfi->ce;
+				} else {
+					fcic.called_scope = called_scope;
+				}
 			} else {
-				zend_call_method(Z_ISUNDEF(alfi->obj)? NULL : &alfi->obj, alfi->ce, &alfi->func_ptr, ZSTR_VAL(func_name), ZSTR_LEN(func_name), retval, 1, class_name, NULL);
+				fci.object = Z_OBJ(alfi->obj);
+				fcic.object = Z_OBJ(alfi->obj);
+				fcic.called_scope = Z_OBJCE(alfi->obj);
 			}
+
+			zend_call_function(&fci, &fcic);
+
 			zend_exception_save();
-			if (retval) {
-				zval_ptr_dtor(retval);
-				retval = NULL;
-			}
-			if (zend_hash_exists(EG(class_table), lc_name)) {
+			zval_ptr_dtor(&retval);
+			if (pos + 1 == SPL_G(autoload_functions)->nNumUsed ||
+			    zend_hash_exists(EG(class_table), lc_name)) {
 				break;
 			}
 			zend_hash_move_forward_ex(SPL_G(autoload_functions), &pos);
 		}
 		zend_exception_restore();
-		zend_string_free(lc_name);
+		zend_string_release(lc_name);
 		SPL_G(autoload_running) = l_autoload_running;
 	} else {
 		/* do not use or overwrite &EG(autoload_func) here */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.