summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend.c25
-rw-r--r--Zend/zend_compile.h4
-rw-r--r--Zend/zend_constants.c24
-rw-r--r--Zend/zend_constants.h1
-rw-r--r--Zend/zend_execute_API.c206
-rw-r--r--Zend/zend_hash.h36
-rw-r--r--Zend/zend_objects_API.c43
-rw-r--r--Zend/zend_objects_API.h2
-rw-r--r--Zend/zend_opcode.c45
9 files changed, 158 insertions, 228 deletions
diff --git a/Zend/zend.c b/Zend/zend.c
index d51bd277a6..a5434c2e5e 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -903,31 +903,6 @@ void zend_post_startup(void) /* {{{ */
void zend_shutdown(void) /* {{{ */
{
zend_destroy_rsrc_list(&EG(persistent_list));
- if (EG(active))
- {
- /*
- * The order of destruction is important here.
- * See bugs #65463 and 66036.
- */
- zend_function *func;
- zend_class_entry *ce;
-
- ZEND_HASH_REVERSE_FOREACH_PTR(GLOBAL_FUNCTION_TABLE, func) {
- if (func->type == ZEND_USER_FUNCTION) {
- zend_cleanup_op_array_data((zend_op_array *) func);
- }
- } ZEND_HASH_FOREACH_END();
- ZEND_HASH_REVERSE_FOREACH_PTR(GLOBAL_CLASS_TABLE, ce) {
- if (ce->type == ZEND_USER_CLASS) {
- zend_cleanup_user_class_data(ce);
- } else {
- break;
- }
- } ZEND_HASH_FOREACH_END();
- zend_cleanup_internal_classes();
- zend_hash_reverse_apply(GLOBAL_FUNCTION_TABLE, (apply_func_t) clean_non_persistent_function_full);
- zend_hash_reverse_apply(GLOBAL_CLASS_TABLE, (apply_func_t) clean_non_persistent_class_full);
- }
zend_destroy_modules();
virtual_cwd_deactivate();
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 4264232bc4..99f8e37240 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -779,12 +779,8 @@ ZEND_API int open_file_for_scanning(zend_file_handle *file_handle);
ZEND_API void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_size);
ZEND_API void destroy_op_array(zend_op_array *op_array);
ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle);
-ZEND_API void zend_cleanup_user_class_data(zend_class_entry *ce);
ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce);
ZEND_API void zend_cleanup_internal_classes(void);
-ZEND_API void zend_cleanup_op_array_data(zend_op_array *op_array);
-ZEND_API int clean_non_persistent_function_full(zval *zv);
-ZEND_API int clean_non_persistent_class_full(zval *zv);
ZEND_API void destroy_zend_function(zend_function *function);
ZEND_API void zend_function_dtor(zval *zv);
diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c
index 77124fcf12..4d128c4843 100644
--- a/Zend/zend_constants.c
+++ b/Zend/zend_constants.c
@@ -69,20 +69,6 @@ void zend_copy_constants(HashTable *target, HashTable *source)
}
-static int clean_non_persistent_constant(zval *zv)
-{
- zend_constant *c = Z_PTR_P(zv);
- return (c->flags & CONST_PERSISTENT) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE;
-}
-
-
-static int clean_non_persistent_constant_full(zval *zv)
-{
- zend_constant *c = Z_PTR_P(zv);
- return (c->flags & CONST_PERSISTENT) ? 0 : 1;
-}
-
-
static int clean_module_constant(zval *el, void *arg)
{
zend_constant *c = (zend_constant *)Z_PTR_P(el);
@@ -152,16 +138,6 @@ int zend_shutdown_constants(void)
return SUCCESS;
}
-
-void clean_non_persistent_constants(void)
-{
- if (EG(full_tables_cleanup)) {
- zend_hash_apply(EG(zend_constants), clean_non_persistent_constant_full);
- } else {
- zend_hash_reverse_apply(EG(zend_constants), clean_non_persistent_constant);
- }
-}
-
ZEND_API void zend_register_null_constant(const char *name, size_t name_len, int flags, int module_number)
{
zend_constant c;
diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h
index 531ef665d8..3622cc45b8 100644
--- a/Zend/zend_constants.h
+++ b/Zend/zend_constants.h
@@ -64,7 +64,6 @@ void free_zend_constant(zval *zv);
int zend_startup_constants(void);
int zend_shutdown_constants(void);
void zend_register_standard_constants(void);
-void clean_non_persistent_constants(void);
ZEND_API int zend_verify_const_access(zend_class_constant *c, zend_class_entry *ce);
ZEND_API zval *zend_get_constant(zend_string *name);
ZEND_API zval *zend_get_constant_str(const char *name, size_t name_len);
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index ef29546ac0..3c453e64ef 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -100,28 +100,21 @@ static void zend_extension_deactivator(zend_extension *extension) /* {{{ */
}
/* }}} */
-static int clean_non_persistent_function(zval *zv) /* {{{ */
+static int clean_non_persistent_constant_full(zval *zv) /* {{{ */
{
- zend_function *function = Z_PTR_P(zv);
- return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE;
+ zend_constant *c = Z_PTR_P(zv);
+ return (c->flags & CONST_PERSISTENT) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
}
/* }}} */
-ZEND_API int clean_non_persistent_function_full(zval *zv) /* {{{ */
+static int clean_non_persistent_function_full(zval *zv) /* {{{ */
{
zend_function *function = Z_PTR_P(zv);
return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
}
/* }}} */
-static int clean_non_persistent_class(zval *zv) /* {{{ */
-{
- zend_class_entry *ce = Z_PTR_P(zv);
- return (ce->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE;
-}
-/* }}} */
-
-ZEND_API int clean_non_persistent_class_full(zval *zv) /* {{{ */
+static int clean_non_persistent_class_full(zval *zv) /* {{{ */
{
zend_class_entry *ce = Z_PTR_P(zv);
return (ce->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
@@ -253,123 +246,117 @@ void shutdown_destructors(void) /* {{{ */
void shutdown_executor(void) /* {{{ */
{
- zend_function *func;
- zend_class_entry *ce;
+ zend_string *key;
+ zval *zv;
+#if ZEND_DEBUG
+ zend_bool fast_shutdown = 0;
+#else
+ zend_bool fast_shutdown = is_zend_mm() && !EG(full_tables_cleanup);
+#endif
zend_try {
+ zend_llist_destroy(&CG(open_files));
+ } zend_end_try();
-/* Removed because this can not be safely done, e.g. in this situation:
- Object 1 creates object 2
- Object 3 holds reference to object 2.
- Now when 1 and 2 are destroyed, 3 can still access 2 in its destructor, with
- very problematic results */
-/* zend_objects_store_call_destructors(&EG(objects_store)); */
+ zend_try {
+ zend_close_rsrc_list(&EG(regular_list));
+ } zend_end_try();
-/* Moved after symbol table cleaners, because some of the cleaners can call
- destructors, which would use EG(symtable_cache_ptr) and thus leave leaks */
-/* while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
- zend_hash_destroy(*EG(symtable_cache_ptr));
- efree(*EG(symtable_cache_ptr));
- EG(symtable_cache_ptr)--;
- }
-*/
- zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator);
+ zend_objects_store_free_object_storage(&EG(objects_store), fast_shutdown);
- zend_hash_graceful_reverse_destroy(&EG(symbol_table));
+ /* All resources and objects are destroyed. */
+ /* No PHP callback functions may be called after this point. */
+
+ zend_try {
+ zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator);
} zend_end_try();
+
EG(valid_symbol_table) = 0;
- zend_try {
- zval *zeh;
+ if (fast_shutdown) {
+ /* Fast Request Shutdown
+ * =====================
+ * Zend Memory Manager frees memory by its own. We don't have to free
+ * each allocated block separately.
+ */
+ ZEND_HASH_REVERSE_FOREACH_VAL(EG(zend_constants), zv) {
+ zend_constant *c = Z_PTR_P(zv);
+ if (c->flags & CONST_PERSISTENT) {
+ break;
+ }
+ } ZEND_HASH_FOREACH_END_DEL();
+ ZEND_HASH_REVERSE_FOREACH_VAL(EG(function_table), zv) {
+ zend_function *func = Z_PTR_P(zv);
+ if (func->type == ZEND_INTERNAL_FUNCTION) {
+ break;
+ }
+ } ZEND_HASH_FOREACH_END_DEL();
+ ZEND_HASH_REVERSE_FOREACH_VAL(EG(class_table), zv) {
+ zend_class_entry *ce = Z_PTR_P(zv);
+ if (ce->type == ZEND_INTERNAL_CLASS) {
+ break;
+ }
+ } ZEND_HASH_FOREACH_END_DEL();
+ } else {
+ zend_hash_graceful_reverse_destroy(&EG(symbol_table));
+
+#if ZEND_DEBUG
+ if (GC_G(gc_enabled) && !CG(unclean_shutdown)) {
+ gc_collect_cycles();
+ }
+#endif
+
/* remove error handlers before destroying classes and functions,
* so that if handler used some class, crash would not happen */
if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
- zeh = &EG(user_error_handler);
- zval_ptr_dtor(zeh);
+ zval_ptr_dtor(&EG(user_error_handler));
ZVAL_UNDEF(&EG(user_error_handler));
}
if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
- zeh = &EG(user_exception_handler);
- zval_ptr_dtor(zeh);
+ zval_ptr_dtor(&EG(user_exception_handler));
ZVAL_UNDEF(&EG(user_exception_handler));
}
zend_stack_clean(&EG(user_error_handlers_error_reporting), NULL, 1);
zend_stack_clean(&EG(user_error_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1);
zend_stack_clean(&EG(user_exception_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1);
- } zend_end_try();
- zend_try {
- /* Cleanup static data for functions and arrays.
- * We need a separate cleanup stage because of the following problem:
- * Suppose we destroy class X, which destroys the class's function table,
- * and in the function table we have function foo() that has static $bar.
- * Now if an object of class X is assigned to $bar, its destructor will be
- * called and will fail since X's function table is in mid-destruction.
- * So we want first of all to clean up all data and then move to tables destruction.
- * Note that only run-time accessed data need to be cleaned up, pre-defined data can
- * not contain objects and thus are not probelmatic */
+ zend_vm_stack_destroy();
+
if (EG(full_tables_cleanup)) {
- ZEND_HASH_FOREACH_PTR(EG(function_table), func) {
- if (func->type == ZEND_USER_FUNCTION) {
- zend_cleanup_op_array_data((zend_op_array *) func);
+ 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);
+ } else {
+ ZEND_HASH_REVERSE_FOREACH_STR_KEY_VAL(EG(zend_constants), key, zv) {
+ zend_constant *c = Z_PTR_P(zv);
+ if (c->flags & CONST_PERSISTENT) {
+ break;
}
- } ZEND_HASH_FOREACH_END();
- ZEND_HASH_REVERSE_FOREACH_PTR(EG(class_table), ce) {
- if (ce->type == ZEND_USER_CLASS) {
- zend_cleanup_user_class_data(ce);
- } else {
- zend_cleanup_internal_class_data(ce);
+ zval_ptr_dtor(&c->value);
+ if (c->name) {
+ zend_string_release(c->name);
}
- } ZEND_HASH_FOREACH_END();
- } else {
- ZEND_HASH_REVERSE_FOREACH_PTR(EG(function_table), func) {
- if (func->type != ZEND_USER_FUNCTION) {
+ efree(c);
+ zend_string_release(key);
+ } ZEND_HASH_FOREACH_END_DEL();
+ ZEND_HASH_REVERSE_FOREACH_STR_KEY_VAL(EG(function_table), key, zv) {
+ zend_function *func = Z_PTR_P(zv);
+ if (func->type == ZEND_INTERNAL_FUNCTION) {
break;
}
- zend_cleanup_op_array_data((zend_op_array *) func);
- } ZEND_HASH_FOREACH_END();
- ZEND_HASH_REVERSE_FOREACH_PTR(EG(class_table), ce) {
- if (ce->type != ZEND_USER_CLASS) {
+ destroy_op_array(&func->op_array);
+ zend_string_release(key);
+ } ZEND_HASH_FOREACH_END_DEL();
+ ZEND_HASH_REVERSE_FOREACH_STR_KEY_VAL(EG(class_table), key, zv) {
+ zend_class_entry *ce = Z_PTR_P(zv);
+ if (ce->type == ZEND_INTERNAL_CLASS) {
break;
}
- zend_cleanup_user_class_data(ce);
- } ZEND_HASH_FOREACH_END();
- zend_cleanup_internal_classes();
- }
- } zend_end_try();
-
- zend_try {
- zend_llist_destroy(&CG(open_files));
- } zend_end_try();
-
- zend_try {
- clean_non_persistent_constants();
- } zend_end_try();
-
- zend_try {
- zend_close_rsrc_list(&EG(regular_list));
- } zend_end_try();
-
-#if ZEND_DEBUG
- if (GC_G(gc_enabled) && !CG(unclean_shutdown)) {
- gc_collect_cycles();
- }
-#endif
-
- zend_try {
- zend_objects_store_free_object_storage(&EG(objects_store));
-
- zend_vm_stack_destroy();
-
- /* Destroy all op arrays */
- if (EG(full_tables_cleanup)) {
- zend_hash_reverse_apply(EG(function_table), clean_non_persistent_function_full);
- zend_hash_reverse_apply(EG(class_table), clean_non_persistent_class_full);
- } else {
- zend_hash_reverse_apply(EG(function_table), clean_non_persistent_function);
- zend_hash_reverse_apply(EG(class_table), clean_non_persistent_class);
+ destroy_zend_class(zv);
+ zend_string_release(key);
+ } ZEND_HASH_FOREACH_END_DEL();
}
while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
@@ -377,12 +364,6 @@ void shutdown_executor(void) /* {{{ */
FREE_HASHTABLE(*EG(symtable_cache_ptr));
EG(symtable_cache_ptr)--;
}
- } zend_end_try();
-
- zend_try {
-#if 0&&ZEND_DEBUG
- signal(SIGSEGV, original_sigsegv_handler);
-#endif
zend_hash_destroy(&EG(included_files));
@@ -394,9 +375,11 @@ void shutdown_executor(void) /* {{{ */
zend_hash_destroy(EG(in_autoload));
FREE_HASHTABLE(EG(in_autoload));
}
- } zend_end_try();
- zend_shutdown_fpu();
+ if (EG(ht_iterators) != EG(ht_iterators_slots)) {
+ efree(EG(ht_iterators));
+ }
+ }
#if ZEND_DEBUG
if (EG(ht_iterators_used) && !CG(unclean_shutdown)) {
@@ -405,9 +388,10 @@ void shutdown_executor(void) /* {{{ */
#endif
EG(ht_iterators_used) = 0;
- if (EG(ht_iterators) != EG(ht_iterators_slots)) {
- efree(EG(ht_iterators));
- }
+
+ zend_cleanup_internal_classes();
+
+ zend_shutdown_fpu();
EG(active) = 0;
}
diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h
index 638fbe27fc..ef0d23bbbf 100644
--- a/Zend/zend_hash.h
+++ b/Zend/zend_hash.h
@@ -800,8 +800,9 @@ static zend_always_inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht,
zend_hash_get_current_data_ptr_ex(ht, &(ht)->nInternalPointer)
#define ZEND_HASH_FOREACH(_ht, indirect) do { \
- Bucket *_p = (_ht)->arData; \
- Bucket *_end = _p + (_ht)->nNumUsed; \
+ HashTable *__ht = (_ht); \
+ Bucket *_p = __ht->arData; \
+ Bucket *_end = _p + __ht->nNumUsed; \
for (; _p != _end; _p++) { \
zval *_z = &_p->val; \
if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { \
@@ -810,9 +811,10 @@ static zend_always_inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht,
if (UNEXPECTED(Z_TYPE_P(_z) == IS_UNDEF)) continue;
#define ZEND_HASH_REVERSE_FOREACH(_ht, indirect) do { \
+ HashTable *__ht = (_ht); \
uint32_t _idx; \
- for (_idx = (_ht)->nNumUsed; _idx > 0; _idx--) { \
- Bucket *_p = (_ht)->arData + _idx - 1; \
+ for (_idx = __ht->nNumUsed; _idx > 0; _idx--) { \
+ Bucket *_p = __ht->arData + (_idx - 1); \
zval *_z = &_p->val; \
if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { \
_z = Z_INDIRECT_P(_z); \
@@ -823,6 +825,27 @@ static zend_always_inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht,
} \
} while (0)
+#define ZEND_HASH_FOREACH_END_DEL() \
+ __ht->nNumOfElements--; \
+ do { \
+ uint32_t j = HT_IDX_TO_HASH(_idx - 1); \
+ uint32_t nIndex = _p->h | __ht->nTableMask; \
+ uint32_t i = HT_HASH(__ht, nIndex); \
+ if (j != i) { \
+ Bucket *prev = HT_HASH_TO_BUCKET(__ht, i); \
+ while (Z_NEXT(prev->val) != j) { \
+ i = Z_NEXT(prev->val); \
+ prev = HT_HASH_TO_BUCKET(__ht, i); \
+ } \
+ Z_NEXT(prev->val) = Z_NEXT(_p->val); \
+ } else { \
+ HT_HASH(__ht, _p->h | __ht->nTableMask) = Z_NEXT(_p->val); \
+ } \
+ } while (0); \
+ } \
+ __ht->nNumUsed = _idx; \
+ } while (0)
+
#define ZEND_HASH_FOREACH_BUCKET(ht, _bucket) \
ZEND_HASH_FOREACH(ht, 0); \
_bucket = _p;
@@ -911,6 +934,11 @@ static zend_always_inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht,
ZEND_HASH_REVERSE_FOREACH(ht, 1); \
_val = _z;
+#define ZEND_HASH_REVERSE_FOREACH_STR_KEY_VAL(ht, _key, _val) \
+ ZEND_HASH_REVERSE_FOREACH(ht, 0); \
+ _key = _p->key; \
+ _val = _z;
+
#define ZEND_HASH_REVERSE_FOREACH_KEY_VAL(ht, _h, _key, _val) \
ZEND_HASH_REVERSE_FOREACH(ht, 0); \
_h = _p->h; \
diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c
index 53a0c3be23..f838eddc97 100644
--- a/Zend/zend_objects_API.c
+++ b/Zend/zend_objects_API.c
@@ -76,7 +76,7 @@ ZEND_API void zend_objects_store_mark_destructed(zend_objects_store *objects)
}
}
-ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects)
+ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects, zend_bool fast_shutdown)
{
zend_object **obj_ptr, **end, *obj;
@@ -88,20 +88,37 @@ ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects
end = objects->object_buckets + 1;
obj_ptr = objects->object_buckets + objects->top;
- do {
- obj_ptr--;
- obj = *obj_ptr;
- if (IS_OBJ_VALID(obj)) {
- if (!(GC_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
- GC_FLAGS(obj) |= IS_OBJ_FREE_CALLED;
- if (obj->handlers->free_obj) {
- GC_REFCOUNT(obj)++;
- obj->handlers->free_obj(obj);
- GC_REFCOUNT(obj)--;
+ if (fast_shutdown) {
+ do {
+ obj_ptr--;
+ obj = *obj_ptr;
+ if (IS_OBJ_VALID(obj)) {
+ if (!(GC_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
+ GC_FLAGS(obj) |= IS_OBJ_FREE_CALLED;
+ if (obj->handlers->free_obj && obj->handlers->free_obj != zend_object_std_dtor) {
+ GC_REFCOUNT(obj)++;
+ obj->handlers->free_obj(obj);
+ GC_REFCOUNT(obj)--;
+ }
}
}
- }
- } while (obj_ptr != end);
+ } while (obj_ptr != end);
+ } else {
+ do {
+ obj_ptr--;
+ obj = *obj_ptr;
+ if (IS_OBJ_VALID(obj)) {
+ if (!(GC_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
+ GC_FLAGS(obj) |= IS_OBJ_FREE_CALLED;
+ if (obj->handlers->free_obj) {
+ GC_REFCOUNT(obj)++;
+ obj->handlers->free_obj(obj);
+ GC_REFCOUNT(obj)--;
+ }
+ }
+ }
+ } while (obj_ptr != end);
+ }
}
diff --git a/Zend/zend_objects_API.h b/Zend/zend_objects_API.h
index 223060035e..b105def176 100644
--- a/Zend/zend_objects_API.h
+++ b/Zend/zend_objects_API.h
@@ -68,7 +68,7 @@ static zend_always_inline void zend_object_store_ctor_failed(zend_object *obj)
GC_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED;
}
-ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects);
+ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects, zend_bool fast_shutdown);
#define ZEND_OBJECTS_STORE_HANDLERS 0, zend_object_std_dtor, zend_objects_destroy_object, zend_objects_clone_obj
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index e8764e964a..a0ec068405 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -148,51 +148,6 @@ ZEND_API void zend_function_dtor(zval *zv)
}
}
-ZEND_API void zend_cleanup_op_array_data(zend_op_array *op_array)
-{
- if (op_array->static_variables &&
- !(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)
- ) {
- /* The static variables are initially shared when inheriting methods and will
- * be separated on first use. If they are never used, they stay shared. Cleaning
- * a shared static variables table is safe, as the intention is to clean all
- * such tables. */
- HT_ALLOW_COW_VIOLATION(op_array->static_variables);
-
- zend_hash_clean(op_array->static_variables);
- }
-}
-
-ZEND_API void zend_cleanup_user_class_data(zend_class_entry *ce)
-{
- /* Clean all parts that can contain run-time data */
- /* Note that only run-time accessed data need to be cleaned up, pre-defined data can
- not contain objects and thus are not probelmatic */
- if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) {
- zend_function *func;
-
- ZEND_HASH_FOREACH_PTR(&ce->function_table, func) {
- if (func->type == ZEND_USER_FUNCTION) {
- zend_cleanup_op_array_data((zend_op_array *) func);
- }
- } ZEND_HASH_FOREACH_END();
- }
- if (ce->static_members_table) {
- zval *static_members = ce->static_members_table;
- zval *p = static_members;
- zval *end = p + ce->default_static_members_count;
-
-
- ce->default_static_members_count = 0;
- ce->default_static_members_table = ce->static_members_table = NULL;
- while (p != end) {
- i_zval_ptr_dtor(p ZEND_FILE_LINE_CC);
- p++;
- }
- efree(static_members);
- }
-}
-
ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce)
{
if (CE_STATIC_MEMBERS(ce)) {