Skip to content

Commit

Permalink
Separate "cold" and common unspecialized code
Browse files Browse the repository at this point in the history
  • Loading branch information
dstogov committed Jul 16, 2019
1 parent a520974 commit ee58282
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 235 deletions.
24 changes: 23 additions & 1 deletion Zend/zend_execute.c
Expand Up @@ -1313,11 +1313,14 @@ 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, zval *value OPLINE_DC EXECUTE_DATA_DC)
static zend_never_inline void zend_binary_assign_op_obj_dim(zval *object, zval *property OPLINE_DC EXECUTE_DATA_DC)
{
zend_free_op free_op_data1;
zval *value;
zval *z;
zval rv, res;

value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
if ((z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv)) != NULL) {

if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
Expand Down Expand Up @@ -1345,6 +1348,7 @@ static zend_never_inline void zend_binary_assign_op_obj_dim(zval *object, zval *
ZVAL_NULL(EX_VAR(opline->result.var));
}
}
FREE_OP(free_op_data1);
}

static zend_never_inline void zend_binary_assign_op_typed_ref(zend_reference *ref, zval *value OPLINE_DC EXECUTE_DATA_DC)
Expand Down Expand Up @@ -2005,6 +2009,24 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_use_new_element_for_s
zend_throw_error(NULL, "[] operator not supported for strings");
}

static ZEND_COLD void zend_binary_assign_op_dim_slow(zval *container, zval *dim OPLINE_DC EXECUTE_DATA_DC)
{
zend_free_op free_op_data1;

if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
if (opline->op2_type == IS_UNUSED) {
zend_use_new_element_for_string();
} else {
zend_check_string_offset(dim, BP_VAR_RW EXECUTE_DATA_CC);
zend_wrong_string_offset(EXECUTE_DATA_C);
}
} else if (EXPECTED(!Z_ISERROR_P(container))) {
zend_use_scalar_as_array();
}
get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
FREE_OP(free_op_data1);
}

static zend_never_inline zend_uchar slow_index_convert(const zval *dim, zend_value *value EXECUTE_DATA_DC)
{
switch (Z_TYPE_P(dim)) {
Expand Down
38 changes: 12 additions & 26 deletions Zend/zend_vm_def.h
Expand Up @@ -1253,6 +1253,7 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array):
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
}
FREE_OP(free_op_data1);
} else {
if (EXPECTED(Z_ISREF_P(container))) {
container = Z_REFVAL_P(container);
Expand All @@ -1264,42 +1265,27 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array):
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);

if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
dim++;
}
zend_binary_assign_op_obj_dim(container, dim, value OPLINE_CC EXECUTE_DATA_CC);
zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC);
} else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
ZVAL_NULL(container);
ZVAL_UNDEFINED_OP1();
}
ZVAL_ARR(container, zend_new_array(8));
ZEND_VM_C_GOTO(assign_dim_op_new_array);
} else {
if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
if (OP2_TYPE == IS_UNUSED) {
zend_use_new_element_for_string();
} else {
zend_check_string_offset(dim, BP_VAR_RW EXECUTE_DATA_CC);
zend_wrong_string_offset(EXECUTE_DATA_C);
}
UNDEF_RESULT();
} else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
ZVAL_NULL(container);
ZVAL_UNDEFINED_OP1();
}
ZVAL_ARR(container, zend_new_array(8));
ZEND_VM_C_GOTO(assign_dim_op_new_array);
} else {
if (UNEXPECTED(OP1_TYPE != IS_VAR || EXPECTED(!Z_ISERROR_P(container)))) {
zend_use_scalar_as_array();
}
zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
ZEND_VM_C_LABEL(assign_dim_op_ret_null):
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
}
}

FREE_OP2();
FREE_OP(free_op_data1);
FREE_OP1_VAR_PTR();
ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
Expand Down

0 comments on commit ee58282

Please sign in to comment.