]> granicus.if.org Git - php/commitdiff
Use interned strings for one character strings
authorDmitry Stogov <dmitry@zend.com>
Tue, 1 Apr 2014 14:06:50 +0000 (18:06 +0400)
committerDmitry Stogov <dmitry@zend.com>
Tue, 1 Apr 2014 14:06:50 +0000 (18:06 +0400)
Zend/zend_execute.c
Zend/zend_globals.h
Zend/zend_string.c
ext/opcache/ZendAccelerator.c

index e2de52c7777a6f06f84ac45ed495075752e478ea..bdc0e2e8dbef94a5e7647988763fa0949112de2a 100644 (file)
@@ -1225,7 +1225,7 @@ static void zend_fetch_dimension_address_read(zval *result, zval *container, zva
                                zval tmp;
                                zend_string *str;
 
-                               if (Z_TYPE_P(dim) != IS_LONG) {
+                               if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
                                        switch(Z_TYPE_P(dim)) {
                                                /* case IS_LONG: */
                                                case IS_STRING:
@@ -1253,13 +1253,19 @@ static void zend_fetch_dimension_address_read(zval *result, zval *container, zva
                                        dim = &tmp;
                                }
 
-                               if (Z_LVAL_P(dim) < 0 || Z_STRLEN_P(container) <= Z_LVAL_P(dim)) {
+                               if (UNEXPECTED(Z_LVAL_P(dim) < 0) || UNEXPECTED(Z_STRLEN_P(container) <= Z_LVAL_P(dim))) {
                                        if (type != BP_VAR_IS) {
                                                zend_error(E_NOTICE, "Uninitialized string offset: %ld", Z_LVAL_P(dim));
                                        }
                                        str = STR_EMPTY_ALLOC();
                                } else {
-                                       str = STR_INIT(Z_STRVAL_P(container) + Z_LVAL_P(dim), 1, 0);
+                                       zend_uchar c = (zend_uchar)Z_STRVAL_P(container)[Z_LVAL_P(dim)];
+                                       
+                                       if (CG(one_char_string)[c]) {
+                                               str = CG(one_char_string)[c];
+                                       } else {
+                                               str = STR_INIT(Z_STRVAL_P(container) + Z_LVAL_P(dim), 1, 0);
+                                       }
                                }
                                ZVAL_STR(result, str);
                                return;
index 9dae1fcfcaf5fe808c2e775df4a2a723592c6240..828acfa106ce5a7596da4e6a838925f454964be9 100644 (file)
@@ -141,6 +141,7 @@ struct _zend_compiler_globals {
        zend_stack context_stack;
 
        zend_string *empty_string;
+       zend_string *one_char_string[256];
 
        HashTable interned_strings;
 
index 170cb2c200151aa43afedb0fde9fde9a37acb3af..abd784ed5f96eb7d4e804b36ba77d0921aabfb25 100644 (file)
@@ -57,6 +57,9 @@ void zend_interned_strings_init(TSRMLS_D)
        str = STR_ALLOC(sizeof("")-1, 1);
        str->val[0] = '\000';
        CG(empty_string) = zend_new_interned_string_int(str TSRMLS_CC);
+
+       /* one char strings (the actual interned strings are going to be created by ext/opcache) */
+       memset(CG(one_char_string), 0, sizeof(CG(one_char_string)));
 #else
        str = STR_ALLOC(sizeof("")-1, 1);
        str->val[0] = '\000';
index 1bf672e3df515ae691e8520cbb30fbea112fd1cc..cb93fbf63398dd91c6b4601ce7e09f402fdcbc6d 100644 (file)
@@ -382,6 +382,12 @@ static void accel_use_shm_interned_strings(TSRMLS_D)
 #if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO
        /* empty string */
        CG(empty_string) = accel_new_interned_string(CG(empty_string) TSRMLS_CC);
+       for (j = 0; j < 256; j++) {
+               char s[2];
+               s[0] = j;
+               s[1] = 0;
+               CG(one_char_string)[j] = accel_new_interned_string(STR_INIT(s, 1, 0) TSRMLS_CC);
+       }
 #endif
 
        /* function table hash keys */