]> granicus.if.org Git - php/commitdiff
Optimization of zend_do_fcall_common_helper()
authorDmitry Stogov <dmitry@php.net>
Tue, 20 Nov 2007 13:53:08 +0000 (13:53 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 20 Nov 2007 13:53:08 +0000 (13:53 +0000)
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 7c20026c42705a6d44b34514fa81e456b7a652a2..ef18499924afd6c9f48b4df80ff5c179636b6924 100644 (file)
@@ -1937,11 +1937,9 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
 ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
 {
        zend_op *opline = EX(opline);
-       zval **original_return_value;
        zend_class_entry *current_scope;
        zend_class_entry *current_called_scope;
        zval *current_this;
-       int return_value_used = RETURN_VALUE_USED(opline);
        zend_bool should_change_scope;
        zval *ex_object;
 
@@ -1989,8 +1987,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
        EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
 
        if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
-               ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
-               INIT_ZVAL(*(EX_T(opline->result.u.var).var.ptr));
+               ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
                EX_T(opline->result.u.var).var.fcall_returned_reference = EX(function_state).function->common.return_reference;
 
                if (EX(function_state).function->common.arg_info) {
@@ -2008,9 +2005,9 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
                }
                if (!zend_execute_internal) {
                        /* saves one function call if zend_execute_internal is not used */
-                       ((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(function_state).function->common.return_reference?&EX_T(opline->result.u.var).var.ptr:NULL, EX(object), return_value_used TSRMLS_CC);
+                       ((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(function_state).function->common.return_reference?&EX_T(opline->result.u.var).var.ptr:NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
                } else {
-                       zend_execute_internal(EXECUTE_DATA, return_value_used TSRMLS_CC);
+                       zend_execute_internal(EXECUTE_DATA, RETURN_VALUE_USED(opline) TSRMLS_CC);
                }
 
 /*     We shouldn't fix bad extensions here,
@@ -2020,35 +2017,32 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
                        Z_SET_REFCOUNT_P(EX_T(opline->result.u.var).var.ptr, 1);
                }
 */
-               if (!return_value_used) {
+               if (!RETURN_VALUE_USED(opline)) {
                        zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
                }
        } else if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
-               HashTable *function_symbol_table;
+               zval **original_return_value = EG(return_value_ptr_ptr);
 
                EX_T(opline->result.u.var).var.ptr = NULL;
                if (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
                        /*printf("Cache hit!  Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/
-                       function_symbol_table = *(EG(symtable_cache_ptr)--);
+                       EG(active_symbol_table) = *(EG(symtable_cache_ptr)--);
                } else {
-                       ALLOC_HASHTABLE(function_symbol_table);
-                       zend_hash_init(function_symbol_table, 0, NULL, ZVAL_PTR_DTOR, 0);
-                       /*printf("Cache miss!  Initialized %x\n", function_symbol_table);*/
+                       ALLOC_HASHTABLE(EG(active_symbol_table));
+                       zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0);
+                       /*printf("Cache miss!  Initialized %x\n", EG(active_symbol_table));*/
                }
-               EG(active_symbol_table) = function_symbol_table;
-               original_return_value = EG(return_value_ptr_ptr);
                EG(return_value_ptr_ptr) = &EX_T(opline->result.u.var).var.ptr;
                EG(active_op_array) = (zend_op_array *) EX(function_state).function;
 
                zend_execute(EG(active_op_array) TSRMLS_CC);
                EX_T(opline->result.u.var).var.fcall_returned_reference = EG(active_op_array)->return_reference;
 
-               if (return_value_used && !EX_T(opline->result.u.var).var.ptr) {
-                       if (!EG(exception)) {
-                               ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
-                               INIT_ZVAL(*EX_T(opline->result.u.var).var.ptr);
+               if (RETURN_VALUE_USED(opline)) {
+                       if (!EX_T(opline->result.u.var).var.ptr && !EG(exception)) {
+                               ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
                        }
-               } else if (!return_value_used && EX_T(opline->result.u.var).var.ptr) {
+               } else if (EX_T(opline->result.u.var).var.ptr) {
                        zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
                }
 
@@ -2056,22 +2050,21 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
                EG(active_op_array) = EX(op_array);
                EG(return_value_ptr_ptr)=original_return_value;
                if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
-                       zend_hash_destroy(function_symbol_table);
-                       FREE_HASHTABLE(function_symbol_table);
+                       zend_hash_destroy(EG(active_symbol_table));
+                       FREE_HASHTABLE(EG(active_symbol_table));
                } else {
                        /* clean before putting into the cache, since clean
                           could call dtors, which could use cached hash */
-                       zend_hash_clean(function_symbol_table);
-                       *(++EG(symtable_cache_ptr)) = function_symbol_table;
+                       zend_hash_clean(EG(active_symbol_table));
+                       *(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
                }
                EG(active_symbol_table) = EX(symbol_table);
        } else { /* ZEND_OVERLOADED_FUNCTION */
-               ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
-               INIT_ZVAL(*(EX_T(opline->result.u.var).var.ptr));
+               ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
 
                        /* Not sure what should be done here if it's a static method */
                if (EX(object)) {
-                       Z_OBJ_HT_P(EX(object))->call_method(EX(function_state).function->common.function_name, opline->extended_value, EX_T(opline->result.u.var).var.ptr, &EX_T(opline->result.u.var).var.ptr, EX(object), return_value_used TSRMLS_CC);
+                       Z_OBJ_HT_P(EX(object))->call_method(EX(function_state).function->common.function_name, opline->extended_value, EX_T(opline->result.u.var).var.ptr, &EX_T(opline->result.u.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
                } else {
                        zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
                }
@@ -2081,7 +2074,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
                }
                efree(EX(function_state).function);
 
-               if (!return_value_used) {
+               if (!RETURN_VALUE_USED(opline)) {
                        zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
                } else {
                        Z_UNSET_ISREF_P(EX_T(opline->result.u.var).var.ptr);
@@ -2119,7 +2112,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
 
        if (EG(exception)) {
                zend_throw_exception_internal(NULL TSRMLS_CC);
-               if (return_value_used && EX_T(opline->result.u.var).var.ptr) {
+               if (RETURN_VALUE_USED(opline) && EX_T(opline->result.u.var).var.ptr) {
                        zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
                }
        }
index a192406782a5525996d85e5e43f8048248bb67e3..e98a83f3241cbd7af311425d5ae699f19c3f55bb 100644 (file)
@@ -119,11 +119,9 @@ static int ZEND_INIT_STRING_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zval **original_return_value;
        zend_class_entry *current_scope;
        zend_class_entry *current_called_scope;
        zval *current_this;
-       int return_value_used = RETURN_VALUE_USED(opline);
        zend_bool should_change_scope;
        zval *ex_object;
 
@@ -171,8 +169,7 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
        EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
 
        if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
-               ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
-               INIT_ZVAL(*(EX_T(opline->result.u.var).var.ptr));
+               ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
                EX_T(opline->result.u.var).var.fcall_returned_reference = EX(function_state).function->common.return_reference;
 
                if (EX(function_state).function->common.arg_info) {
@@ -190,9 +187,9 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
                }
                if (!zend_execute_internal) {
                        /* saves one function call if zend_execute_internal is not used */
-                       ((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(function_state).function->common.return_reference?&EX_T(opline->result.u.var).var.ptr:NULL, EX(object), return_value_used TSRMLS_CC);
+                       ((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(function_state).function->common.return_reference?&EX_T(opline->result.u.var).var.ptr:NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
                } else {
-                       zend_execute_internal(execute_data, return_value_used TSRMLS_CC);
+                       zend_execute_internal(execute_data, RETURN_VALUE_USED(opline) TSRMLS_CC);
                }
 
 /*     We shouldn't fix bad extensions here,
@@ -202,35 +199,32 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
                        Z_SET_REFCOUNT_P(EX_T(opline->result.u.var).var.ptr, 1);
                }
 */
-               if (!return_value_used) {
+               if (!RETURN_VALUE_USED(opline)) {
                        zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
                }
        } else if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
-               HashTable *function_symbol_table;
+               zval **original_return_value = EG(return_value_ptr_ptr);
 
                EX_T(opline->result.u.var).var.ptr = NULL;
                if (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
                        /*printf("Cache hit!  Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/
-                       function_symbol_table = *(EG(symtable_cache_ptr)--);
+                       EG(active_symbol_table) = *(EG(symtable_cache_ptr)--);
                } else {
-                       ALLOC_HASHTABLE(function_symbol_table);
-                       zend_hash_init(function_symbol_table, 0, NULL, ZVAL_PTR_DTOR, 0);
-                       /*printf("Cache miss!  Initialized %x\n", function_symbol_table);*/
+                       ALLOC_HASHTABLE(EG(active_symbol_table));
+                       zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0);
+                       /*printf("Cache miss!  Initialized %x\n", EG(active_symbol_table));*/
                }
-               EG(active_symbol_table) = function_symbol_table;
-               original_return_value = EG(return_value_ptr_ptr);
                EG(return_value_ptr_ptr) = &EX_T(opline->result.u.var).var.ptr;
                EG(active_op_array) = (zend_op_array *) EX(function_state).function;
 
                zend_execute(EG(active_op_array) TSRMLS_CC);
                EX_T(opline->result.u.var).var.fcall_returned_reference = EG(active_op_array)->return_reference;
 
-               if (return_value_used && !EX_T(opline->result.u.var).var.ptr) {
-                       if (!EG(exception)) {
-                               ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
-                               INIT_ZVAL(*EX_T(opline->result.u.var).var.ptr);
+               if (RETURN_VALUE_USED(opline)) {
+                       if (!EX_T(opline->result.u.var).var.ptr && !EG(exception)) {
+                               ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
                        }
-               } else if (!return_value_used && EX_T(opline->result.u.var).var.ptr) {
+               } else if (EX_T(opline->result.u.var).var.ptr) {
                        zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
                }
 
@@ -238,22 +232,21 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
                EG(active_op_array) = EX(op_array);
                EG(return_value_ptr_ptr)=original_return_value;
                if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
-                       zend_hash_destroy(function_symbol_table);
-                       FREE_HASHTABLE(function_symbol_table);
+                       zend_hash_destroy(EG(active_symbol_table));
+                       FREE_HASHTABLE(EG(active_symbol_table));
                } else {
                        /* clean before putting into the cache, since clean
                           could call dtors, which could use cached hash */
-                       zend_hash_clean(function_symbol_table);
-                       *(++EG(symtable_cache_ptr)) = function_symbol_table;
+                       zend_hash_clean(EG(active_symbol_table));
+                       *(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
                }
                EG(active_symbol_table) = EX(symbol_table);
        } else { /* ZEND_OVERLOADED_FUNCTION */
-               ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
-               INIT_ZVAL(*(EX_T(opline->result.u.var).var.ptr));
+               ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
 
                        /* Not sure what should be done here if it's a static method */
                if (EX(object)) {
-                       Z_OBJ_HT_P(EX(object))->call_method(EX(function_state).function->common.function_name, opline->extended_value, EX_T(opline->result.u.var).var.ptr, &EX_T(opline->result.u.var).var.ptr, EX(object), return_value_used TSRMLS_CC);
+                       Z_OBJ_HT_P(EX(object))->call_method(EX(function_state).function->common.function_name, opline->extended_value, EX_T(opline->result.u.var).var.ptr, &EX_T(opline->result.u.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
                } else {
                        zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
                }
@@ -263,7 +256,7 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
                }
                efree(EX(function_state).function);
 
-               if (!return_value_used) {
+               if (!RETURN_VALUE_USED(opline)) {
                        zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
                } else {
                        Z_UNSET_ISREF_P(EX_T(opline->result.u.var).var.ptr);
@@ -301,7 +294,7 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
 
        if (EG(exception)) {
                zend_throw_exception_internal(NULL TSRMLS_CC);
-               if (return_value_used && EX_T(opline->result.u.var).var.ptr) {
+               if (RETURN_VALUE_USED(opline) && EX_T(opline->result.u.var).var.ptr) {
                        zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
                }
        }