1
0
mirror of https://github.com/php/php-src.git synced 2026-03-26 01:02:25 +01:00

Optimized ZEND_RETURN opcode to not allocate and copy return value if it is not

used.
This commit is contained in:
Dmitry Stogov
2008-04-11 09:43:49 +00:00
parent 20b755c30e
commit b287ccf508
4 changed files with 69 additions and 73 deletions

View File

@@ -1668,7 +1668,6 @@ ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_co
zend_file_handle *file_handle;
zend_op_array *orig_op_array = EG(active_op_array);
zval **orig_retval_ptr_ptr = EG(return_value_ptr_ptr);
zval *local_retval = NULL;
va_start(files, file_count);
for (i = 0; i < file_count; i++) {
@@ -1683,7 +1682,7 @@ ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_co
}
zend_destroy_file_handle(file_handle TSRMLS_CC);
if (EG(active_op_array)) {
EG(return_value_ptr_ptr) = retval ? retval : &local_retval;
EG(return_value_ptr_ptr) = retval ? retval : NULL;
zend_execute(EG(active_op_array) TSRMLS_CC);
if (EG(exception)) {
EG(opline_ptr) = NULL;
@@ -1714,13 +1713,6 @@ ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_co
} else {
zend_exception_error(EG(exception) TSRMLS_CC);
}
if (retval == NULL && *EG(return_value_ptr_ptr) != NULL) {
zval_ptr_dtor(EG(return_value_ptr_ptr));
local_retval = NULL;
}
} else if (!retval && *EG(return_value_ptr_ptr)) {
zval_ptr_dtor(EG(return_value_ptr_ptr));
local_retval = NULL;
}
destroy_op_array(EG(active_op_array) TSRMLS_CC);
efree(EG(active_op_array));

View File

