Skip to content

Commit 069aa8c

Browse files
committed
RC1 optimisation for strto{lower,upper}
1 parent a92dedc commit 069aa8c

File tree

1 file changed

+16
-8
lines changed

1 file changed

+16
-8
lines changed

Zend/zend_operators.c

+16-8
Original file line numberDiff line numberDiff line change
@@ -2877,6 +2877,18 @@ ZEND_API char* ZEND_FASTCALL zend_str_toupper_dup_ex(const char *source, size_t
28772877
}
28782878
/* }}} */
28792879

2880+
static zend_string* ZEND_FASTCALL zend_string_alloc_or_partial_dup(zend_string *str, bool persistent, const unsigned char *p)
2881+
{
2882+
if (persistent || !zend_may_modify_string_in_place(str)) {
2883+
zend_string *res = zend_string_alloc(ZSTR_LEN(str), persistent);
2884+
memcpy(ZSTR_VAL(res), ZSTR_VAL(str), p - (unsigned char *) ZSTR_VAL(str));
2885+
return res;
2886+
} else {
2887+
zend_string_forget_hash_val(str);
2888+
return str;
2889+
}
2890+
}
2891+
28802892
ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower_ex(zend_string *str, bool persistent) /* {{{ */
28812893
{
28822894
size_t length = ZSTR_LEN(str);
@@ -2888,8 +2900,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower_ex(zend_string *str, boo
28882900
while (p + BLOCKCONV_STRIDE <= end) {
28892901
BLOCKCONV_LOAD(p);
28902902
if (BLOCKCONV_FOUND()) {
2891-
zend_string *res = zend_string_alloc(length, persistent);
2892-
memcpy(ZSTR_VAL(res), ZSTR_VAL(str), p - (unsigned char *) ZSTR_VAL(str));
2903+
zend_string *res = zend_string_alloc_or_partial_dup(str, persistent, p);
28932904
unsigned char *q = (unsigned char*) ZSTR_VAL(res) + (p - (unsigned char*) ZSTR_VAL(str));
28942905

28952906
/* Lowercase the chunk we already compared. */
@@ -2909,8 +2920,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower_ex(zend_string *str, boo
29092920

29102921
while (p < end) {
29112922
if (*p != zend_tolower_ascii(*p)) {
2912-
zend_string *res = zend_string_alloc(length, persistent);
2913-
memcpy(ZSTR_VAL(res), ZSTR_VAL(str), p - (unsigned char*) ZSTR_VAL(str));
2923+
zend_string *res = zend_string_alloc_or_partial_dup(str, persistent, p);
29142924

29152925
unsigned char *q = (unsigned char*) ZSTR_VAL(res) + (p - (unsigned char*) ZSTR_VAL(str));
29162926
while (p < end) {
@@ -2937,8 +2947,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_toupper_ex(zend_string *str, boo
29372947
while (p + BLOCKCONV_STRIDE <= end) {
29382948
BLOCKCONV_LOAD(p);
29392949
if (BLOCKCONV_FOUND()) {
2940-
zend_string *res = zend_string_alloc(length, persistent);
2941-
memcpy(ZSTR_VAL(res), ZSTR_VAL(str), p - (unsigned char *) ZSTR_VAL(str));
2950+
zend_string *res = zend_string_alloc_or_partial_dup(str, persistent, p);
29422951
unsigned char *q = (unsigned char *) ZSTR_VAL(res) + (p - (unsigned char *) ZSTR_VAL(str));
29432952

29442953
/* Uppercase the chunk we already compared. */
@@ -2958,8 +2967,7 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_toupper_ex(zend_string *str, boo
29582967

29592968
while (p < end) {
29602969
if (*p != zend_toupper_ascii(*p)) {
2961-
zend_string *res = zend_string_alloc(length, persistent);
2962-
memcpy(ZSTR_VAL(res), ZSTR_VAL(str), p - (unsigned char*) ZSTR_VAL(str));
2970+
zend_string *res = zend_string_alloc_or_partial_dup(str, persistent, p);
29632971

29642972
unsigned char *q = (unsigned char *) ZSTR_VAL(res) + (p - (unsigned char *) ZSTR_VAL(str));
29652973
while (p < end) {

0 commit comments

Comments
 (0)