diff options
author | Dmitry Stogov <dmitry@zend.com> | 2016-05-12 13:47:22 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2016-05-12 13:47:22 +0300 |
commit | 7b94b958ccbc87595d688d178f96daf96a9f54b3 (patch) | |
tree | f74f2fdf78a194c86fa7d34f27e0cf8f1e2d8ec0 | |
parent | 00390449c6c5d3cb65e129cb558b9e523e17090f (diff) | |
download | php-git-7b94b958ccbc87595d688d178f96daf96a9f54b3.tar.gz |
Intern some known (and offten used) strings.
-rw-r--r-- | Zend/zend.c | 4 | ||||
-rw-r--r-- | Zend/zend_API.c | 17 | ||||
-rw-r--r-- | Zend/zend_API.h | 1 | ||||
-rw-r--r-- | Zend/zend_builtin_functions.c | 75 | ||||
-rw-r--r-- | Zend/zend_closures.c | 6 | ||||
-rw-r--r-- | Zend/zend_compile.c | 2 | ||||
-rw-r--r-- | Zend/zend_exceptions.c | 165 | ||||
-rw-r--r-- | Zend/zend_execute.c | 4 | ||||
-rw-r--r-- | Zend/zend_execute_API.c | 2 | ||||
-rw-r--r-- | Zend/zend_globals.h | 2 | ||||
-rw-r--r-- | Zend/zend_language_parser.y | 2 | ||||
-rw-r--r-- | Zend/zend_object_handlers.c | 2 | ||||
-rw-r--r-- | Zend/zend_operators.c | 2 | ||||
-rw-r--r-- | Zend/zend_string.c | 40 | ||||
-rw-r--r-- | Zend/zend_string.h | 56 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 6 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 12 | ||||
-rw-r--r-- | ext/opcache/ZendAccelerator.c | 3 |
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++) { |