@@ -1423,7 +1423,7 @@ ZEND_API int zend_u_eval_string(zend_uchar type, zstr string, zval *retval_ptr,
u_strcat(Z_USTRVAL(pv), u_semicolon);
} else {
Z_USTRLEN(pv) = u_strlen(str);
Z_USTRVAL(pv) = eustrndup(str, Z_USTRLEN(pv));
Z_USTRVAL(pv) = str;
}
} else {
char *str = string.s;
@@ -1436,7 +1436,7 @@ ZEND_API int zend_u_eval_string(zend_uchar type, zstr string, zval *retval_ptr,
strcat(Z_STRVAL(pv), " ;");
} else {
Z_STRLEN(pv) = strlen(str);
Z_STRVAL(pv) = estrndup(str, Z_STRLEN(pv));
Z_STRVAL(pv) = str;
}
}
Z_TYPE(pv) = type;
@@ -1481,7 +1481,9 @@ ZEND_API int zend_u_eval_string(zend_uchar type, zstr string, zval *retval_ptr,
} else {
retval = FAILURE;
}
zval_dtor(&pv);
if (retval_ptr) {
zval_dtor(&pv);
}
return retval;
}
/* }}} */
@@ -1515,7 +1517,6 @@ void execute_new_code(TSRMLS_D) /* {{{ */
{
zend_op *opline, *end;
zend_op *ret_opline;
zval *local_retval=NULL;
if (!(CG(active_op_array)->fn_flags & ZEND_ACC_INTERACTIVE)
|| CG(active_op_array)->backpatch_count>0
@@ -1569,12 +1570,9 @@ void execute_new_code(TSRMLS_D) /* {{{ */
zend_release_labels(TSRMLS_C);
EG(return_value_ptr_ptr) = &local_retval;
EG(return_value_ptr_ptr) = NULL;
EG(active_op_array) = CG(active_op_array);
zend_execute(CG(active_op_array) TSRMLS_CC);
if (local_retval) {
zval_ptr_dtor(&local_retval);
}
if (EG(exception)) {
zend_exception_error(EG(exception) TSRMLS_CC);

View File

@@ -2229,7 +2229,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
zend_u_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
/*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/
}
EG(return_value_ptr_ptr) = &EX_T(opline->result.u.var).var.ptr;
EG(return_value_ptr_ptr) = RETURN_VALUE_USED(opline) ? &EX_T(opline->result.u.var).var.ptr : NULL;
EG(active_op_array) = (zend_op_array *) EX(function_state).function;
zend_execute(EG(active_op_array) TSRMLS_CC);
@@ -2239,8 +2239,6 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
if (!EG(exception) && !EX_T(opline->result.u.var).var.ptr) {
ALLOC_INIT_ZVAL(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);
}
EG(opline_ptr) = &EX(opline);
@@ -2377,16 +2375,22 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
}
}
SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
Z_ADDREF_PP(retval_ptr_ptr);
if (EG(return_value_ptr_ptr)) {
SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
Z_ADDREF_PP(retval_ptr_ptr);
(*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
(*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
}
} else {
ZEND_VM_C_LABEL(return_by_value):
retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
if (!IS_OP1_TMP_FREE()) { /* Not a temp var */
if (!EG(return_value_ptr_ptr)) {
if (OP1_TYPE == IS_TMP_VAR) {
FREE_OP1();
}
} else if (!IS_OP1_TMP_FREE()) { /* Not a temp var */
if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
(PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
zval *ret;
@@ -3214,7 +3218,7 @@ skip_compile:
zval *saved_object;
zend_function *saved_function;
EG(return_value_ptr_ptr) = EX_T(opline->result.u.var).var.ptr_ptr;
EG(return_value_ptr_ptr) = return_value_used ? EX_T(opline->result.u.var).var.ptr_ptr : NULL;
EG(active_op_array) = new_op_array;
EX_T(opline->result.u.var).var.ptr = NULL;
@@ -3229,11 +3233,7 @@ skip_compile:
EX(function_state).function = saved_function;
EX(object) = saved_object;
if (!return_value_used) {
if (EX_T(opline->result.u.var).var.ptr) {
zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
}
} else { /* return value is used */
if (return_value_used) {
if (!EX_T(opline->result.u.var).var.ptr) { /* there was no return statement */
ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);

View File

@@ -222,7 +222,7 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
zend_u_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
/*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/
}
EG(return_value_ptr_ptr) = &EX_T(opline->result.u.var).var.ptr;
EG(return_value_ptr_ptr) = RETURN_VALUE_USED(opline) ? &EX_T(opline->result.u.var).var.ptr : NULL;
EG(active_op_array) = (zend_op_array *) EX(function_state).function;
zend_execute(EG(active_op_array) TSRMLS_CC);
@@ -232,8 +232,6 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
if (!EG(exception) && !EX_T(opline->result.u.var).var.ptr) {
ALLOC_INIT_ZVAL(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);
}
EG(opline_ptr) = &EX(opline);
@@ -1438,16 +1436,22 @@ static int ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
}
SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
Z_ADDREF_PP(retval_ptr_ptr);
if (EG(return_value_ptr_ptr)) {
SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
Z_ADDREF_PP(retval_ptr_ptr);
(*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
(*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
}
} else {
return_by_value:
retval_ptr = &opline->op1.u.constant;
if (!0) { /* Not a temp var */
if (!EG(return_value_ptr_ptr)) {
if (IS_CONST == IS_TMP_VAR) {
}
} else if (!0) { /* Not a temp var */
if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
(PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
zval *ret;
@@ -1768,7 +1772,7 @@ skip_compile:
zval *saved_object;
zend_function *saved_function;
EG(return_value_ptr_ptr) = EX_T(opline->result.u.var).var.ptr_ptr;
EG(return_value_ptr_ptr) = return_value_used ? EX_T(opline->result.u.var).var.ptr_ptr : NULL;
EG(active_op_array) = new_op_array;
EX_T(opline->result.u.var).var.ptr = NULL;
@@ -1783,11 +1787,7 @@ skip_compile:
EX(function_state).function = saved_function;
EX(object) = saved_object;
if (!return_value_used) {
if (EX_T(opline->result.u.var).var.ptr) {
zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
}
} else { /* return value is used */
if (return_value_used) {
if (!EX_T(opline->result.u.var).var.ptr) { /* there was no return statement */
ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
@@ -4736,16 +4736,22 @@ static int ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
}
SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
Z_ADDREF_PP(retval_ptr_ptr);
if (EG(return_value_ptr_ptr)) {
SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
Z_ADDREF_PP(retval_ptr_ptr);
(*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
(*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
}
} else {
return_by_value:
retval_ptr = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
if (!1) { /* Not a temp var */
if (!EG(return_value_ptr_ptr)) {
if (IS_TMP_VAR == IS_TMP_VAR) {
zval_dtor(free_op1.var);
}
} else if (!1) { /* Not a temp var */
if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
(PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
zval *ret;
@@ -5075,7 +5081,7 @@ skip_compile:
zval *saved_object;
zend_function *saved_function;
EG(return_value_ptr_ptr) = EX_T(opline->result.u.var).var.ptr_ptr;
EG(return_value_ptr_ptr) = return_value_used ? EX_T(opline->result.u.var).var.ptr_ptr : NULL;
EG(active_op_array) = new_op_array;
EX_T(opline->result.u.var).var.ptr = NULL;
@@ -5090,11 +5096,7 @@ skip_compile:
EX(function_state).function = saved_function;
EX(object) = saved_object;
if (!return_value_used) {
if (EX_T(opline->result.u.var).var.ptr) {
zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
}
} else { /* return value is used */
if (return_value_used) {
if (!EX_T(opline->result.u.var).var.ptr) { /* there was no return statement */
ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
@@ -7972,16 +7974,22 @@ static int ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
}
SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
Z_ADDREF_PP(retval_ptr_ptr);
if (EG(return_value_ptr_ptr)) {
SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
Z_ADDREF_PP(retval_ptr_ptr);
(*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
(*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
}
} else {
return_by_value:
retval_ptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
if (!0) { /* Not a temp var */
if (!EG(return_value_ptr_ptr)) {
if (IS_VAR == IS_TMP_VAR) {
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
}
} else if (!0) { /* Not a temp var */
if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
(PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
zval *ret;
@@ -8416,7 +8424,7 @@ skip_compile:
zval *saved_object;
zend_function *saved_function;
EG(return_value_ptr_ptr) = EX_T(opline->result.u.var).var.ptr_ptr;
EG(return_value_ptr_ptr) = return_value_used ? EX_T(opline->result.u.var).var.ptr_ptr : NULL;
EG(active_op_array) = new_op_array;
EX_T(opline->result.u.var).var.ptr = NULL;
@@ -8431,11 +8439,7 @@ skip_compile:
EX(function_state).function = saved_function;
EX(object) = saved_object;
if (!return_value_used) {
if (EX_T(opline->result.u.var).var.ptr) {
zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
}
} else { /* return value is used */
if (return_value_used) {
if (!EX_T(opline->result.u.var).var.ptr) { /* there was no return statement */
ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
@@ -22238,16 +22242,22 @@ static int ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
}
SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
Z_ADDREF_PP(retval_ptr_ptr);
if (EG(return_value_ptr_ptr)) {
SEPARATE_ZVAL_TO_MAKE_IS_REF(retval_ptr_ptr);
Z_ADDREF_PP(retval_ptr_ptr);
(*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
(*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
}
} else {
return_by_value:
retval_ptr = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
if (!0) { /* Not a temp var */
if (!EG(return_value_ptr_ptr)) {
if (IS_CV == IS_TMP_VAR) {
}
} else if (!0) { /* Not a temp var */
if (EG(active_op_array)->return_reference == ZEND_RETURN_REF ||
(PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
zval *ret;
@@ -22672,7 +22682,7 @@ skip_compile:
zval *saved_object;
zend_function *saved_function;
EG(return_value_ptr_ptr) = EX_T(opline->result.u.var).var.ptr_ptr;
EG(return_value_ptr_ptr) = return_value_used ? EX_T(opline->result.u.var).var.ptr_ptr : NULL;
EG(active_op_array) = new_op_array;
EX_T(opline->result.u.var).var.ptr = NULL;
@@ -22687,11 +22697,7 @@ skip_compile:
EX(function_state).function = saved_function;
EX(object) = saved_object;
if (!return_value_used) {
if (EX_T(opline->result.u.var).var.ptr) {
zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
}
} else { /* return value is used */
if (return_value_used) {
if (!EX_T(opline->result.u.var).var.ptr) { /* there was no return statement */
ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);