Skip to content

Commit 78aed20

Browse files
committed
Optimized cleanup loops on request shutdown
1 parent c23806d commit 78aed20

File tree

4 files changed

+46
-25
lines changed

4 files changed

+46
-25
lines changed

Zend/zend_compile.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,7 @@ ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle TSRMLS_DC);
537537
ZEND_API void zend_file_handle_dtor(zend_file_handle *fh);
538538
ZEND_API int zend_cleanup_class_data(zend_class_entry **pce TSRMLS_DC);
539539
ZEND_API int zend_cleanup_function_data(zend_function *function TSRMLS_DC);
540+
ZEND_API int zend_cleanup_function_data_full(zend_function *function TSRMLS_DC);
540541

541542
ZEND_API void destroy_zend_function(zend_function *function TSRMLS_DC);
542543
ZEND_API void zend_function_dtor(zend_function *function);

Zend/zend_constants.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,13 @@ void zend_copy_constants(HashTable *target, HashTable *source)
6060

6161
static int clean_non_persistent_constant(zend_constant *c TSRMLS_DC)
6262
{
63-
if (c->flags & CONST_PERSISTENT) {
64-
return EG(full_tables_cleanup) ? 0 : ZEND_HASH_APPLY_STOP;
65-
} else {
66-
return EG(full_tables_cleanup) ? 1 : ZEND_HASH_APPLY_REMOVE;
67-
}
63+
return (c->flags & CONST_PERSISTENT) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE;
64+
}
65+
66+
67+
static int clean_non_persistent_constant_full(zend_constant *c TSRMLS_DC)
68+
{
69+
return (c->flags & CONST_PERSISTENT) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
6870
}
6971

7072

@@ -164,7 +166,7 @@ int zend_shutdown_constants(TSRMLS_D)
164166
void clean_non_persistent_constants(TSRMLS_D)
165167
{
166168
if (EG(full_tables_cleanup)) {
167-
zend_hash_apply(EG(zend_constants), (apply_func_t) clean_non_persistent_constant TSRMLS_CC);
169+
zend_hash_apply(EG(zend_constants), (apply_func_t) clean_non_persistent_constant_full TSRMLS_CC);
168170
} else {
169171
zend_hash_reverse_apply(EG(zend_constants), (apply_func_t) clean_non_persistent_constant TSRMLS_CC);
170172
}

Zend/zend_execute_API.c

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -107,23 +107,27 @@ static void zend_extension_deactivator(zend_extension *extension TSRMLS_DC)
107107
}
108108

109109

110-
static int is_not_internal_function(zend_function *function TSRMLS_DC)
110+
static int clean_non_persistent_function(zend_function *function TSRMLS_DC)
111111
{
112-
if (function->type == ZEND_INTERNAL_FUNCTION) {
113-
return EG(full_tables_cleanup) ? 0 : ZEND_HASH_APPLY_STOP;
114-
} else {
115-
return EG(full_tables_cleanup) ? 1 : ZEND_HASH_APPLY_REMOVE;
116-
}
112+
return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE;
117113
}
118114

119115

