diff options
author | Dmitry Stogov <dmitry@zend.com> | 2016-03-10 13:33:36 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2016-03-10 13:33:36 +0300 |
commit | f8506c062f8c4f72e12f20487bbb8c453602e5e7 (patch) | |
tree | d5cbc87031b8331fb2c7a0c85a711069d78e85a8 | |
parent | 3edd33083c59fcbded55a272abee18ae2946d9ce (diff) | |
download | php-git-f8506c062f8c4f72e12f20487bbb8c453602e5e7.tar.gz |
More effecient fix for bug #71756
-rw-r--r-- | Zend/zend_execute.c | 6 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 8 | ||||
-rw-r--r-- | 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); |