com php-src: 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): Zend/zend_comp ile.h Zend/zend_execute.c Zend/zend_execute.h Z end/zend_types.h
| From: | Dmitry Stogov | Date: | Fri, 26 Dec 2014 19:34:44 +0000 |
| Subject: | com php-src: 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): Zend/zend_comp ile.h Zend/zend_execute.c Zend/zend_execute.h Z end/zend_types.h |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-83883@lists.php.net to get a copy of this message | ||
Commit: ab0b15b8ff90a292dcf0af2eb95d426ba4662095
Author: Dmitry Stogov <dmitry@zend.com> Fri, 26 Dec 2014 22:34:44 +0300
Parents: 4409b6db3ee5f9fea7f004b48e427a50541ddec0
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=ab0b15b8ff90a292dcf0af2eb95d426ba4662095
Log:
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)
Changed paths:
M Zend/zend_compile.h
M Zend/zend_execute.c
M Zend/zend_execute.h
M Zend/zend_types.h
Diff:
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index f560054..7909e98 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -412,8 +412,9 @@ struct _zend_execute_data {
#define ZEND_CALL_CODE (1 << 0)
#define ZEND_CALL_NESTED (0 << 1)
#define ZEND_CALL_TOP (1 << 1)
-#define ZEND_CALL_CTOR (1 << 2)
-#define ZEND_CALL_CTOR_RESULT_UNUSED (1 << 3)
+#define ZEND_CALL_FREE_EXTRA_ARGS (1 << 2) /* equal to IS_TYPE_REFCOUNTED */
+#define ZEND_CALL_CTOR (1 << 3)
+#define ZEND_CALL_CTOR_RESULT_UNUSED (1 << 4)
#define ZEND_CALL_INFO(call) \
(Z_TYPE_INFO((call)->This) >> 24)
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 35dd10f..3c01b28 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;
diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h
index 9197e4c..a94299f 100644
--- a/Zend/zend_execute.h
+++ b/Zend/zend_execute.h
@@ -176,11 +176,9 @@ static zend_always_inline zend_execute_data
*zend_vm_stack_push_call_frame(uint3
static zend_always_inline void zend_vm_stack_free_extra_args(zend_execute_data *call)
{
- uint32_t first_extra_arg = call->func->op_array.num_args;
-
- if (UNEXPECTED(ZEND_CALL_NUM_ARGS(call) > first_extra_arg)) {
- zval *end = ZEND_CALL_VAR_NUM(call, call->func->op_array.last_var +
call->func->op_array.T);
- zval *p = end + (ZEND_CALL_NUM_ARGS(call) - first_extra_arg);
+ if (ZEND_CALL_INFO(call) & ZEND_CALL_FREE_EXTRA_ARGS) {
+ zval *end = ZEND_CALL_VAR_NUM(call, call->func->op_array.last_var +
call->func->op_array.T);
+ zval *p = end + (ZEND_CALL_NUM_ARGS(call) - call->func->op_array.num_args);
do {
p--;
zval_ptr_dtor_nogc(p);
diff --git a/Zend/zend_types.h b/Zend/zend_types.h
index 1f7978b..28885db 100644
--- a/Zend/zend_types.h
+++ b/Zend/zend_types.h
@@ -264,7 +264,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
#define Z_COUNTED_P(zval_p) Z_COUNTED(*(zval_p))
#define Z_TYPE_FLAGS_SHIFT 8
-#define Z_CONST_FLAGS_SHIFT 8
+#define Z_CONST_FLAGS_SHIFT 16
#define GC_REFCOUNT(p) ((zend_refcounted*)(p))->refcount
#define GC_TYPE(p) ((zend_refcounted*)(p))->u.v.type
@@ -286,10 +286,10 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
/* zval.u1..v.type_flags */
#define IS_TYPE_CONSTANT (1<<0)
-#define IS_TYPE_REFCOUNTED (1<<1)
-#define IS_TYPE_COLLECTABLE (1<<2)
-#define IS_TYPE_COPYABLE (1<<3)
-#define IS_TYPE_IMMUTABLE (1<<4)
+#define IS_TYPE_IMMUTABLE (1<<1)
+#define IS_TYPE_REFCOUNTED (1<<2)
+#define IS_TYPE_COLLECTABLE (1<<3)
+#define IS_TYPE_COPYABLE (1<<4)
/* extended types */
#define IS_INTERNED_STRING_EX IS_STRING