From f8506c062f8c4f72e12f20487bbb8c453602e5e7 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 10 Mar 2016 13:33:36 +0300 Subject: [PATCH] More effecient fix for bug #71756 --- Zend/zend_execute.c | 6 ---- Zend/zend_vm_def.h | 8 +++++ Zend/zend_vm_execute.h | 72 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 6 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 432db9be67..8253fd5d85 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1561,8 +1561,6 @@ num_index: retval = zend_hash_index_add_new(ht, hval, &EG(uninitialized_zval)); break; } - } else if (type == BP_VAR_R) { - ZVAL_DEREF(retval); } } else if (EXPECTED(Z_TYPE_P(dim) == IS_STRING)) { offset_key = Z_STR_P(dim); @@ -1593,11 +1591,7 @@ str_index: ZVAL_NULL(retval); break; } - } else if (type == BP_VAR_R) { - ZVAL_DEREF(retval); } - } else if (type == BP_VAR_R) { - ZVAL_DEREF(retval); } } else { switch (type) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 23aa3f3afd..35013c1571 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4891,6 +4891,14 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV) SAVE_OPLINE(); if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } else if ((OP1_TYPE & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) { + /* Don't keep lock on reference, lock the value instead */ + if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { + ZVAL_UNREF(op1); + } else { + Z_DELREF_P(op1); + ZVAL_COPY(op1, Z_REFVAL_P(op1)); + } } if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index e181246ede..8b62a834a4 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -5858,6 +5858,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CONST_HANDLER( SAVE_OPLINE(); if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) { + /* Don't keep lock on reference, lock the value instead */ + if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { + ZVAL_UNREF(op1); + } else { + Z_DELREF_P(op1); + ZVAL_COPY(op1, Z_REFVAL_P(op1)); + } } if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -9646,6 +9654,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CV_HANDLER(ZEN SAVE_OPLINE(); if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) { + /* Don't keep lock on reference, lock the value instead */ + if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { + ZVAL_UNREF(op1); + } else { + Z_DELREF_P(op1); + ZVAL_COPY(op1, Z_REFVAL_P(op1)); + } } if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -11412,6 +11428,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER SAVE_OPLINE(); if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) { + /* Don't keep lock on reference, lock the value instead */ + if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { + ZVAL_UNREF(op1); + } else { + Z_DELREF_P(op1); + ZVAL_COPY(op1, Z_REFVAL_P(op1)); + } } if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -32076,6 +32100,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEN SAVE_OPLINE(); if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } else if ((IS_CV & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) { + /* Don't keep lock on reference, lock the value instead */ + if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { + ZVAL_UNREF(op1); + } else { + Z_DELREF_P(op1); + ZVAL_COPY(op1, Z_REFVAL_P(op1)); + } } if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -37152,6 +37184,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_O SAVE_OPLINE(); if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } else if ((IS_CV & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) { + /* Don't keep lock on reference, lock the value instead */ + if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { + ZVAL_UNREF(op1); + } else { + Z_DELREF_P(op1); + ZVAL_COPY(op1, Z_REFVAL_P(op1)); + } } if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -39725,6 +39765,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMPVAR_HANDLER(ZE SAVE_OPLINE(); if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } else if ((IS_CV & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) { + /* Don't keep lock on reference, lock the value instead */ + if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { + ZVAL_UNREF(op1); + } else { + Z_DELREF_P(op1); + ZVAL_COPY(op1, Z_REFVAL_P(op1)); + } } if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -41952,6 +42000,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER SAVE_OPLINE(); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) { + /* Don't keep lock on reference, lock the value instead */ + if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { + ZVAL_UNREF(op1); + } else { + Z_DELREF_P(op1); + ZVAL_COPY(op1, Z_REFVAL_P(op1)); + } } if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -44092,6 +44148,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZE SAVE_OPLINE(); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) { + /* Don't keep lock on reference, lock the value instead */ + if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { + ZVAL_UNREF(op1); + } else { + Z_DELREF_P(op1); + ZVAL_COPY(op1, Z_REFVAL_P(op1)); + } } if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); @@ -45231,6 +45295,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLE SAVE_OPLINE(); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) { + /* Don't keep lock on reference, lock the value instead */ + if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) { + ZVAL_UNREF(op1); + } else { + Z_DELREF_P(op1); + ZVAL_COPY(op1, Z_REFVAL_P(op1)); + } } if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); -- 2.40.0