Skip to content

Commit

Permalink
Allocate only necessary space for static properties of internal class…
Browse files Browse the repository at this point in the history
…es in ZTS mode.
  • Loading branch information
dstogov committed Oct 1, 2018
1 parent 250b577 commit a2e8334
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 19 deletions.
14 changes: 12 additions & 2 deletions Zend/zend.c
Expand Up @@ -41,6 +41,7 @@ static HashTable *global_class_table = NULL;
static HashTable *global_constants_table = NULL;
static HashTable *global_auto_globals_table = NULL;
static HashTable *global_persistent_list = NULL;
static zend_uintptr_t global_last_static_member = 0;
ZEND_TSRMLS_CACHE_DEFINE()
# define GLOBAL_FUNCTION_TABLE global_function_table
# define GLOBAL_CLASS_TABLE global_class_table
Expand Down Expand Up @@ -630,9 +631,9 @@ static void compiler_globals_ctor(zend_compiler_globals *compiler_globals) /* {{
zend_hash_init_ex(compiler_globals->auto_globals, 8, NULL, auto_global_dtor, 1, 0);
zend_hash_copy(compiler_globals->auto_globals, global_auto_globals_table, auto_global_copy_ctor);

compiler_globals->last_static_member = zend_hash_num_elements(compiler_globals->class_table);
compiler_globals->last_static_member = global_last_static_member;
if (compiler_globals->last_static_member) {
compiler_globals->static_members_table = calloc(compiler_globals->last_static_member, sizeof(zval*));
compiler_globals->static_members_table = calloc(compiler_globals->last_static_member + 1, sizeof(zval*));
} else {
compiler_globals->static_members_table = NULL;
}
Expand Down Expand Up @@ -935,6 +936,7 @@ int zend_post_startup(void) /* {{{ */
*GLOBAL_FUNCTION_TABLE = *compiler_globals->function_table;
*GLOBAL_CLASS_TABLE = *compiler_globals->class_table;
*GLOBAL_CONSTANTS_TABLE = *executor_globals->zend_constants;
global_last_static_member = compiler_globals->last_static_member;

short_tags_default = CG(short_tags);
compiler_options_default = CG(compiler_options);
Expand Down Expand Up @@ -1083,6 +1085,14 @@ ZEND_API void zend_activate(void) /* {{{ */
}
/* }}} */

#ifdef ZTS
void zend_reset_internal_classes(void) /* {{{ */
{
CG(last_static_member) = global_last_static_member;
}
/* }}} */
#endif

