summaryrefslogtreecommitdiff
path: root/Zend/zend_execute.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-12-26 22:34:44 +0300
committerDmitry Stogov <dmitry@zend.com>2014-12-26 22:34:44 +0300
commitab0b15b8ff90a292dcf0af2eb95d426ba4662095 (patch)
tree31f2eb2f9e0903344356ee2309d3c1796a338ab4 /Zend/zend_execute.c
parent4409b6db3ee5f9fea7f004b48e427a50541ddec0 (diff)
downloadphp-git-ab0b15b8ff90a292dcf0af2eb95d426ba4662095.tar.gz
Optimized destruction of extra arguments passed to user functions.
If no refcounted arguments are passed, then destruction code is not triggered at all. (Full rebuild required)
Diffstat (limited to 'Zend/zend_execute.c')
-rw-r--r--Zend/zend_execute.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 35dd10feb2..3c01b28c48 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -1617,6 +1617,7 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu
num_args = EX_NUM_ARGS();
if (UNEXPECTED(num_args > first_extra_arg)) {
zval *end, *src, *dst;
+ uint32_t type_flags = 0;
if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
/* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
@@ -1629,12 +1630,19 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu
dst = src + (op_array->last_var + op_array->T - first_extra_arg);
if (EXPECTED(src != dst)) {
do {
+ type_flags |= Z_TYPE_INFO_P(src);
ZVAL_COPY_VALUE(dst, src);
ZVAL_UNDEF(src);
src--;
dst--;
} while (src != end);
+ } else {
+ do {
+ type_flags |= Z_TYPE_INFO_P(src);
+ src--;
+ } while (src != end);
}
+ ZEND_ADD_CALL_FLAG(execute_data, ((type_flags >> Z_TYPE_FLAGS_SHIFT) & IS_TYPE_REFCOUNTED));
} else if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
/* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
EX(opline) += num_args;
@@ -1709,6 +1717,7 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da
num_args = EX_NUM_ARGS();
if (UNEXPECTED(num_args > first_extra_arg)) {
zval *end, *src, *dst;
+ uint32_t type_flags = 0;
if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
/* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
@@ -1721,12 +1730,19 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da
dst = src + (op_array->last_var + op_array->T - first_extra_arg);
if (EXPECTED(src != dst)) {
do {
+ type_flags |= Z_TYPE_INFO_P(src);
ZVAL_COPY_VALUE(dst, src);
ZVAL_UNDEF(src);
src--;
dst--;
} while (src != end);
+ } else {
+ do {
+ type_flags |= Z_TYPE_INFO_P(src);
+ src--;
+ } while (src != end);
}
+ ZEND_ADD_CALL_FLAG(execute_data, ((type_flags >> Z_TYPE_FLAGS_SHIFT) & IS_TYPE_REFCOUNTED));
} else if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
/* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
EX(opline) += num_args;