From aed1f785159e7c9e81da8f2e2e06df9a6ee0d809 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 20 Aug 2020 15:02:12 +0300 Subject: [PATCH] micro-optimization --- Zend/zend_vm_def.h | 36 ++-- Zend/zend_vm_execute.h | 423 +++++++++++++++++++++++++---------------- 2 files changed, 286 insertions(+), 173 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index f06713d5ac..55a1e9ba86 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3428,8 +3428,17 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, do { if (OP1_TYPE == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { if ((OP1_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - object = Z_REFVAL_P(object); + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + if (OP1_TYPE & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } break; } } @@ -3473,7 +3482,9 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, zend_undefined_method(obj->ce, Z_STR_P(function_name)); } FREE_OP2(); - FREE_OP1(); + if ((OP1_TYPE & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } HANDLE_EXCEPTION(); } if (OP2_TYPE == IS_CONST && @@ -3482,8 +3493,10 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((OP1_TYPE & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - /* Reset "object" to trigger reference counting */ - object = NULL; + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); @@ -3496,10 +3509,11 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - FREE_OP1(); - - if ((OP1_TYPE & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + if ((OP1_TYPE & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } } /* call static method */ obj = (zend_object*)called_scope; @@ -3507,12 +3521,6 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, } else if (OP1_TYPE & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (OP1_TYPE == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ - } else { - zval *free_op1 = EX_VAR(opline->op1.var); - if (free_op1 != object) { - GC_ADDREF(obj); /* For $this pointer */ - zval_ptr_dtor_nogc(free_op1); - } } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index f103e91d33..70506a6e14 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -5743,8 +5743,17 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ do { if (IS_CONST == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - object = Z_REFVAL_P(object); + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + if (IS_CONST & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } break; } } @@ -5788,7 +5797,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ zend_undefined_method(obj->ce, Z_STR_P(function_name)); } - + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } HANDLE_EXCEPTION(); } if (IS_CONST == IS_CONST && @@ -5797,8 +5808,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - /* Reset "object" to trigger reference counting */ - object = NULL; + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); @@ -5811,9 +5824,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - - if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } } /* call static method */ obj = (zend_object*)called_scope; @@ -5821,12 +5836,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CONST == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ - } else { - zval *free_op1 = EX_VAR(opline->op1.var); - if (free_op1 != object) { - GC_ADDREF(obj); /* For $this pointer */ - zval_ptr_dtor_nogc(free_op1); - } } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -8018,8 +8027,17 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ do { if (IS_CONST == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - object = Z_REFVAL_P(object); + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + if (IS_CONST & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } break; } } @@ -8063,7 +8081,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ zend_undefined_method(obj->ce, Z_STR_P(function_name)); } zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } HANDLE_EXCEPTION(); } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && @@ -8072,8 +8092,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - /* Reset "object" to trigger reference counting */ - object = NULL; + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); @@ -8086,9 +8108,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - - if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } } /* call static method */ obj = (zend_object*)called_scope; @@ -8096,12 +8120,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CONST == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ - } else { - zval *free_op1 = EX_VAR(opline->op1.var); - if (free_op1 != object) { - GC_ADDREF(obj); /* For $this pointer */ - zval_ptr_dtor_nogc(free_op1); - } } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -10386,8 +10404,17 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ do { if (IS_CONST == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - object = Z_REFVAL_P(object); + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + if (IS_CONST & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } break; } } @@ -10431,7 +10458,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ zend_undefined_method(obj->ce, Z_STR_P(function_name)); } - + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } HANDLE_EXCEPTION(); } if (IS_CV == IS_CONST && @@ -10440,8 +10469,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - /* Reset "object" to trigger reference counting */ - object = NULL; + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); @@ -10454,9 +10485,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - - if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } } /* call static method */ obj = (zend_object*)called_scope; @@ -10464,12 +10497,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CONST == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ - } else { - zval *free_op1 = EX_VAR(opline->op1.var); - if (free_op1 != object) { - GC_ADDREF(obj); /* For $this pointer */ - zval_ptr_dtor_nogc(free_op1); - } } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -14746,8 +14773,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C do { if ((IS_TMP_VAR|IS_VAR) == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - object = Z_REFVAL_P(object); + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + if ((IS_TMP_VAR|IS_VAR) & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } break; } } @@ -14791,7 +14827,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C zend_undefined_method(obj->ce, Z_STR_P(function_name)); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } HANDLE_EXCEPTION(); } if (IS_CONST == IS_CONST && @@ -14800,8 +14838,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - /* Reset "object" to trigger reference counting */ - object = NULL; + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); @@ -14814,10 +14854,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } } /* call static method */ obj = (zend_object*)called_scope; @@ -14825,12 +14866,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { if ((IS_TMP_VAR|IS_VAR) == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ - } else { - zval *free_op1 = EX_VAR(opline->op1.var); - if (free_op1 != object) { - GC_ADDREF(obj); /* For $this pointer */ - zval_ptr_dtor_nogc(free_op1); - } } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -16153,8 +16188,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T do { if ((IS_TMP_VAR|IS_VAR) == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - object = Z_REFVAL_P(object); + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + if ((IS_TMP_VAR|IS_VAR) & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } break; } } @@ -16198,7 +16242,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T zend_undefined_method(obj->ce, Z_STR_P(function_name)); } zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } HANDLE_EXCEPTION(); } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && @@ -16207,8 +16253,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - /* Reset "object" to trigger reference counting */ - object = NULL; + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); @@ -16221,10 +16269,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } } /* call static method */ obj = (zend_object*)called_scope; @@ -16232,12 +16281,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { if ((IS_TMP_VAR|IS_VAR) == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ - } else { - zval *free_op1 = EX_VAR(opline->op1.var); - if (free_op1 != object) { - GC_ADDREF(obj); /* For $this pointer */ - zval_ptr_dtor_nogc(free_op1); - } } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -17453,8 +17496,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C do { if ((IS_TMP_VAR|IS_VAR) == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - object = Z_REFVAL_P(object); + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + if ((IS_TMP_VAR|IS_VAR) & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } break; } } @@ -17498,7 +17550,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C zend_undefined_method(obj->ce, Z_STR_P(function_name)); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } HANDLE_EXCEPTION(); } if (IS_CV == IS_CONST && @@ -17507,8 +17561,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - /* Reset "object" to trigger reference counting */ - object = NULL; + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); @@ -17521,10 +17577,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } } /* call static method */ obj = (zend_object*)called_scope; @@ -17532,12 +17589,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { if ((IS_TMP_VAR|IS_VAR) == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ - } else { - zval *free_op1 = EX_VAR(opline->op1.var); - if (free_op1 != object) { - GC_ADDREF(obj); /* For $this pointer */ - zval_ptr_dtor_nogc(free_op1); - } } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -31478,8 +31529,17 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S do { if (IS_UNUSED == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - object = Z_REFVAL_P(object); + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + if (IS_UNUSED & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } break; } } @@ -31523,7 +31583,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S zend_undefined_method(obj->ce, Z_STR_P(function_name)); } - + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } HANDLE_EXCEPTION(); } if (IS_CONST == IS_CONST && @@ -31532,8 +31594,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - /* Reset "object" to trigger reference counting */ - object = NULL; + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); @@ -31546,9 +31610,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - - if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } } /* call static method */ obj = (zend_object*)called_scope; @@ -31556,12 +31622,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_UNUSED == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ - } else { - zval *free_op1 = EX_VAR(opline->op1.var); - if (free_op1 != object) { - GC_ADDREF(obj); /* For $this pointer */ - zval_ptr_dtor_nogc(free_op1); - } } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -33374,8 +33434,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T do { if (IS_UNUSED == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - object = Z_REFVAL_P(object); + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + if (IS_UNUSED & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } break; } } @@ -33419,7 +33488,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T zend_undefined_method(obj->ce, Z_STR_P(function_name)); } zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } HANDLE_EXCEPTION(); } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && @@ -33428,8 +33499,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - /* Reset "object" to trigger reference counting */ - object = NULL; + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); @@ -33442,9 +33515,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - - if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } } /* call static method */ obj = (zend_object*)called_scope; @@ -33452,12 +33527,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_UNUSED == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ - } else { - zval *free_op1 = EX_VAR(opline->op1.var); - if (free_op1 != object) { - GC_ADDREF(obj); /* For $this pointer */ - zval_ptr_dtor_nogc(free_op1); - } } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -35848,8 +35917,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C do { if (IS_UNUSED == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - object = Z_REFVAL_P(object); + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + if (IS_UNUSED & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } break; } } @@ -35893,7 +35971,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C zend_undefined_method(obj->ce, Z_STR_P(function_name)); } - + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } HANDLE_EXCEPTION(); } if (IS_CV == IS_CONST && @@ -35902,8 +35982,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - /* Reset "object" to trigger reference counting */ - object = NULL; + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); @@ -35916,9 +35998,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - - if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } } /* call static method */ obj = (zend_object*)called_scope; @@ -35926,12 +36010,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_UNUSED == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ - } else { - zval *free_op1 = EX_VAR(opline->op1.var); - if (free_op1 != object) { - GC_ADDREF(obj); /* For $this pointer */ - zval_ptr_dtor_nogc(free_op1); - } } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -40514,8 +40592,17 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S do { if (IS_CV == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - object = Z_REFVAL_P(object); + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + if (IS_CV & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } break; } } @@ -40559,7 +40646,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S zend_undefined_method(obj->ce, Z_STR_P(function_name)); } - + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } HANDLE_EXCEPTION(); } if (IS_CONST == IS_CONST && @@ -40568,8 +40657,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - /* Reset "object" to trigger reference counting */ - object = NULL; + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); @@ -40582,9 +40673,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } } /* call static method */ obj = (zend_object*)called_scope; @@ -40592,12 +40685,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CV == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ - } else { - zval *free_op1 = EX_VAR(opline->op1.var); - if (free_op1 != object) { - GC_ADDREF(obj); /* For $this pointer */ - zval_ptr_dtor_nogc(free_op1); - } } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -44086,8 +44173,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA do { if (IS_CV == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - object = Z_REFVAL_P(object); + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + if (IS_CV & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } break; } } @@ -44131,7 +44227,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA zend_undefined_method(obj->ce, Z_STR_P(function_name)); } zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } HANDLE_EXCEPTION(); } if ((IS_TMP_VAR|IS_VAR) == IS_CONST && @@ -44140,8 +44238,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - /* Reset "object" to trigger reference counting */ - object = NULL; + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); @@ -44154,9 +44254,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } } /* call static method */ obj = (zend_object*)called_scope; @@ -44164,12 +44266,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CV == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ - } else { - zval *free_op1 = EX_VAR(opline->op1.var); - if (free_op1 != object) { - GC_ADDREF(obj); /* For $this pointer */ - zval_ptr_dtor_nogc(free_op1); - } } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; @@ -49195,8 +49291,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA do { if (IS_CV == IS_CONST || UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - object = Z_REFVAL_P(object); + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + if (IS_CV & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } break; } } @@ -49240,7 +49345,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA zend_undefined_method(obj->ce, Z_STR_P(function_name)); } - + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } HANDLE_EXCEPTION(); } if (IS_CV == IS_CONST && @@ -49249,8 +49356,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - /* Reset "object" to trigger reference counting */ - object = NULL; + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); @@ -49263,9 +49372,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } } /* call static method */ obj = (zend_object*)called_scope; @@ -49273,12 +49384,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { if (IS_CV == IS_CV) { GC_ADDREF(obj); /* For $this pointer */ - } else { - zval *free_op1 = EX_VAR(opline->op1.var); - if (free_op1 != object) { - GC_ADDREF(obj); /* For $this pointer */ - zval_ptr_dtor_nogc(free_op1); - } } /* CV may be changed indirectly (e.g. when it's a reference) */ call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; -- 2.40.0