summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2018-10-01 19:05:31 +0300
committerDmitry Stogov <dmitry@zend.com>2018-10-01 19:05:31 +0300
commita2e83346134c7a197492cb520ad440e0e1aff463 (patch)
tree82e98f145137a2877254fbe1836bf9753accf37e
parent250b577258ba9a736a15527f211ba52c9368d322 (diff)
downloadphp-git-a2e83346134c7a197492cb520ad440e0e1aff463.tar.gz
Allocate only necessary space for static properties of internal classes in ZTS mode.
-rw-r--r--Zend/zend.c14
-rw-r--r--Zend/zend.h7
-rw-r--r--Zend/zend_API.c10
-rw-r--r--Zend/zend_API.h2
-rw-r--r--Zend/zend_compile.c12
-rw-r--r--Zend/zend_execute_API.c3
-rw-r--r--Zend/zend_globals.h2
-rw-r--r--Zend/zend_inheritance.c10
-rw-r--r--Zend/zend_object_handlers.c2
-rw-r--r--Zend/zend_opcode.c2
10 files changed, 45 insertions, 19 deletions
diff --git a/Zend/zend.c b/Zend/zend.c
index fe7ea7af22..cbbe08858d 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -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
@@ -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;
}
@@ -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);
@@ -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 {
diff --git a/Zend/zend.h b/Zend/zend.h
index 5ab9fdb532..d6d427ccdb 100644
--- a/Zend/zend.h
+++ b/Zend/zend.h
@@ -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;
@@ -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()
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 8c6113c0e1..81a4ee7698 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -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 &&
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index 718f5a7a80..54344fe0aa 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -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
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 504dd536ca..b96c6c79aa 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -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;
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index 8d1c056c63..2ade3e3818 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -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);
diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h
index 3c92a8f7f6..9412801c1b 100644
--- a/Zend/zend_globals.h
+++ b/Zend/zend_globals.h
@@ -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
};
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index bb18fbc9fe..816d67e851 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -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
}
}
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 8703cc44dc..f56913cbe8 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -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
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index 64a49b57f1..58d23e6773 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -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