summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-04-01 18:06:50 +0400
committerDmitry Stogov <dmitry@zend.com>2014-04-01 18:06:50 +0400
commit8dedaf8512d7292c9df90bebae91362ba36e7a97 (patch)
tree4fc23181e2e0f00821850204c49a77b1c0c230c9
parent042c937f6915876a1aec014394daa1db8f75cea6 (diff)
downloadphp-git-8dedaf8512d7292c9df90bebae91362ba36e7a97.tar.gz
Use interned strings for one character strings
-rw-r--r--Zend/zend_execute.c12
-rw-r--r--Zend/zend_globals.h1
-rw-r--r--Zend/zend_string.c3
-rw-r--r--ext/opcache/ZendAccelerator.c6
4 files changed, 19 insertions, 3 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index e2de52c777..bdc0e2e8db 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -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;
diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h
index 9dae1fcfca..828acfa106 100644
--- a/Zend/zend_globals.h
+++ b/Zend/zend_globals.h
@@ -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;
diff --git a/Zend/zend_string.c b/Zend/zend_string.c
index 170cb2c200..abd784ed5f 100644
--- a/Zend/zend_string.c
+++ b/Zend/zend_string.c
@@ -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';
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index 1bf672e3df..cb93fbf633 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -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 */