Skip to content

Commit

Permalink
Intern some known (and offten used) strings.
Browse files Browse the repository at this point in the history
  • Loading branch information
dstogov committed May 12, 2016
1 parent 0039044 commit 7b94b95
Show file tree
Hide file tree
Showing 18 changed files with 262 additions and 139 deletions.
4 changes: 2 additions & 2 deletions Zend/zend.c
Expand Up @@ -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));
}
Expand Down Expand Up @@ -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);
}
/* }}} */

Expand Down
17 changes: 14 additions & 3 deletions Zend/zend_API.c
Expand Up @@ -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);
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions Zend/zend_API.h
Expand Up @@ -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);
Expand Down
75 changes: 42 additions & 33 deletions Zend/zend_builtin_functions.c
Expand Up @@ -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) {
Expand All @@ -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);
}
/* }}} */
Expand Down Expand Up @@ -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 {
Expand All @@ -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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -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;
}
Expand All @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions Zend/zend_closures.c
Expand Up @@ -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;
}
/* }}} */
Expand Down Expand Up @@ -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 &&
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_compile.c
Expand Up @@ -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);
}
}
Expand Down

0 comments on commit 7b94b95

Please sign in to comment.