diff options
author | Dmitry Stogov <dmitry@zend.com> | 2018-07-25 12:48:16 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2018-07-25 12:48:16 +0300 |
commit | aed3de1bc58c21fa00e3e732992ea5e64bcbe1f0 (patch) | |
tree | eafbab51f383964d7d9d45801c650cc2da5db929 /Zend/zend_operators.c | |
parent | df6bd506d492292ef4353b0f8da0c34eeb076be5 (diff) | |
download | php-git-aed3de1bc58c21fa00e3e732992ea5e64bcbe1f0.tar.gz |
Split add/sub_function(s) into fast and slow parts
Diffstat (limited to 'Zend/zend_operators.c')
-rw-r--r-- | Zend/zend_operators.c | 231 |
1 files changed, 132 insertions, 99 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index add1e4ecf9..d639eb6b9d 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -901,132 +901,165 @@ try_again: } /* }}} */ -ZEND_API int ZEND_FASTCALL add_function(zval *result, zval *op1, zval *op2) /* {{{ */ +static zend_never_inline void ZEND_FASTCALL add_function_array(zval *result, zval *op1, zval *op2) /* {{{ */ { - zval op1_copy, op2_copy; - int converted = 0; - - while (1) { - zend_uchar type_pair = TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2)); - - if (EXPECTED(type_pair == TYPE_PAIR(IS_LONG, IS_LONG))) { - fast_long_add_function(result, op1, op2); - return SUCCESS; + if ((result == op1) && (result == op2)) { + /* $a += $a */ + return; + } + if (result != op1) { + ZVAL_ARR(result, zend_array_dup(Z_ARR_P(op1))); + } else { + SEPARATE_ARRAY(result); + } + zend_hash_merge(Z_ARRVAL_P(result), Z_ARRVAL_P(op2), zval_add_ref, 0); +} +/* }}} */ - } else if (EXPECTED(type_pair == TYPE_PAIR(IS_DOUBLE, IS_DOUBLE))) { - ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); - return SUCCESS; +static zend_always_inline int add_function_fast(zval *result, zval *op1, zval *op2) /* {{{ */ +{ + zend_uchar type_pair = TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2)); - } else if (EXPECTED(type_pair == TYPE_PAIR(IS_LONG, IS_DOUBLE))) { - ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2)); - return SUCCESS; + if (EXPECTED(type_pair == TYPE_PAIR(IS_LONG, IS_LONG))) { + fast_long_add_function(result, op1, op2); + return SUCCESS; + } else if (EXPECTED(type_pair == TYPE_PAIR(IS_DOUBLE, IS_DOUBLE))) { + ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); + return SUCCESS; + } else if (EXPECTED(type_pair == TYPE_PAIR(IS_LONG, IS_DOUBLE))) { + ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2)); + return SUCCESS; + } else if (EXPECTED(type_pair == TYPE_PAIR(IS_DOUBLE, IS_LONG))) { + ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2))); + return SUCCESS; + } else if (EXPECTED(type_pair == TYPE_PAIR(IS_ARRAY, IS_ARRAY))) { + add_function_array(result, op1, op2); + return SUCCESS; + } else { + return FAILURE; + } +} /* }}} */ - } else if (EXPECTED(type_pair == TYPE_PAIR(IS_DOUBLE, IS_LONG))) { - ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2))); - return SUCCESS; +static zend_never_inline int ZEND_FASTCALL add_function_slow(zval *result, zval *op1, zval *op2) /* {{{ */ +{ + zval op1_copy, op2_copy; + int converted = 0; - } else if (EXPECTED(type_pair == TYPE_PAIR(IS_ARRAY, IS_ARRAY))) { - if ((result == op1) && (result == op2)) { - /* $a += $a */ - return SUCCESS; - } - if (result != op1) { - ZVAL_ARR(result, zend_array_dup(Z_ARR_P(op1))); + while (1) { + if (Z_ISREF_P(op1)) { + op1 = Z_REFVAL_P(op1); + } else if (Z_ISREF_P(op2)) { + op2 = Z_REFVAL_P(op2); + } else if (!converted) { + ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_ADD, add_function); + + if (EXPECTED(op1 != op2)) { + op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0); + op2 = zendi_convert_scalar_to_number(op2, &op2_copy, result, 0); } else { - SEPARATE_ARRAY(result); + op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0); + op2 = op1; } - zend_hash_merge(Z_ARRVAL_P(result), Z_ARRVAL_P(op2), zval_add_ref, 0); - return SUCCESS; - - } else { - if (Z_ISREF_P(op1)) { - op1 = Z_REFVAL_P(op1); - } else if (Z_ISREF_P(op2)) { - op2 = Z_REFVAL_P(op2); - } else if (!converted) { - ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_ADD, add_function); - - if (EXPECTED(op1 != op2)) { - op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0); - op2 = zendi_convert_scalar_to_number(op2, &op2_copy, result, 0); - } else { - op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0); - op2 = op1; - } - if (EG(exception)) { - if (result != op1) { - ZVAL_UNDEF(result); - } - return FAILURE; - } - converted = 1; - } else { + if (EG(exception)) { if (result != op1) { ZVAL_UNDEF(result); } - zend_throw_error(NULL, "Unsupported operand types"); - return FAILURE; /* unknown datatype */ + return FAILURE; } + converted = 1; + } else { + if (result != op1) { + ZVAL_UNDEF(result); + } + zend_throw_error(NULL, "Unsupported operand types"); + return FAILURE; /* unknown datatype */ } + if (add_function_fast(result, op1, op2) == SUCCESS) { + return SUCCESS; + } + } +} /* }}} */ + +ZEND_API int ZEND_FASTCALL add_function(zval *result, zval *op1, zval *op2) /* {{{ */ +{ + if (add_function_fast(result, op1, op2) == SUCCESS) { + return SUCCESS; + } else { + return add_function_slow(result, op1, op2); } } /* }}} */ -ZEND_API int ZEND_FASTCALL sub_function(zval *result, zval *op1, zval *op2) /* {{{ */ +static zend_always_inline int sub_function_fast(zval *result, zval *op1, zval *op2) /* {{{ */ +{ + zend_uchar type_pair = TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2)); + + if (EXPECTED(type_pair == TYPE_PAIR(IS_LONG, IS_LONG))) { + fast_long_sub_function(result, op1, op2); + return SUCCESS; + } else if (EXPECTED(type_pair == TYPE_PAIR(IS_DOUBLE, IS_DOUBLE))) { + ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); + return SUCCESS; + } else if (EXPECTED(type_pair == TYPE_PAIR(IS_LONG, IS_DOUBLE))) { + ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2)); + return SUCCESS; + } else if (EXPECTED(type_pair == TYPE_PAIR(IS_DOUBLE, IS_LONG))) { + ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2))); + return SUCCESS; + } else { + return FAILURE; + } +} +/* }}} */ + +static zend_never_inline int ZEND_FASTCALL sub_function_slow(zval *result, zval *op1, zval *op2) /* {{{ */ { zval op1_copy, op2_copy; int converted = 0; - while (1) { - zend_uchar type_pair = TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2)); - - if (EXPECTED(type_pair == TYPE_PAIR(IS_LONG, IS_LONG))) { - fast_long_sub_function(result, op1, op2); - return SUCCESS; - - } else if (EXPECTED(type_pair == TYPE_PAIR(IS_DOUBLE, IS_DOUBLE))) { - ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); - return SUCCESS; - - } else if (EXPECTED(type_pair == TYPE_PAIR(IS_LONG, IS_DOUBLE))) { - ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2)); - return SUCCESS; - - } else if (EXPECTED(type_pair == TYPE_PAIR(IS_DOUBLE, IS_LONG))) { - ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2))); - return SUCCESS; - - } else { - if (Z_ISREF_P(op1)) { - op1 = Z_REFVAL_P(op1); - } else if (Z_ISREF_P(op2)) { - op2 = Z_REFVAL_P(op2); - } else if (!converted) { - ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SUB, sub_function); - - if (EXPECTED(op1 != op2)) { - op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0); - op2 = zendi_convert_scalar_to_number(op2, &op2_copy, result, 0); - } else { - op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0); - op2 = op1; - } - if (EG(exception)) { - if (result != op1) { - ZVAL_UNDEF(result); - } - return FAILURE; - } - converted = 1; + if (Z_ISREF_P(op1)) { + op1 = Z_REFVAL_P(op1); + } else if (Z_ISREF_P(op2)) { + op2 = Z_REFVAL_P(op2); + } else if (!converted) { + ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SUB, sub_function); + + if (EXPECTED(op1 != op2)) { + op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0); + op2 = zendi_convert_scalar_to_number(op2, &op2_copy, result, 0); } else { + op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0); + op2 = op1; + } + if (EG(exception)) { if (result != op1) { ZVAL_UNDEF(result); } - zend_throw_error(NULL, "Unsupported operand types"); - return FAILURE; /* unknown datatype */ + return FAILURE; } + converted = 1; + } else { + if (result != op1) { + ZVAL_UNDEF(result); + } + zend_throw_error(NULL, "Unsupported operand types"); + return FAILURE; /* unknown datatype */ + } + if (sub_function_fast(result, op1, op2) == SUCCESS) { + return SUCCESS; } } + +} +/* }}} */ + +ZEND_API int ZEND_FASTCALL sub_function(zval *result, zval *op1, zval *op2) /* {{{ */ +{ + if (sub_function_fast(result, op1, op2) == SUCCESS) { + return SUCCESS; + } else { + return sub_function_slow(result, op1, op2); + } } /* }}} */ |