void zend_call_destructors(void) /* {{{ */
{
zend_try {
Expand Down
7 changes: 6 additions & 1 deletion Zend/zend.h
Expand Up @@ -127,7 +127,10 @@ struct _zend_class_entry {
int default_static_members_count;
zval *default_properties_table;
zval *default_static_members_table;
zval *static_members_table;
union {
zval *static_members_table;
zend_uintptr_t static_members_table_idx;
};
HashTable function_table;
HashTable properties_info;
HashTable constants_table;
Expand Down Expand Up @@ -268,6 +271,8 @@ ZEND_API void zend_activate_modules(void);
ZEND_API void zend_deactivate_modules(void);
ZEND_API void zend_post_deactivate_modules(void);

void zend_reset_internal_classes(void);

ZEND_API void free_estring(char **str_p);
END_EXTERN_C()

Expand Down
10 changes: 10 additions & 0 deletions Zend/zend_API.c
Expand Up @@ -3698,6 +3698,16 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z
ZVAL_COPY_VALUE(&ce->default_static_members_table[property_info->offset], property);
if (ce->type == ZEND_USER_CLASS) {
ce->static_members_table = ce->default_static_members_table;
#ifdef ZTS
} else if (!ce->static_members_table_idx) {
CG(last_static_member)++;
ce->static_members_table_idx = CG(last_static_member);
if (CG(static_members_table)) {
/* Support for run-time declaration: dl() */
CG(static_members_table) = realloc(CG(static_members_table), (CG(last_static_member) + 1) * sizeof(zval*));
CG(static_members_table)[ce->static_members_table_idx] = NULL;
}
#endif
}
} else {
if ((property_info_ptr = zend_hash_find_ptr(&ce->properties_info, name)) != NULL &&
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_API.h
Expand Up @@ -229,7 +229,7 @@ typedef struct _zend_fcall_info_cache {
INIT_CLASS_ENTRY(class_container, ZEND_NS_NAME(ns, class_name), functions)

#ifdef ZTS
# define CE_STATIC_MEMBERS(ce) (((ce)->type==ZEND_USER_CLASS)?(ce)->static_members_table:CG(static_members_table)[(zend_intptr_t)(ce)->static_members_table])
# define CE_STATIC_MEMBERS(ce) (((ce)->type==ZEND_USER_CLASS)?(ce)->static_members_table:CG(static_members_table)[(ce)->static_members_table_idx])
#else
# define CE_STATIC_MEMBERS(ce) ((ce)->static_members_table)
#endif
Expand Down
12 changes: 0 additions & 12 deletions Zend/zend_compile.c
Expand Up @@ -1615,19 +1615,7 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify
zend_hash_init_ex(&ce->function_table, 8, NULL, ZEND_FUNCTION_DTOR, persistent_hashes, 0);

if (ce->type == ZEND_INTERNAL_CLASS) {
#ifdef ZTS
int n = zend_hash_num_elements(CG(class_table));

if (CG(static_members_table) && n >= CG(last_static_member)) {
/* Support for run-time declaration: dl() */
CG(last_static_member) = n+1;
CG(static_members_table) = realloc(CG(static_members_table), (n+1)*sizeof(zval*));
CG(static_members_table)[n] = NULL;
}
ce->static_members_table = (zval*)(zend_intptr_t)n;
#else
ce->static_members_table = NULL;
#endif
} else {
ce->static_members_table = ce->default_static_members_table;
ce->info.user.doc_comment = NULL;
Expand Down
3 changes: 3 additions & 0 deletions Zend/zend_execute_API.c
Expand Up @@ -318,6 +318,9 @@ void shutdown_executor(void) /* {{{ */
zend_hash_reverse_apply(EG(zend_constants), clean_non_persistent_constant_full);
zend_hash_reverse_apply(EG(function_table), clean_non_persistent_function_full);
zend_hash_reverse_apply(EG(class_table), clean_non_persistent_class_full);
#ifdef ZTS
zend_reset_internal_classes();
#endif
} else {
ZEND_HASH_REVERSE_FOREACH_STR_KEY_VAL(EG(zend_constants), key, zv) {
zend_constant *c = Z_PTR_P(zv);
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_globals.h
Expand Up @@ -119,7 +119,7 @@ struct _zend_compiler_globals {

#ifdef ZTS
zval **static_members_table;
int last_static_member;
zend_uintptr_t last_static_member;
#endif
};

Expand Down
10 changes: 10 additions & 0 deletions Zend/zend_inheritance.c
Expand Up @@ -928,6 +928,16 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
ce->default_static_members_count += parent_ce->default_static_members_count;
if (ce->type == ZEND_USER_CLASS) {
ce->static_members_table = ce->default_static_members_table;
#ifdef ZTS
} else if (!ce->static_members_table_idx) {
CG(last_static_member)++;
ce->static_members_table_idx = CG(last_static_member);
if (CG(static_members_table)) {
/* Support for run-time declaration: dl() */
CG(static_members_table) = realloc(CG(static_members_table), (CG(last_static_member) + 1) * sizeof(zval*));
CG(static_members_table)[ce->static_members_table_idx] = NULL;
}
#endif
}
}

Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_object_handlers.c
Expand Up @@ -1355,7 +1355,7 @@ static void zend_intenal_class_init_statics(zend_class_entry *class_type) /* {{{
}

#if ZTS
CG(static_members_table)[(zend_intptr_t)(class_type->static_members_table)] = emalloc(sizeof(zval) * class_type->default_static_members_count);
CG(static_members_table)[class_type->static_members_table_idx] = emalloc(sizeof(zval) * class_type->default_static_members_count);
#else
class_type->static_members_table = emalloc(sizeof(zval) * class_type->default_static_members_count);
#endif
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_opcode.c
Expand Up @@ -146,7 +146,7 @@ ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce)
zval *end = p + ce->default_static_members_count;

#ifdef ZTS
CG(static_members_table)[(zend_intptr_t)(ce->static_members_table)] = NULL;
CG(static_members_table)[ce->static_members_table_idx] = NULL;
#else
ce->static_members_table = NULL;
#endif
Expand Down

0 comments on commit a2e8334

Please sign in to comment.