summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2016-05-12 13:47:22 +0300
committerDmitry Stogov <dmitry@zend.com>2016-05-12 13:47:22 +0300
commit7b94b958ccbc87595d688d178f96daf96a9f54b3 (patch)
treef74f2fdf78a194c86fa7d34f27e0cf8f1e2d8ec0
parent00390449c6c5d3cb65e129cb558b9e523e17090f (diff)
downloadphp-git-7b94b958ccbc87595d688d178f96daf96a9f54b3.tar.gz
Intern some known (and offten used) strings.
-rw-r--r--Zend/zend.c4
-rw-r--r--Zend/zend_API.c17
-rw-r--r--Zend/zend_API.h1
-rw-r--r--Zend/zend_builtin_functions.c75
-rw-r--r--Zend/zend_closures.c6
-rw-r--r--Zend/zend_compile.c2
-rw-r--r--Zend/zend_exceptions.c165
-rw-r--r--Zend/zend_execute.c4
-rw-r--r--Zend/zend_execute_API.c2
-rw-r--r--Zend/zend_globals.h2
-rw-r--r--Zend/zend_language_parser.y2
-rw-r--r--Zend/zend_object_handlers.c2
-rw-r--r--Zend/zend_operators.c2
-rw-r--r--Zend/zend_string.c40
-rw-r--r--Zend/zend_string.h56
-rw-r--r--Zend/zend_vm_def.h6
-rw-r--r--Zend/zend_vm_execute.h12
-rw-r--r--ext/opcache/ZendAccelerator.c3
18 files changed, 262 insertions, 139 deletions
diff --git a/Zend/zend.c b/Zend/zend.c
index 50cda403f6..c4b91ce31a 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -501,7 +501,7 @@ static void compiler_globals_ctor(zend_compiler_globals *compiler_globals) /* {{
}
compiler_globals->script_encoding_list = NULL;
- zend_interned_empty_string_init(&compiler_globals->empty_string);
+ compiler_globals->empty_string = zend_zts_interned_string_init("", sizeof("")-1);
memset(compiler_globals->one_char_string, 0, sizeof(compiler_globals->one_char_string));
}
@@ -529,7 +529,7 @@ static void compiler_globals_dtor(zend_compiler_globals *compiler_globals) /* {{
}
compiler_globals->last_static_member = 0;
- zend_interned_empty_string_free(&compiler_globals->empty_string);
+ zend_zts_interned_string_free(&compiler_globals->empty_string);
}
/* }}} */
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index f646883435..536a9aec2c 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -4031,7 +4031,7 @@ ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, const
}
/* }}} */
-ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_bool silent, zval *rv) /* {{{ */
+ZEND_API zval *zend_read_property_ex(zend_class_entry *scope, zval *object, zend_string *name, zend_bool silent, zval *rv) /* {{{ */
{
zval property, *value;
zend_class_entry *old_scope = EG(fake_scope);
@@ -4042,15 +4042,26 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const c
zend_error_noreturn(E_CORE_ERROR, "Property %s of class %s cannot be read", name, ZSTR_VAL(Z_OBJCE_P(object)->name));
}
- ZVAL_STRINGL(&property, name, name_length);
+ ZVAL_STR(&property, name);
value = Z_OBJ_HT_P(object)->read_property(object, &property, silent?BP_VAR_IS:BP_VAR_R, NULL, rv);
- zval_ptr_dtor(&property);
EG(fake_scope) = old_scope;
return value;
}
/* }}} */
+ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_bool silent, zval *rv) /* {{{ */
+{
+ zval *value;
+ zend_string *str;
+
+ str = zend_string_init(name, name_length, 0);
+ value = zend_read_property_ex(scope, object, str, silent, rv);
+ zend_string_release(str);
+ return value;
+}
+/* }}} */
+
ZEND_API zval *zend_read_static_property(zend_class_entry *scope, const char *name, size_t name_length, zend_bool silent) /* {{{ */
{
zval *property;
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index 1078b257eb..91ba73cae7 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -351,6 +351,7 @@ ZEND_API int zend_update_static_property_double(zend_class_entry *scope, const c
ZEND_API int zend_update_static_property_string(zend_class_entry *scope, const char *name, size_t name_length, const char *value);
ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, const char *name, size_t name_length, const char *value, size_t value_length);
+ZEND_API zval *zend_read_property_ex(zend_class_entry *scope, zval *object, zend_string *name, zend_bool silent, zval *rv);
ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_bool silent, zval *rv);
ZEND_API zval *zend_read_static_property(zend_class_entry *scope, const char *name, size_t name_length, zend_bool silent);
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 0af280b97e..04827cfb67 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -736,7 +736,7 @@ ZEND_FUNCTION(each)
if (Z_REFCOUNTED_P(entry)) Z_ADDREF_P(entry);
}
zend_hash_index_add_new(Z_ARRVAL_P(return_value), 1, entry);
- zend_hash_str_add_new(Z_ARRVAL_P(return_value), "value", sizeof("value")-1, entry);
+ zend_hash_add_new(Z_ARRVAL_P(return_value), CG(known_strings)[ZEND_STR_VALUE], entry);
/* add the key elements */
if (zend_hash_get_current_key(target_hash, &key, &num_key) == HASH_KEY_IS_STRING) {
@@ -746,7 +746,7 @@ ZEND_FUNCTION(each)
ZVAL_LONG(&tmp, num_key);
}
zend_hash_index_add_new(Z_ARRVAL_P(return_value), 0, &tmp);
- zend_hash_str_add_new(Z_ARRVAL_P(return_value), "key", sizeof("key")-1, &tmp);
+ zend_hash_add_new(Z_ARRVAL_P(return_value), CG(known_strings)[ZEND_STR_KEY], &tmp);
zend_hash_move_forward(target_hash);
}
/* }}} */
@@ -776,7 +776,7 @@ ZEND_FUNCTION(error_reporting)
zend_ini_entry *p = EG(error_reporting_ini_entry);
if (!p) {
- p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1);
+ p = zend_hash_find_ptr(EG(ini_directives), CG(known_strings)[ZEND_STR_ERROR_REPORTING]);
if (p) {
EG(error_reporting_ini_entry) = p;
} else {
@@ -788,7 +788,7 @@ ZEND_FUNCTION(error_reporting)
ALLOC_HASHTABLE(EG(modified_ini_directives));
zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
}
- if (EXPECTED(zend_hash_str_add_ptr(EG(modified_ini_directives), "error_reporting", sizeof("error_reporting")-1, p) != NULL)) {
+ if (EXPECTED(zend_hash_add_ptr(EG(modified_ini_directives), CG(known_strings)[ZEND_STR_ERROR_REPORTING], p) != NULL)) {
p->orig_value = p->value;
p->orig_modifiable = p->modifiable;
p->modified = 1;
@@ -2570,7 +2570,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
zend_string *function_name;
zend_string *filename;
zend_string *include_filename = NULL;
- zval stack_frame;
+ zval stack_frame, tmp;
array_init(return_value);
@@ -2632,8 +2632,10 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
} else {
lineno = skip->opline->lineno;
}
- add_assoc_str_ex(&stack_frame, "file", sizeof("file")-1, zend_string_copy(filename));
- add_assoc_long_ex(&stack_frame, "line", sizeof("line")-1, lineno);
+ ZVAL_STR_COPY(&tmp, filename);
+ zend_hash_add_new(Z_ARRVAL(stack_frame), CG(known_strings)[ZEND_STR_FILE], &tmp);
+ ZVAL_LONG(&tmp, lineno);
+ zend_hash_add_new(Z_ARRVAL(stack_frame), CG(known_strings)[ZEND_STR_LINE], &tmp);
/* try to fetch args only if an FCALL was just made - elsewise we're in the middle of a function
* and debug_baktrace() might have been called by the error_handler. in this case we don't
@@ -2650,8 +2652,10 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
break;
}
if (prev->func && ZEND_USER_CODE(prev->func->common.type)) {
- add_assoc_str_ex(&stack_frame, "file", sizeof("file")-1, zend_string_copy(prev->func->op_array.filename));
- add_assoc_long_ex(&stack_frame, "line", sizeof("line")-1, prev->opline->lineno);
+ ZVAL_STR_COPY(&tmp, prev->func->op_array.filename);
+ zend_hash_add_new(Z_ARRVAL(stack_frame), CG(known_strings)[ZEND_STR_FILE], &tmp);
+ ZVAL_LONG(&tmp, prev->opline->lineno);
+ zend_hash_add_new(Z_ARRVAL(stack_frame), CG(known_strings)[ZEND_STR_LINE], &tmp);
break;
}
prev_call = prev;
@@ -2676,66 +2680,69 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
}
if (function_name) {
- add_assoc_str_ex(&stack_frame, "function", sizeof("function")-1, zend_string_copy(function_name));
+ ZVAL_STR_COPY(&tmp, function_name);
+ zend_hash_add_new(Z_ARRVAL(stack_frame), CG(known_strings)[ZEND_STR_FUNCTION], &tmp);
if (object) {
if (func->common.scope) {
- add_assoc_str_ex(&stack_frame, "class", sizeof("class")-1, zend_string_copy(func->common.scope->name));
+ ZVAL_STR_COPY(&tmp, func->common.scope->name);
} else {
- add_assoc_str_ex(&stack_frame, "class", sizeof("class")-1, zend_string_copy(object->ce->name));
+ ZVAL_STR_COPY(&tmp, object->ce->name);
}
+ zend_hash_add_new(Z_ARRVAL(stack_frame), CG(known_strings)[ZEND_STR_CLASS], &tmp);
if ((options & DEBUG_BACKTRACE_PROVIDE_OBJECT) != 0) {
- zval zv;
- ZVAL_OBJ(&zv, object);
- add_assoc_zval_ex(&stack_frame, "object", sizeof("object")-1, &zv);
- Z_ADDREF(zv);
+ ZVAL_OBJ(&tmp, object);
+ zend_hash_add_new(Z_ARRVAL(stack_frame), CG(known_strings)[ZEND_STR_OBJECT], &tmp);
+ Z_ADDREF(tmp);
}
- add_assoc_string_ex(&stack_frame, "type", sizeof("type")-1, "->");
+ ZVAL_INTERNED_STR(&tmp, CG(known_strings)[ZEND_STR_OBJECT_OPERATOR]);
+ zend_hash_add_new(Z_ARRVAL(stack_frame), CG(known_strings)[ZEND_STR_TYPE], &tmp);
} else if (func->common.scope) {
- add_assoc_str_ex(&stack_frame, "class", sizeof("class")-1, zend_string_copy(func->common.scope->name));
- add_assoc_string_ex(&stack_frame, "type", sizeof("type")-1, "::");
+ ZVAL_STR_COPY(&tmp, func->common.scope->name);
+ zend_hash_add_new(Z_ARRVAL(stack_frame), CG(known_strings)[ZEND_STR_CLASS], &tmp);
+ ZVAL_INTERNED_STR(&tmp, CG(known_strings)[ZEND_STR_PAAMAYIM_NEKUDOTAYIM]);
+ zend_hash_add_new(Z_ARRVAL(stack_frame), CG(known_strings)[ZEND_STR_TYPE], &tmp);
}
if ((options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0 &&
func->type != ZEND_EVAL_CODE) {
- zval args;
- debug_backtrace_get_args(call, &args);
- add_assoc_zval_ex(&stack_frame, "args", sizeof("args")-1, &args);
+ debug_backtrace_get_args(call, &tmp);
+ zend_hash_add_new(Z_ARRVAL(stack_frame), CG(known_strings)[ZEND_STR_ARGS], &tmp);
}
} else {
/* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
zend_bool build_filename_arg = 1;
- const char *pseudo_function_name;
+ zend_string *pseudo_function_name;
if (!ptr->func || !ZEND_USER_CODE(ptr->func->common.type) || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
/* can happen when calling eval from a custom sapi */
- pseudo_function_name = "unknown";
+ pseudo_function_name = CG(known_strings)[ZEND_STR_UNKNOWN];
build_filename_arg = 0;
} else
switch (ptr->opline->extended_value) {
case ZEND_EVAL:
- pseudo_function_name = "eval";
+ pseudo_function_name = CG(known_strings)[ZEND_STR_EVAL];
build_filename_arg = 0;
break;
case ZEND_INCLUDE:
- pseudo_function_name = "include";
+ pseudo_function_name = CG(known_strings)[ZEND_STR_INCLUDE];
break;
case ZEND_REQUIRE:
- pseudo_function_name = "require";
+ pseudo_function_name = CG(known_strings)[ZEND_STR_REQUIRE];
break;
case ZEND_INCLUDE_ONCE:
- pseudo_function_name = "include_once";
+ pseudo_function_name = CG(known_strings)[ZEND_STR_INCLUDE_ONCE];
break;
case ZEND_REQUIRE_ONCE:
- pseudo_function_name = "require_once";
+ pseudo_function_name = CG(known_strings)[ZEND_STR_REQUIRE_ONCE];
break;
default:
/* this can actually happen if you use debug_backtrace() in your error_handler and
* you're in the top-scope */
- pseudo_function_name = "unknown";
+ pseudo_function_name = CG(known_strings)[ZEND_STR_UNKNOWN];
build_filename_arg = 0;
break;
}
@@ -2749,11 +2756,13 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
if we have called include in the frame above - this is the file we have included.
*/
- add_next_index_str(&arg_array, zend_string_copy(include_filename));
- add_assoc_zval_ex(&stack_frame, "args", sizeof("args")-1, &arg_array);
+ ZVAL_STR_COPY(&tmp, include_filename);
+ zend_hash_next_index_insert_new(Z_ARRVAL(arg_array), &tmp);
+ zend_hash_add_new(Z_ARRVAL(stack_frame), CG(known_strings)[ZEND_STR_ARGS], &arg_array);
}
- add_assoc_string_ex(&stack_frame, "function", sizeof("function")-1, (char *) pseudo_function_name);
+ ZVAL_INTERNED_STR(&tmp, pseudo_function_name);
+ zend_hash_add_new(Z_ARRVAL(stack_frame), CG(known_strings)[ZEND_STR_FUNCTION], &tmp);
}
zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &stack_frame);
diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c
index 989ef769c8..810ac6a66c 100644
--- a/Zend/zend_closures.c
+++ b/Zend/zend_closures.c
@@ -271,7 +271,7 @@ ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *object) /* {
invoke->internal_function.handler = ZEND_MN(Closure___invoke);
invoke->internal_function.module = 0;
invoke->internal_function.scope = zend_ce_closure;
- invoke->internal_function.function_name = zend_string_init(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1, 0);
+ invoke->internal_function.function_name = CG(known_strings)[ZEND_STR_MAGIC_INVOKE];
return invoke;
}
/* }}} */
@@ -411,12 +411,12 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp) /* {{{
if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) {
HashTable *static_variables = closure->func.op_array.static_variables;
ZVAL_ARR(&val, zend_array_dup(static_variables));
- zend_hash_str_update(debug_info, "static", sizeof("static")-1, &val);
+ zend_hash_update(debug_info, CG(known_strings)[ZEND_STR_STATIC], &val);
}
if (Z_TYPE(closure->this_ptr) != IS_UNDEF) {
Z_ADDREF(closure->this_ptr);
- zend_hash_str_update(debug_info, "this", sizeof("this")-1, &closure->this_ptr);
+ zend_hash_update(debug_info, CG(known_strings)[ZEND_STR_THIS], &closure->this_ptr);
}
if (arg_info &&
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 50bcb3b7ad..b4cb05f616 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2544,7 +2544,7 @@ static zend_op *zend_compile_simple_var_no_cv(znode *result, zend_ast *ast, uint
if (ast->kind != ZEND_AST_ZVAL
&& CG(active_op_array)->scope && CG(active_op_array)->this_var == (uint32_t)-1
) {
- zend_string *key = zend_string_init("this", sizeof("this") - 1, 0);
+ zend_string *key = CG(known_strings)[ZEND_STR_THIS];
CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), key);
}
}
diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c
index 63bcca2640..4a85e4e73a 100644
--- a/Zend/zend_exceptions.c
+++ b/Zend/zend_exceptions.c
@@ -87,18 +87,18 @@ void zend_exception_set_previous(zend_object *exception, zend_object *add_previo
ZVAL_OBJ(&zv, exception);
ex = &zv;
do {
- ancestor = zend_read_property(i_get_exception_base(&pv), &pv, "previous", sizeof("previous")-1, 1, &rv);
+ ancestor = zend_read_property_ex(i_get_exception_base(&pv), &pv, CG(known_strings)[ZEND_STR_PREVIOUS], 1, &rv);
while (Z_TYPE_P(ancestor) == IS_OBJECT) {
if (Z_OBJ_P(ancestor) == Z_OBJ_P(ex)) {
OBJ_RELEASE(add_previous);
return;
}
- ancestor = zend_read_property(i_get_exception_base(ancestor), ancestor, "previous", sizeof("previous")-1, 1, &rv);
+ ancestor = zend_read_property_ex(i_get_exception_base(ancestor), ancestor, CG(known_strings)[ZEND_STR_PREVIOUS], 1, &rv);
}
base_ce = i_get_exception_base(ex);
- previous = zend_read_property(base_ce, ex, "previous", sizeof("previous")-1, 1, &rv);
+ previous = zend_read_property_ex(base_ce, ex, CG(known_strings)[ZEND_STR_PREVIOUS], 1, &rv);
if (Z_TYPE_P(previous) == IS_NULL) {
- zend_update_property(base_ce, ex, "previous", sizeof("previous")-1, &pv);
+ zend_update_property_ex(base_ce, ex, CG(known_strings)[ZEND_STR_PREVIOUS], &pv);
GC_REFCOUNT(add_previous)--;
return;
}
@@ -198,7 +198,7 @@ ZEND_API void zend_clear_exception(void) /* {{{ */
static zend_object *zend_default_exception_new_ex(zend_class_entry *class_type, int skip_top_traces) /* {{{ */
{
- zval obj;
+ zval obj, tmp;
zend_object *object;
zval trace;
zend_class_entry *base_ce;
@@ -219,13 +219,18 @@ static zend_object *zend_default_exception_new_ex(zend_class_entry *class_type,
base_ce = i_get_exception_base(&obj);
if (EXPECTED(class_type != zend_ce_parse_error || !(filename = zend_get_compiled_filename()))) {
- zend_update_property_string(base_ce, &obj, "file", sizeof("file")-1, zend_get_executed_filename());
- zend_update_property_long(base_ce, &obj, "line", sizeof("line")-1, zend_get_executed_lineno());
+ ZVAL_STRING(&tmp, zend_get_executed_filename());
+ zend_update_property_ex(base_ce, &obj, CG(known_strings)[ZEND_STR_FILE], &tmp);
+ zval_ptr_dtor(&tmp);
+ ZVAL_LONG(&tmp, zend_get_executed_lineno());
+ zend_update_property_ex(base_ce, &obj, CG(known_strings)[ZEND_STR_LINE], &tmp);
} else {
- zend_update_property_str(base_ce, &obj, "file", sizeof("file")-1, filename);
- zend_update_property_long(base_ce, &obj, "line", sizeof("line")-1, zend_get_compiled_lineno());
+ ZVAL_STR(&tmp, filename);
+ zend_update_property_ex(base_ce, &obj, CG(known_strings)[ZEND_STR_FILE], &tmp);
+ ZVAL_LONG(&tmp, zend_get_compiled_lineno());
+ zend_update_property_ex(base_ce, &obj, CG(known_strings)[ZEND_STR_LINE], &tmp);
}
- zend_update_property(base_ce, &obj, "trace", sizeof("trace")-1, &trace);
+ zend_update_property_ex(base_ce, &obj, CG(known_strings)[ZEND_STR_TRACE], &trace);
return object;
}
@@ -258,7 +263,7 @@ ZEND_METHOD(exception, __construct)
{
zend_string *message = NULL;
zend_long code = 0;
- zval *object, *previous = NULL;
+ zval tmp, *object, *previous = NULL;
zend_class_entry *base_ce;
int argc = ZEND_NUM_ARGS();
@@ -280,27 +285,29 @@ ZEND_METHOD(exception, __construct)
}
if (message) {
- zend_update_property_str(base_ce, object, "message", sizeof("message")-1, message);
+ ZVAL_STR(&tmp, message);
+ zend_update_property_ex(base_ce, object, CG(known_strings)[ZEND_STR_MESSAGE], &tmp);
}
if (code) {
- zend_update_property_long(base_ce, object, "code", sizeof("code")-1, code);
+ ZVAL_LONG(&tmp, code);
+ zend_update_property_ex(base_ce, object, CG(known_strings)[ZEND_STR_CODE], &tmp);
}
if (previous) {
- zend_update_property(base_ce, object, "previous", sizeof("previous")-1, previous);
+ zend_update_property_ex(base_ce, object, CG(known_strings)[ZEND_STR_PREVIOUS], previous);
}
}
/* }}} */
/* {{{ proto Exception::__wakeup()
Exception unserialize checks */
-#define CHECK_EXC_TYPE(name, type) \
+#define CHECK_EXC_TYPE(id, type) \
ZVAL_UNDEF(&value); \
- pvalue = zend_read_property(i_get_exception_base(object), (object), name, sizeof(name) - 1, 1, &value); \
+ pvalue = zend_read_property_ex(i_get_exception_base(object), (object), CG(known_strings)[id], 1, &value); \
if(Z_TYPE_P(pvalue) != IS_UNDEF && Z_TYPE_P(pvalue) != type) { \
zval tmp; \
- ZVAL_STRINGL(&tmp, name, sizeof(name) - 1); \
+ ZVAL_STR_COPY(&tmp, CG(known_strings)[id]); \
Z_OBJ_HANDLER_P(object, unset_property)(object, &tmp, NULL); \
zval_ptr_dtor(&tmp); \
}
@@ -309,13 +316,13 @@ ZEND_METHOD(exception, __wakeup)
{
zval value, *pvalue;
zval *object = getThis();
- CHECK_EXC_TYPE("message", IS_STRING);
- CHECK_EXC_TYPE("string", IS_STRING);
- CHECK_EXC_TYPE("code", IS_LONG);
- CHECK_EXC_TYPE("file", IS_STRING);
- CHECK_EXC_TYPE("line", IS_LONG);
- CHECK_EXC_TYPE("trace", IS_ARRAY);
- CHECK_EXC_TYPE("previous", IS_OBJECT);
+ CHECK_EXC_TYPE(ZEND_STR_MESSAGE, IS_STRING);
+ CHECK_EXC_TYPE(ZEND_STR_STRING, IS_STRING);
+ CHECK_EXC_TYPE(ZEND_STR_CODE, IS_LONG);
+ CHECK_EXC_TYPE(ZEND_STR_FILE, IS_STRING);
+ CHECK_EXC_TYPE(ZEND_STR_LINE, IS_LONG);
+ CHECK_EXC_TYPE(ZEND_STR_TRACE, IS_ARRAY);
+ CHECK_EXC_TYPE(ZEND_STR_PREVIOUS, IS_OBJECT);
}
/* }}} */
@@ -325,7 +332,7 @@ ZEND_METHOD(error_exception, __construct)
{
char *message = NULL, *filename = NULL;
zend_long code = 0, severity = E_ERROR, lineno;
- zval *object, *previous = NULL;
+ zval tmp, *object, *previous = NULL;
int argc = ZEND_NUM_ARGS();
size_t message_len, filename_len;
@@ -346,25 +353,32 @@ ZEND_METHOD(error_exception, __construct)
object = getThis();
if (message) {
- zend_update_property_string(zend_ce_exception, object, "message", sizeof("message")-1, message);
+ ZVAL_STRING(&tmp, message);
+ zend_update_property_ex(zend_ce_exception, object, CG(known_strings)[ZEND_STR_MESSAGE], &tmp);
+ zval_ptr_dtor(&tmp);
}
if (code) {
- zend_update_property_long(zend_ce_exception, object, "code", sizeof("code")-1, code);
+ ZVAL_LONG(&tmp, code);
+ zend_update_property_ex(zend_ce_exception, object, CG(known_strings)[ZEND_STR_CODE], &tmp);
}
if (previous) {
- zend_update_property(zend_ce_exception, object, "previous", sizeof("previous")-1, previous);
+ zend_update_property_ex(zend_ce_exception, object, CG(known_strings)[ZEND_STR_PREVIOUS], previous);
}
- zend_update_property_long(zend_ce_error_exception, object, "severity", sizeof("severity")-1, severity);
+ ZVAL_LONG(&tmp, severity);
+ zend_update_property_ex(zend_ce_exception, object, CG(known_strings)[ZEND_STR_SEVERITY], &tmp);
if (argc >= 4) {
- zend_update_property_string(zend_ce_exception, object, "file", sizeof("file")-1, filename);
+ ZVAL_STRING(&tmp, filename);
+ zend_update_property_ex(zend_ce_exception, object, CG(known_strings)[ZEND_STR_FILE], &tmp);
+ zval_ptr_dtor(&tmp);
if (argc < 5) {
lineno = 0; /* invalidate lineno */
}
- zend_update_property_long(zend_ce_exception, object, "line", sizeof("line")-1, lineno);
+ ZVAL_LONG(&tmp, lineno);
+ zend_update_property_ex(zend_ce_exception, object, CG(known_strings)[ZEND_STR_LINE], &tmp);
}
}
/* }}} */
@@ -374,10 +388,10 @@ ZEND_METHOD(error_exception, __construct)
return; \
}
-#define GET_PROPERTY(object, name) \
- zend_read_property(i_get_exception_base(object), (object), name, sizeof(name) - 1, 0, &rv)
-#define GET_PROPERTY_SILENT(object, name) \
- zend_read_property(i_get_exception_base(object), (object), name, sizeof(name) - 1, 1, &rv)
+#define GET_PROPERTY(object, id) \
+ zend_read_property_ex(i_get_exception_base(object), (object), CG(known_strings)[id], 0, &rv)
+#define GET_PROPERTY_SILENT(object, id) \
+ zend_read_property_ex(i_get_exception_base(object), (object), CG(known_strings)[id], 1, &rv)
/* {{{ proto string Exception|Error::getFile()
Get the file in which the exception occurred */
@@ -387,7 +401,7 @@ ZEND_METHOD(exception, getFile)
DEFAULT_0_PARAMS;
- ZVAL_COPY(return_value, GET_PROPERTY(getThis(), "file"));
+ ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_FILE));
}
/* }}} */
@@ -399,7 +413,7 @@ ZEND_METHOD(exception, getLine)
DEFAULT_0_PARAMS;
- ZVAL_COPY(return_value, GET_PROPERTY(getThis(), "line"));
+ ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_LINE));
}
/* }}} */
@@ -411,7 +425,7 @@ ZEND_METHOD(exception, getMessage)
DEFAULT_0_PARAMS;
- ZVAL_COPY(return_value, GET_PROPERTY(getThis(), "message"));
+ ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_MESSAGE));
}
/* }}} */
@@ -423,7 +437,7 @@ ZEND_METHOD(exception, getCode)
DEFAULT_0_PARAMS;
- ZVAL_COPY(return_value, GET_PROPERTY(getThis(), "code"));
+ ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_CODE));
}
/* }}} */
@@ -435,7 +449,7 @@ ZEND_METHOD(exception, getTrace)
DEFAULT_0_PARAMS;
- ZVAL_COPY(return_value, GET_PROPERTY(getThis(), "trace"));
+ ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_TRACE));
}
/* }}} */
@@ -447,23 +461,23 @@ ZEND_METHOD(error_exception, getSeverity)
DEFAULT_0_PARAMS;
- ZVAL_COPY(return_value, GET_PROPERTY(getThis(), "severity"));
+ ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_SEVERITY));
}
/* }}} */
#define TRACE_APPEND_KEY(key) do { \
- tmp = zend_hash_str_find(ht, key, sizeof(key)-1); \
+ tmp = zend_hash_find(ht, key); \
if (tmp) { \
if (Z_TYPE_P(tmp) != IS_STRING) { \
- zend_error(E_WARNING, "Value for %s is no string", key); \
+ zend_error(E_WARNING, "Value for %s is no string", \
+ ZSTR_VAL(key)); \
smart_str_appends(str, "[unknown]"); \
} else { \
- smart_str_appends(str, Z_STRVAL_P(tmp)); \
+ smart_str_appends(str, Z_STRVAL_P(tmp)); \
} \
} \
} while (0)
-
static void _build_trace_args(zval *arg, smart_str *str) /* {{{ */
{
/* the trivial way would be to do
@@ -530,14 +544,14 @@ static void _build_trace_string(smart_str *str, HashTable *ht, uint32_t num) /*
smart_str_append_long(str, num);
smart_str_appendc(str, ' ');
- file = zend_hash_str_find(ht, "file", sizeof("file")-1);
+ file = zend_hash_find(ht, CG(known_strings)[ZEND_STR_FILE]);
if (file) {
if (Z_TYPE_P(file) != IS_STRING) {
zend_error(E_WARNING, "Function name is no string");
smart_str_appends(str, "[unknown function]");
} else{
zend_long line;
- tmp = zend_hash_str_find(ht, "line", sizeof("line")-1);
+ tmp = zend_hash_find(ht, CG(known_strings)[ZEND_STR_LINE]);
if (tmp) {
if (Z_TYPE_P(tmp) == IS_LONG) {
line = Z_LVAL_P(tmp);
@@ -556,11 +570,11 @@ static void _build_trace_string(smart_str *str, HashTable *ht, uint32_t num) /*
} else {
smart_str_appends(str, "[internal function]: ");
}
- TRACE_APPEND_KEY("class");
- TRACE_APPEND_KEY("type");
- TRACE_APPEND_KEY("function");
+ TRACE_APPEND_KEY(CG(known_strings)[ZEND_STR_CLASS]);
+ TRACE_APPEND_KEY(CG(known_strings)[ZEND_STR_TYPE]);
+ TRACE_APPEND_KEY(CG(known_strings)[ZEND_STR_FUNCTION]);
smart_str_appendc(str, '(');
- tmp = zend_hash_str_find(ht, "args", sizeof("args")-1);
+ tmp = zend_hash_find(ht, CG(known_strings)[ZEND_STR_ARGS]);
if (tmp) {
if (Z_TYPE_P(tmp) == IS_ARRAY) {
size_t last_len = ZSTR_LEN(str->s);
@@ -597,7 +611,7 @@ ZEND_METHOD(exception, getTraceAsString)
object = getThis();
base_ce = i_get_exception_base(object);
- trace = zend_read_property(base_ce, object, "trace", sizeof("trace")-1, 1, &rv);
+ trace = zend_read_property_ex(base_ce, object, CG(known_strings)[ZEND_STR_TRACE], 1, &rv);
if (Z_TYPE_P(trace) != IS_ARRAY) {
RETURN_FALSE;
}
@@ -627,7 +641,7 @@ ZEND_METHOD(exception, getPrevious)
DEFAULT_0_PARAMS;
- ZVAL_COPY(return_value, GET_PROPERTY_SILENT(getThis(), "previous"));
+ ZVAL_COPY(return_value, GET_PROPERTY_SILENT(getThis(), ZEND_STR_PREVIOUS));
} /* }}} */
size_t zend_spprintf(char **message, size_t max_len, const char *format, ...) /* {{{ */
@@ -662,7 +676,7 @@ ZEND_METHOD(exception, __toString)
zend_class_entry *base_ce;
zend_string *str;
zend_fcall_info fci;
- zval rv;
+ zval rv, tmp;
zend_string *fname;
DEFAULT_0_PARAMS;
@@ -674,9 +688,9 @@ ZEND_METHOD(exception, __toString)
while (exception && Z_TYPE_P(exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception), zend_ce_throwable)) {
zend_string *prev_str = str;
- zend_string *message = zval_get_string(GET_PROPERTY(exception, "message"));
- zend_string *file = zval_get_string(GET_PROPERTY(exception, "file"));
- zend_long line = zval_get_long(GET_PROPERTY(exception, "line"));
+ zend_string *message = zval_get_string(GET_PROPERTY(exception, ZEND_STR_MESSAGE));
+ zend_string *file = zval_get_string(GET_PROPERTY(exception, ZEND_STR_FILE));
+ zend_long line = zval_get_long(GET_PROPERTY(exception, ZEND_STR_LINE));
fci.size = sizeof(fci);
ZVAL_STR(&fci.function_name, fname);
@@ -718,7 +732,7 @@ ZEND_METHOD(exception, __toString)
zend_string_release(file);
zval_ptr_dtor(&trace);
- exception = GET_PROPERTY(exception, "previous");
+ exception = GET_PROPERTY(exception, ZEND_STR_PREVIOUS);
}
zend_string_release(fname);
@@ -727,7 +741,8 @@ ZEND_METHOD(exception, __toString)
/* We store the result in the private property string so we can access
* the result in uncaught exception handlers without memleaks. */
- zend_update_property_str(base_ce, exception, "string", sizeof("string")-1, str);
+ ZVAL_STR(&tmp, str);
+ zend_update_property_ex(base_ce, exception, CG(known_strings)[ZEND_STR_STRING], &tmp);
RETURN_STR(str);
}
@@ -868,7 +883,7 @@ ZEND_API zend_class_entry *zend_get_error_exception(void)
ZEND_API ZEND_COLD zend_object *zend_throw_exception(zend_class_entry *exception_ce, const char *message, zend_long code) /* {{{ */
{
- zval ex;
+ zval ex, tmp;
if (exception_ce) {
if (!instanceof_function(exception_ce, zend_ce_throwable)) {
@@ -882,10 +897,13 @@ ZEND_API ZEND_COLD zend_object *zend_throw_exception(zend_class_entry *exception
if (message) {
- zend_update_property_string(exception_ce, &ex, "message", sizeof("message")-1, message);
+ ZVAL_STRING(&tmp, message);
+ zend_update_property_ex(exception_ce, &ex, CG(known_strings)[ZEND_STR_MESSAGE], &tmp);
+ zval_ptr_dtor(&tmp);
}
if (code) {
- zend_update_property_long(exception_ce, &ex, "code", sizeof("code")-1, code);
+ ZVAL_LONG(&tmp, code);
+ zend_update_property_ex(exception_ce, &ex, CG(known_strings)[ZEND_STR_CODE], &tmp);
}
zend_throw_exception_internal(&ex);
@@ -910,10 +928,11 @@ ZEND_API ZEND_COLD zend_object *zend_throw_exception_ex(zend_class_entry *except
ZEND_API ZEND_COLD zend_object *zend_throw_error_exception(zend_class_entry *exception_ce, const char *message, zend_long code, int severity) /* {{{ */
{
- zval ex;
+ zval ex, tmp;
zend_object *obj = zend_throw_exception(exception_ce, message, code);
ZVAL_OBJ(&ex, obj);
- zend_update_property_long(zend_ce_error_exception, &ex, "severity", sizeof("severity")-1, severity);
+ ZVAL_LONG(&tmp, severity);
+ zend_update_property_ex(zend_ce_error_exception, &ex, CG(known_strings)[ZEND_STR_SEVERITY], &tmp);
return obj;
}
/* }}} */
@@ -948,9 +967,9 @@ ZEND_API ZEND_COLD void zend_exception_error(zend_object *ex, int severity) /* {
ce_exception = Z_OBJCE(exception);
EG(exception) = NULL;
if (ce_exception == zend_ce_parse_error) {
- zend_string *message = zval_get_string(GET_PROPERTY(&exception, "message"));
- zend_string *file = zval_get_string(GET_PROPERTY_SILENT(&exception, "file"));
- zend_long line = zval_get_long(GET_PROPERTY_SILENT(&exception, "line"));
+ zend_string *message = zval_get_string(GET_PROPERTY(&exception, ZEND_STR_MESSAGE));
+ zend_string *file = zval_get_string(GET_PROPERTY_SILENT(&exception, ZEND_STR_FILE));
+ zend_long line = zval_get_long(GET_PROPERTY_SILENT(&exception, ZEND_STR_LINE));
zend_error_helper(E_PARSE, ZSTR_VAL(file), line, "%s", ZSTR_VAL(message));
@@ -966,7 +985,7 @@ ZEND_API ZEND_COLD void zend_exception_error(zend_object *ex, int severity) /* {
if (Z_TYPE(tmp) != IS_STRING) {
zend_error(E_WARNING, "%s::__toString() must return a string", ZSTR_VAL(ce_exception->name));
} else {
- zend_update_property(i_get_exception_base(&exception), &exception, "string", sizeof("string")-1, &tmp);
+ zend_update_property_ex(i_get_exception_base(&exception), &exception, CG(known_strings)[ZEND_STR_STRING], &tmp);
}
}
zval_ptr_dtor(&tmp);
@@ -977,8 +996,8 @@ ZEND_API ZEND_COLD void zend_exception_error(zend_object *ex, int severity) /* {
ZVAL_OBJ(&zv, EG(exception));
/* do the best we can to inform about the inner exception */
if (instanceof_function(ce_exception, zend_ce_exception) || instanceof_function(ce_exception, zend_ce_error)) {
- file = zval_get_string(GET_PROPERTY_SILENT(&zv, "file"));
- line = zval_get_long(GET_PROPERTY_SILENT(&zv, "line"));
+ file = zval_get_string(GET_PROPERTY_SILENT(&zv, ZEND_STR_FILE));
+ line = zval_get_long(GET_PROPERTY_SILENT(&zv, ZEND_STR_LINE));
}
zend_error_va(E_WARNING, (file && ZSTR_LEN(file) > 0) ? ZSTR_VAL(file) : NULL, line,
@@ -990,9 +1009,9 @@ ZEND_API ZEND_COLD void zend_exception_error(zend_object *ex, int severity) /* {
}
}
- str = zval_get_string(GET_PROPERTY_SILENT(&exception, "string"));
- file = zval_get_string(GET_PROPERTY_SILENT(&exception, "file"));
- line = zval_get_long(GET_PROPERTY_SILENT(&exception, "line"));
+ str = zval_get_string(GET_PROPERTY_SILENT(&exception, ZEND_STR_STRING));
+ file = zval_get_string(GET_PROPERTY_SILENT(&exception, ZEND_STR_FILE));
+ line = zval_get_long(GET_PROPERTY_SILENT(&exception, ZEND_STR_LINE));
zend_error_va(severity, (file && ZSTR_LEN(file) > 0) ? ZSTR_VAL(file) : NULL, line,
"Uncaught %s\n thrown", ZSTR_VAL(str));
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index bb27463c6c..0bc21e57ac 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -2227,7 +2227,7 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu
if (UNEXPECTED(op_array->this_var != (uint32_t)-1) && EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) {
GC_REFCOUNT(Z_OBJ(EX(This)))++;
- if (!zend_hash_str_add(EX(symbol_table), "this", sizeof("this")-1, &EX(This))) {
+ if (!zend_hash_add(EX(symbol_table), CG(known_strings)[ZEND_STR_THIS], &EX(This))) {
GC_REFCOUNT(Z_OBJ(EX(This)))--;
}
}
@@ -2256,7 +2256,7 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da
if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) {
if (UNEXPECTED(op_array->this_var != (uint32_t)-1) && EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) {
GC_REFCOUNT(Z_OBJ(EX(This)))++;
- if (!zend_hash_str_add(EX(symbol_table), "this", sizeof("this")-1, &EX(This))) {
+ if (!zend_hash_add(EX(symbol_table), CG(known_strings)[ZEND_STR_THIS], &EX(This))) {
GC_REFCOUNT(Z_OBJ(EX(This)))--;
}
}
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index d4e2d8527e..b98e83be52 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -956,7 +956,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k
}
if (!EG(autoload_func)) {
- zend_function *func = zend_hash_str_find_ptr(EG(function_table), ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1);
+ zend_function *func = zend_hash_find_ptr(EG(function_table), CG(known_strings)[ZEND_STR_MAGIC_AUTOLOAD]);
if (func) {
EG(autoload_func) = func;
} else {
diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h
index 14f47554d1..59ba3477a2 100644
--- a/Zend/zend_globals.h
+++ b/Zend/zend_globals.h
@@ -113,6 +113,8 @@ struct _zend_compiler_globals {
zend_string *empty_string;
zend_string *one_char_string[256];
+ zend_string **known_strings;
+ uint32_t known_strings_count;
HashTable interned_strings;
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index 4722846ce7..fb2f67adbe 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -1019,7 +1019,7 @@ function_call:
class_name:
T_STATIC
- { zval zv; ZVAL_STRINGL(&zv, "static", sizeof("static")-1);
+ { zval zv; ZVAL_INTERNED_STR(&zv, CG(known_strings)[ZEND_STR_STATIC]);
$$ = zend_ast_create_zval_ex(&zv, ZEND_NAME_NOT_FQ); }
| name { $$ = $1; }
;
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 80ffc3595f..47fc542dbc 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -1712,7 +1712,7 @@ int zend_std_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function **f
ce = Z_OBJCE_P(obj);
- if ((func = zend_hash_str_find(&ce->function_table, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1)) == NULL) {
+ if ((func = zend_hash_find(&ce->function_table, CG(known_strings)[ZEND_STR_MAGIC_INVOKE])) == NULL) {
return FAILURE;
}
*fptr_ptr = Z_FUNC_P(func);
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index e24d033da3..f47a148564 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -677,7 +677,7 @@ try_again:
zval tmp;
ZVAL_COPY_VALUE(&tmp, op);
object_init(op);
- zend_hash_str_add_new(Z_OBJPROP_P(op), "scalar", sizeof("scalar")-1, &tmp);
+ zend_hash_add_new(Z_OBJPROP_P(op), CG(known_strings)[ZEND_STR_SCALAR], &tmp);
break;
}
}
diff --git a/Zend/zend_string.c b/Zend/zend_string.c
index 03d77e1293..4866b64949 100644
--- a/Zend/zend_string.c
+++ b/Zend/zend_string.c
@@ -42,6 +42,32 @@ static void _str_dtor(zval *zv)
}
#endif
+ZEND_API uint32_t zend_intern_known_strings(const char **strings, uint32_t count)
+{
+ uint32_t i, old_count = CG(known_strings_count);
+
+ CG(known_strings) = perealloc(CG(known_strings), sizeof(char*) * (old_count + count), 1);
+ for (i = 0; i < count; i++) {
+#ifndef ZTS
+ zend_string *str = zend_string_init(strings[i], strlen(strings[i]), 1);
+ CG(known_strings)[CG(known_strings_count) + i] =
+ zend_new_interned_string_int(str);
+#else
+ CG(known_strings)[CG(known_strings_count) + i] =
+ zend_zts_interned_string_init(strings[i], strlen(strings[i]));
+#endif
+ }
+ CG(known_strings_count) = old_count + count;
+ return old_count;
+}
+
+static const char *known_strings[] = {
+#define _ZEND_STR_DSC(id, str) str,
+ZEND_KNOWN_STRINGS(_ZEND_STR_DSC)
+#undef _ZEND_STR_DSC
+ NULL
+};
+
void zend_interned_strings_init(void)
{
#ifndef ZTS
@@ -63,6 +89,11 @@ void zend_interned_strings_init(void)
/* 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)));
+ /* known strings */
+ CG(known_strings) = NULL;
+ CG(known_strings_count) = 0;
+ zend_intern_known_strings(known_strings, (sizeof(known_strings) / sizeof(known_strings[0])) - 1);
+
zend_new_interned_string = zend_new_interned_string_int;
zend_interned_strings_snapshot = zend_interned_strings_snapshot_int;
zend_interned_strings_restore = zend_interned_strings_restore_int;
@@ -72,7 +103,16 @@ void zend_interned_strings_dtor(void)
{
#ifndef ZTS
zend_hash_destroy(&CG(interned_strings));
+#else
+ uint32_t i;
+
+ for (i = 0; i < CG(known_strings_count); i++) {
+ zend_zts_interned_string_free(&CG(known_strings)[i]);
+ }
#endif
+ free(CG(known_strings));
+ CG(known_strings) = NULL;
+ CG(known_strings_count) = 0;
}
static zend_string *zend_new_interned_string_int(zend_string *str)
diff --git a/Zend/zend_string.h b/Zend/zend_string.h
index 28aebb0ffc..05bf4ef7b8 100644
--- a/Zend/zend_string.h
+++ b/Zend/zend_string.h
@@ -358,29 +358,67 @@ EMPTY_SWITCH_DEFAULT_CASE()
#endif
}
-static zend_always_inline void zend_interned_empty_string_init(zend_string **s)
+#ifdef ZTS
+static zend_always_inline zend_string* zend_zts_interned_string_init(const char *val, size_t len)
{
zend_string *str;
- str = zend_string_alloc(sizeof("")-1, 1);
- ZSTR_VAL(str)[0] = '\000';
+ str = zend_string_init(val, len, 1);
-#ifndef ZTS
- *s = zend_new_interned_string(str);
-#else
zend_string_hash_val(str);
GC_FLAGS(str) |= IS_STR_INTERNED;
- *s = str;
-#endif
+ return str;
}
-static zend_always_inline void zend_interned_empty_string_free(zend_string **s)
+static zend_always_inline void zend_zts_interned_string_free(zend_string **s)
{
if (NULL != *s) {
free(*s);
*s = NULL;
}
}
+#endif
+
+#define ZEND_KNOWN_STRINGS(_) \
+ _(ZEND_STR_FILE, "file") \
+ _(ZEND_STR_LINE, "line") \
+ _(ZEND_STR_FUNCTION, "function") \
+ _(ZEND_STR_CLASS, "class") \
+ _(ZEND_STR_OBJECT, "object") \
+ _(ZEND_STR_TYPE, "type") \
+ _(ZEND_STR_OBJECT_OPERATOR, "->") \
+ _(ZEND_STR_PAAMAYIM_NEKUDOTAYIM, "::") \
+ _(ZEND_STR_ARGS, "args") \
+ _(ZEND_STR_UNKNOWN, "unknown") \
+ _(ZEND_STR_EVAL, "eval") \
+ _(ZEND_STR_INCLUDE, "include") \
+ _(ZEND_STR_REQUIRE, "require") \
+ _(ZEND_STR_INCLUDE_ONCE, "include_once") \
+ _(ZEND_STR_REQUIRE_ONCE, "require_once") \
+ _(ZEND_STR_SCALAR, "scalar") \
+ _(ZEND_STR_ERROR_REPORTING, "error_reporting") \
+ _(ZEND_STR_STATIC, "static") \
+ _(ZEND_STR_THIS, "this") \
+ _(ZEND_STR_VALUE, "value") \
+ _(ZEND_STR_KEY, "key") \
+ _(ZEND_STR_MAGIC_AUTOLOAD, "__autoload") \
+ _(ZEND_STR_MAGIC_INVOKE, "__invoke") \
+ _(ZEND_STR_PREVIOUS, "previous") \
+ _(ZEND_STR_CODE, "code") \
+ _(ZEND_STR_MESSAGE, "message") \
+ _(ZEND_STR_SEVERITY, "severity") \
+ _(ZEND_STR_STRING, "string") \
+ _(ZEND_STR_TRACE, "trace") \
+
+
+typedef enum _zend_known_string_id {
+#define _ZEND_STR_ID(id, str) id,
+ZEND_KNOWN_STRINGS(_ZEND_STR_ID)
+#undef _ZEND_STR_ID
+ ZEND_STR_LAST_KNOWN
+} zend_known_string_id;
+
+ZEND_API uint32_t zend_intern_known_strings(const char **strings, uint32_t count);
#endif /* ZEND_STRING_H */
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 36a041915d..a7c37ed09b 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -5298,7 +5298,7 @@ ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE)
if (Z_TYPE_P(expr) != IS_ARRAY) {
object_init(result);
if (Z_TYPE_P(expr) != IS_NULL) {
- expr = zend_hash_str_add_new(Z_OBJPROP_P(result), "scalar", sizeof("scalar")-1, expr);
+ expr = zend_hash_add_new(Z_OBJPROP_P(result), CG(known_strings)[ZEND_STR_SCALAR], expr);
if (OP1_TYPE == IS_CONST) {
if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) {
zval_copy_ctor_func(expr);
@@ -6636,7 +6636,7 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
do {
EG(error_reporting) = 0;
if (!EG(error_reporting_ini_entry)) {
- zend_ini_entry *p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1);
+ zend_ini_entry *p = zend_hash_find_ptr(EG(ini_directives), CG(known_strings)[ZEND_STR_ERROR_REPORTING]);
if (p) {
EG(error_reporting_ini_entry) = p;
} else {
@@ -6648,7 +6648,7 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
ALLOC_HASHTABLE(EG(modified_ini_directives));
zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
}
- if (EXPECTED(zend_hash_str_add_ptr(EG(modified_ini_directives), "error_reporting", sizeof("error_reporting")-1, EG(error_reporting_ini_entry)) != NULL)) {
+ if (EXPECTED(zend_hash_add_ptr(EG(modified_ini_directives), CG(known_strings)[ZEND_STR_ERROR_REPORTING], EG(error_reporting_ini_entry)) != NULL)) {
EG(error_reporting_ini_entry)->orig_value = EG(error_reporting_ini_entry)->value;
EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable;
EG(error_reporting_ini_entry)->modified = 1;
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index f9b8f6b7f1..c9274bd64f 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -1505,7 +1505,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEN
do {
EG(error_reporting) = 0;
if (!EG(error_reporting_ini_entry)) {
- zend_ini_entry *p = zend_hash_str_find_ptr(EG(ini_directives), "error_reporting", sizeof("error_reporting")-1);
+ zend_ini_entry *p = zend_hash_find_ptr(EG(ini_directives), CG(known_strings)[ZEND_STR_ERROR_REPORTING]);
if (p) {
EG(error_reporting_ini_entry) = p;
} else {
@@ -1517,7 +1517,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEN
ALLOC_HASHTABLE(EG(modified_ini_directives));
zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
}
- if (EXPECTED(zend_hash_str_add_ptr(EG(modified_ini_directives), "error_reporting", sizeof("error_reporting")-1, EG(error_reporting_ini_entry)) != NULL)) {
+ if (EXPECTED(zend_hash_add_ptr(EG(modified_ini_directives), CG(known_strings)[ZEND_STR_ERROR_REPORTING], EG(error_reporting_ini_entry)) != NULL)) {
EG(error_reporting_ini_entry)->orig_value = EG(error_reporting_ini_entry)->value;
EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable;
EG(error_reporting_ini_entry)->modified = 1;
@@ -3327,7 +3327,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_HANDLER(ZEND_O
if (Z_TYPE_P(expr) != IS_ARRAY) {
object_init(result);
if (Z_TYPE_P(expr) != IS_NULL) {
- expr = zend_hash_str_add_new(Z_OBJPROP_P(result), "scalar", sizeof("scalar")-1, expr);
+ expr = zend_hash_add_new(Z_OBJPROP_P(result), CG(known_strings)[ZEND_STR_SCALAR], expr);
if (IS_CONST == IS_CONST) {
if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) {
zval_copy_ctor_func(expr);
@@ -12265,7 +12265,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPC
if (Z_TYPE_P(expr) != IS_ARRAY) {
object_init(result);
if (Z_TYPE_P(expr) != IS_NULL) {
- expr = zend_hash_str_add_new(Z_OBJPROP_P(result), "scalar", sizeof("scalar")-1, expr);
+ expr = zend_hash_add_new(Z_OBJPROP_P(result), CG(known_strings)[ZEND_STR_SCALAR], expr);
if (IS_TMP_VAR == IS_CONST) {
if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) {
zval_copy_ctor_func(expr);
@@ -15775,7 +15775,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPC
if (Z_TYPE_P(expr) != IS_ARRAY) {
object_init(result);
if (Z_TYPE_P(expr) != IS_NULL) {
- expr = zend_hash_str_add_new(Z_OBJPROP_P(result), "scalar", sizeof("scalar")-1, expr);
+ expr = zend_hash_add_new(Z_OBJPROP_P(result), CG(known_strings)[ZEND_STR_SCALAR], expr);
if (IS_VAR == IS_CONST) {
if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) {
zval_copy_ctor_func(expr);
@@ -35420,7 +35420,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCO
if (Z_TYPE_P(expr) != IS_ARRAY) {
object_init(result);
if (Z_TYPE_P(expr) != IS_NULL) {
- expr = zend_hash_str_add_new(Z_OBJPROP_P(result), "scalar", sizeof("scalar")-1, expr);
+ expr = zend_hash_add_new(Z_OBJPROP_P(result), CG(known_strings)[ZEND_STR_SCALAR], expr);
if (IS_CV == IS_CONST) {
if (UNEXPECTED(Z_OPT_COPYABLE_P(expr))) {
zval_copy_ctor_func(expr);
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index 9dd13f0576..0c9ea47283 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -523,6 +523,9 @@ static void accel_use_shm_interned_strings(void)
s[1] = 0;
CG(one_char_string)[j] = accel_new_interned_string(zend_string_init(s, 1, 0));
}
+ for (j = 0; j < CG(known_strings_count); j++) {
+ CG(known_strings)[j] = accel_new_interned_string(CG(known_strings)[j]);
+ }
/* function table hash keys */
for (idx = 0; idx < CG(function_table)->nNumUsed; idx++) {