120-
static int is_not_internal_class(zend_class_entry **ce TSRMLS_DC)
116+
static int clean_non_persistent_function_full(zend_function *function TSRMLS_DC)
121117
{
122-
if ((*ce)->type == ZEND_INTERNAL_CLASS) {
123-
return EG(full_tables_cleanup) ? 0 : ZEND_HASH_APPLY_STOP;
124-
} else {
125-
return EG(full_tables_cleanup) ? 1 : ZEND_HASH_APPLY_REMOVE;
126-
}
118+
return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
119+
}
120+
121+
122+
static int clean_non_persistent_class(zend_class_entry **ce TSRMLS_DC)
123+
{
124+
return ((*ce)->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE;
125+
}
126+
127+
128+
static int clean_non_persistent_class_full(zend_class_entry **ce TSRMLS_DC)
129+
{
130+
return ((*ce)->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
127131
}
128132

129133

@@ -263,18 +267,22 @@ void shutdown_executor(TSRMLS_D)
263267
So we want first of all to clean up all data and then move to tables destruction.
264268
Note that only run-time accessed data need to be cleaned up, pre-defined data can
265269
not contain objects and thus are not probelmatic */
266-
zend_hash_apply(EG(function_table), (apply_func_t) zend_cleanup_function_data TSRMLS_CC);
270+
if (EG(full_tables_cleanup)) {
271+
zend_hash_apply(EG(function_table), (apply_func_t) zend_cleanup_function_data_full TSRMLS_CC);
272+
} else {
273+
zend_hash_reverse_apply(EG(function_table), (apply_func_t) zend_cleanup_function_data TSRMLS_CC);
274+
}
267275
zend_hash_apply(EG(class_table), (apply_func_t) zend_cleanup_class_data TSRMLS_CC);
268276

269277
zend_ptr_stack_destroy(&EG(argument_stack));
270278

271279
/* Destroy all op arrays */
272280
if (EG(full_tables_cleanup)) {
273-
zend_hash_apply(EG(function_table), (apply_func_t) is_not_internal_function TSRMLS_CC);
274-
zend_hash_apply(EG(class_table), (apply_func_t) is_not_internal_class TSRMLS_CC);
281+
zend_hash_apply(EG(function_table), (apply_func_t) clean_non_persistent_function_full TSRMLS_CC);
282+
zend_hash_apply(EG(class_table), (apply_func_t) clean_non_persistent_class_full TSRMLS_CC);
275283
} else {
276-
zend_hash_reverse_apply(EG(function_table), (apply_func_t) is_not_internal_function TSRMLS_CC);
277-
zend_hash_reverse_apply(EG(class_table), (apply_func_t) is_not_internal_class TSRMLS_CC);
284+
zend_hash_reverse_apply(EG(function_table), (apply_func_t) clean_non_persistent_function TSRMLS_CC);
285+
zend_hash_reverse_apply(EG(class_table), (apply_func_t) clean_non_persistent_class TSRMLS_CC);
278286
}
279287

280288
while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {

Zend/zend_opcode.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,18 @@ ZEND_API int zend_cleanup_function_data(zend_function *function TSRMLS_DC)
135135
{
136136
if (function->type == ZEND_USER_FUNCTION) {
137137
zend_cleanup_op_array_data((zend_op_array *) function);
138+
return ZEND_HASH_APPLY_KEEP;
139+
} else {
140+
return ZEND_HASH_APPLY_STOP;
138141
}
139-
return 0;
142+
}
143+
144+
ZEND_API int zend_cleanup_function_data_full(zend_function *function TSRMLS_DC)
145+
{
146+
if (function->type == ZEND_USER_FUNCTION) {
147+
zend_cleanup_op_array_data((zend_op_array *) function);
148+
}
149+
return ZEND_HASH_APPLY_KEEP;
140150
}
141151

142152
ZEND_API int zend_cleanup_class_data(zend_class_entry **pce TSRMLS_DC)
@@ -145,7 +155,7 @@ ZEND_API int zend_cleanup_class_data(zend_class_entry **pce TSRMLS_DC)
145155
/* Clean all parts that can contain run-time data */
146156
/* Note that only run-time accessed data need to be cleaned up, pre-defined data can
147157
not contain objects and thus are not probelmatic */
148-
zend_hash_apply(&(*pce)->function_table, (apply_func_t) zend_cleanup_function_data TSRMLS_CC);
158+
zend_hash_apply(&(*pce)->function_table, (apply_func_t) zend_cleanup_function_data_full TSRMLS_CC);
149159
(*pce)->static_members = NULL;
150160
} else if (CE_STATIC_MEMBERS(*pce)) {
151161
zend_hash_destroy(CE_STATIC_MEMBERS(*pce));

0 commit comments

Comments
 (0)