diff options
author | Bob Weinand <bobwei9@hotmail.com> | 2015-06-03 02:57:16 +0200 |
---|---|---|
committer | Bob Weinand <bobwei9@hotmail.com> | 2015-06-03 02:57:16 +0200 |
commit | 8a1c5d15d24f6ee23a9aa9357e51922778ffc07d (patch) | |
tree | de3afbbd5e7d16e5442c87843c04aca901e35a3c /Zend/zend_operators.c | |
parent | 06332e67067e9fea3117cbce8c164d99027ee142 (diff) | |
download | php-git-8a1c5d15d24f6ee23a9aa9357e51922778ffc07d.tar.gz |
Use CG(one_char_string) if possible in bitwise string operations
emalloc() is not cheap... Also, a good part of bitwise string ops out there are on single bytes.
Diffstat (limited to 'Zend/zend_operators.c')
-rw-r--r-- | Zend/zend_operators.c | 52 |
1 files changed, 44 insertions, 8 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index e384031ddb..dc02c03899 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -1249,11 +1249,20 @@ try_again: case IS_STRING: { size_t i; - ZVAL_NEW_STR(result, zend_string_alloc(Z_STRLEN_P(op1), 0)); - for (i = 0; i < Z_STRLEN_P(op1); i++) { - Z_STRVAL_P(result)[i] = ~Z_STRVAL_P(op1)[i]; + if (Z_STRLEN_P(op1) == 1) { + zend_uchar not = (zend_uchar) ~*Z_STRVAL_P(op1); + if (CG(one_char_string)[not]) { + ZVAL_INTERNED_STR(result, CG(one_char_string)[not]); + } else { + ZVAL_NEW_STR(result, zend_string_init((char *) ¬, 1, 0)); + } + } else { + ZVAL_NEW_STR(result, zend_string_alloc(Z_STRLEN_P(op1), 0)); + for (i = 0; i < Z_STRLEN_P(op1); i++) { + Z_STRVAL_P(result)[i] = ~Z_STRVAL_P(op1)[i]; + } + Z_STRVAL_P(result)[i] = 0; } - Z_STRVAL_P(result)[i] = 0; return SUCCESS; } case IS_REFERENCE: @@ -1280,12 +1289,21 @@ ZEND_API int ZEND_FASTCALL bitwise_or_function(zval *result, zval *op1, zval *op ZVAL_DEREF(op1); ZVAL_DEREF(op2); - if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) { + if (Z_TYPE_P(op1) == IS_STRING && EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { zval *longer, *shorter; zend_string *str; size_t i; - if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) { + if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) { + if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) { + zend_uchar or = (zend_uchar) (*Z_STRVAL_P(op1) | *Z_STRVAL_P(op2)); + if (CG(one_char_string)[or]) { + ZVAL_INTERNED_STR(result, CG(one_char_string)[or]); + } else { + ZVAL_NEW_STR(result, zend_string_init((char *) &or, 1, 0)); + } + return SUCCESS; + } longer = op1; shorter = op2; } else { @@ -1343,7 +1361,16 @@ ZEND_API int ZEND_FASTCALL bitwise_and_function(zval *result, zval *op1, zval *o zend_string *str; size_t i; - if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) { + if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) { + if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) { + zend_uchar and = (zend_uchar) (*Z_STRVAL_P(op1) & *Z_STRVAL_P(op2)); + if (CG(one_char_string)[and]) { + ZVAL_INTERNED_STR(result, CG(one_char_string)[and]); + } else { + ZVAL_NEW_STR(result, zend_string_init((char *) &and, 1, 0)); + } + return SUCCESS; + } longer = op1; shorter = op2; } else { @@ -1401,7 +1428,16 @@ ZEND_API int ZEND_FASTCALL bitwise_xor_function(zval *result, zval *op1, zval *o zend_string *str; size_t i; - if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) { + if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) { + if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) { + zend_uchar xor = (zend_uchar) (*Z_STRVAL_P(op1) ^ *Z_STRVAL_P(op2)); + if (CG(one_char_string)[xor]) { + ZVAL_INTERNED_STR(result, CG(one_char_string)[xor]); + } else { + ZVAL_NEW_STR(result, zend_string_init((char *) &xor, 1, 0)); + } + return SUCCESS; + } longer = op1; shorter = op2; } else { |