From 58871730c84b736b750b9dca681a8246feacf443 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 3 Apr 2014 16:53:30 +0400 Subject: [PATCH] ASSIGN_REF optimization --- Zend/zend_execute.c | 11 ++++------- Zend/zend_vm_def.h | 9 +++++++-- Zend/zend_vm_execute.h | 36 ++++++++++++++++++++++++++++-------- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index b0799ef1c3..c4d2297a08 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -501,16 +501,13 @@ static inline zval *_get_obj_zval_ptr(int op_type, znode_op *op, const zend_exec return get_zval_ptr(op_type, op, execute_data, should_free, type); } -static void zend_assign_to_variable_reference(zval *variable_ptr, zval *value_ptr TSRMLS_DC) +static inline void zend_assign_to_variable_reference(zval *variable_ptr, zval *value_ptr TSRMLS_DC) { - if (variable_ptr == &EG(error_zval) || value_ptr == &EG(error_zval)) { - ZVAL_NULL(variable_ptr); - } else if (EXPECTED(variable_ptr != value_ptr)) { - zval tmp; + if (EXPECTED(variable_ptr != value_ptr)) { SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr); - ZVAL_COPY(&tmp, value_ptr); + Z_ADDREF_P(value_ptr); zval_ptr_dtor(variable_ptr); - ZVAL_COPY_VALUE(variable_ptr, &tmp); + ZVAL_COPY_VALUE(variable_ptr, value_ptr); } else if (!Z_ISREF_P(variable_ptr)) { ZVAL_NEW_REF(variable_ptr, variable_ptr); } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index a3c73b3c12..758dcaa4bf 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1824,7 +1824,7 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV) } if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) && - UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var)))) { + UNEXPECTED(!Z_ISREF_P(variable_ptr))) { zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); } @@ -1833,7 +1833,12 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV) (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); } - zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC); + if ((OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || + (OP2_TYPE == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) { + variable_ptr = &EG(uninitialized_zval); + } else { + zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC); + } if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) { if (!OP2_FREE) { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 3f03f63206..48bbb2b5e6 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -19643,7 +19643,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL } if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) && - UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var)))) { + UNEXPECTED(!Z_ISREF_P(variable_ptr))) { zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); } @@ -19652,7 +19652,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); } - zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC); + if ((IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || + (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) { + variable_ptr = &EG(uninitialized_zval); + } else { + zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC); + } if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) { if (!(free_op2.var != NULL)) { @@ -23024,7 +23029,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE } if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) && - UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var)))) { + UNEXPECTED(!Z_ISREF_P(variable_ptr))) { zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); } @@ -23033,7 +23038,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); } - zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC); + if ((IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || + (IS_CV == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) { + variable_ptr = &EG(uninitialized_zval); + } else { + zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC); + } if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) { if (!0) { @@ -36414,7 +36424,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE } if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) && - UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var)))) { + UNEXPECTED(!Z_ISREF_P(variable_ptr))) { zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); } @@ -36423,7 +36433,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); } - zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC); + if ((IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || + (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) { + variable_ptr = &EG(uninitialized_zval); + } else { + zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC); + } if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) { if (!(free_op2.var != NULL)) { @@ -39529,7 +39544,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER } if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) && - UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var)))) { + UNEXPECTED(!Z_ISREF_P(variable_ptr))) { zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); } @@ -39538,7 +39553,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); } - zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC); + if ((IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || + (IS_CV == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) { + variable_ptr = &EG(uninitialized_zval); + } else { + zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC); + } if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) { if (!0) { -- 2.40.0