From 08f1d470fb6cc418264884dc291e7d9b428bde5e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 7 Dec 2021 11:46:32 +0300 Subject: [PATCH] Separate "cold" code --- Zend/zend_execute.c | 6 +-- Zend/zend_vm_def.h | 33 +++++++++--- Zend/zend_vm_execute.h | 117 +++++++++++++++++++---------------------- 3 files changed, 81 insertions(+), 75 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index aa0a2e39ec4..084eb34a1b0 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1425,17 +1425,17 @@ static zend_always_inline int zend_binary_op(zval *ret, zval *op1, zval *op2 OPL return zend_binary_ops[opcode - ZEND_ADD](ret, op1, op2); } -static zend_never_inline void zend_binary_assign_op_obj_dim(zval *object, zval *property OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_binary_assign_op_obj_dim(zend_object *obj, zval *property OPLINE_DC EXECUTE_DATA_DC) { zval *value; zval *z; zval rv, res; value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - if ((z = Z_OBJ_HT_P(object)->read_dimension(Z_OBJ_P(object), property, BP_VAR_R, &rv)) != NULL) { + if ((z = obj->handlers->read_dimension(obj, property, BP_VAR_R, &rv)) != NULL) { if (zend_binary_op(&res, z, value OPLINE_CC) == SUCCESS) { - Z_OBJ_HT_P(object)->write_dimension(Z_OBJ_P(object), property, &res); + obj->handlers->write_dimension(obj, property, &res); } if (z == &rv) { zval_ptr_dtor(&rv); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 335c4f7a7ab..5632931cf21 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1145,6 +1145,27 @@ ZEND_VM_HANDLER(29, ZEND_ASSIGN_STATIC_PROP_OP, ANY, ANY, OP) ZEND_VM_NEXT_OPCODE_EX(1, 2); } +ZEND_VM_COLD_HELPER(zend_assign_dim_op_obj_undef_helper, ANY, ANY, zend_object *obj) +{ + USE_OPLINE + zval *dim; + + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + FREE_OP_DATA(); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + } + FREE_OP2(); + FREE_OP1(); + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + ZEND_VM_HANDLER(27, ZEND_ASSIGN_DIM_OP, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, OP) { USE_OPLINE @@ -1203,19 +1224,15 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array): } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); if (OP2_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - ZEND_VM_C_GOTO(assign_dim_op_ret_null); - } + ZEND_VM_DISPATCH_TO_HELPER(zend_assign_dim_op_obj_undef_helper, obj, obj); } else if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type; diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 2596d5261a4..96e21e38241 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -799,6 +799,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_OP_SPEC_HAN ZEND_VM_NEXT_OPCODE_EX(1, 2); } +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_assign_dim_op_obj_undef_helper_SPEC(zend_object *obj ZEND_OPCODE_HANDLER_ARGS_DC) +{ + USE_OPLINE + zval *dim; + + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + } + FREE_OP(opline->op2_type, opline->op2.var); + FREE_OP(opline->op1_type, opline->op1.var); + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_STATIC_PROP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -22445,19 +22466,15 @@ assign_dim_op_new_array: } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } + ZEND_VM_TAIL_CALL(zend_assign_dim_op_obj_undef_helper_SPEC(obj ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type; @@ -25124,19 +25141,15 @@ assign_dim_op_new_array: } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } + ZEND_VM_TAIL_CALL(zend_assign_dim_op_obj_undef_helper_SPEC(obj ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type; @@ -27441,19 +27454,15 @@ assign_dim_op_new_array: } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } + ZEND_VM_TAIL_CALL(zend_assign_dim_op_obj_undef_helper_SPEC(obj ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type; @@ -29306,19 +29315,15 @@ assign_dim_op_new_array: } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } + ZEND_VM_TAIL_CALL(zend_assign_dim_op_obj_undef_helper_SPEC(obj ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type; @@ -40038,19 +40043,15 @@ assign_dim_op_new_array: } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } + ZEND_VM_TAIL_CALL(zend_assign_dim_op_obj_undef_helper_SPEC(obj ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type; @@ -43796,19 +43797,15 @@ assign_dim_op_new_array: } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } + ZEND_VM_TAIL_CALL(zend_assign_dim_op_obj_undef_helper_SPEC(obj ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type; @@ -46689,19 +46686,15 @@ assign_dim_op_new_array: } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } + ZEND_VM_TAIL_CALL(zend_assign_dim_op_obj_undef_helper_SPEC(obj ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type; @@ -49085,19 +49078,15 @@ assign_dim_op_new_array: } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } + ZEND_VM_TAIL_CALL(zend_assign_dim_op_obj_undef_helper_SPEC(obj ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type;