summaryrefslogtreecommitdiff
path: root/Zend/zend_operators.c
diff options
context:
space:
mode:
authorBob Weinand <bobwei9@hotmail.com>2015-06-03 02:57:16 +0200
committerBob Weinand <bobwei9@hotmail.com>2015-06-03 02:57:16 +0200
commit8a1c5d15d24f6ee23a9aa9357e51922778ffc07d (patch)
treede3afbbd5e7d16e5442c87843c04aca901e35a3c /Zend/zend_operators.c
parent06332e67067e9fea3117cbce8c164d99027ee142 (diff)
downloadphp-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.c52
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 *) &not, 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 {