@@ -268,9 +268,54 @@ void shutdown_executor(void) /* {{{ */
268
268
zend_close_rsrc_list (& EG (regular_list ));
269
269
} zend_end_try ();
270
270
271
+ /* No PHP callback functions should be called after this point. */
272
+ EG (active ) = 0 ;
273
+
271
274
if (!fast_shutdown ) {
272
275
zend_hash_graceful_reverse_destroy (& EG (symbol_table ));
273
276
277
+ /* Release static properties and static variables prior to the final GC run,
278
+ * as they may hold GC roots. */
279
+ ZEND_HASH_REVERSE_FOREACH_VAL (EG (function_table ), zv ) {
280
+ zend_op_array * op_array = Z_PTR_P (zv );
281
+ if (op_array -> type == ZEND_INTERNAL_FUNCTION ) {
282
+ break ;
283
+ }
284
+ if (op_array -> static_variables ) {
285
+ HashTable * ht = ZEND_MAP_PTR_GET (op_array -> static_variables_ptr );
286
+ if (ht ) {
287
+ ZEND_ASSERT (GC_REFCOUNT (ht ) == 1 );
288
+ zend_array_destroy (ht );
289
+ ZEND_MAP_PTR_SET (op_array -> static_variables_ptr , NULL );
290
+ }
291
+ }
292
+ } ZEND_HASH_FOREACH_END ();
293
+ ZEND_HASH_REVERSE_FOREACH_VAL (EG (class_table ), zv ) {
294
+ zend_class_entry * ce = Z_PTR_P (zv );
295
+ if (ce -> type == ZEND_INTERNAL_CLASS ) {
296
+ break ;
297
+ }
298
+ if (ce -> default_static_members_count ) {
299
+ zend_cleanup_internal_class_data (ce );
300
+ }
301
+ if (ce -> ce_flags & ZEND_HAS_STATIC_IN_METHODS ) {
302
+ zend_op_array * op_array ;
303
+ ZEND_HASH_FOREACH_PTR (& ce -> function_table , op_array ) {
304
+ if (op_array -> type == ZEND_USER_FUNCTION ) {
305
+ if (op_array -> static_variables ) {
306
+ HashTable * ht = ZEND_MAP_PTR_GET (op_array -> static_variables_ptr );
307
+ if (ht ) {
308
+ if (GC_DELREF (ht ) == 0 ) {
309
+ zend_array_destroy (ht );
310
+ }
311
+ ZEND_MAP_PTR_SET (op_array -> static_variables_ptr , NULL );
312
+ }
313
+ }
314
+ }
315
+ } ZEND_HASH_FOREACH_END ();
316
+ }
317
+ } ZEND_HASH_FOREACH_END ();
318
+
274
319
#if ZEND_DEBUG
275
320
if (gc_enabled () && !CG (unclean_shutdown )) {
276
321
gc_collect_cycles ();
@@ -282,10 +327,6 @@ void shutdown_executor(void) /* {{{ */
282
327
283
328
zend_weakrefs_shutdown ();
284
329
285
- /* All resources and objects are destroyed. */
286
- /* No PHP callback functions may be called after this point. */
287
- EG (active ) = 0 ;
288
-
289
330
zend_try {
290
331
zend_llist_apply (& zend_extensions , (llist_apply_func_t ) zend_extension_deactivator );
291
332
} zend_end_try ();
@@ -346,57 +387,13 @@ void shutdown_executor(void) /* {{{ */
346
387
zend_string_release_ex (key , 0 );
347
388
} ZEND_HASH_FOREACH_END_DEL ();
348
389
349
- /* Cleanup preloaded immutable functions */
350
- ZEND_HASH_REVERSE_FOREACH_VAL (EG (function_table ), zv ) {
351
- zend_op_array * op_array = Z_PTR_P (zv );
352
- if (op_array -> type == ZEND_INTERNAL_FUNCTION ) {
353
- break ;
354
- }
355
- ZEND_ASSERT (op_array -> fn_flags & ZEND_ACC_IMMUTABLE );
356
- if (op_array -> static_variables ) {
357
- HashTable * ht = ZEND_MAP_PTR_GET (op_array -> static_variables_ptr );
358
- if (ht ) {
359
- ZEND_ASSERT (GC_REFCOUNT (ht ) == 1 );
360
- zend_array_destroy (ht );
361
- ZEND_MAP_PTR_SET (op_array -> static_variables_ptr , NULL );
362
- }
363
- }
364
- } ZEND_HASH_FOREACH_END ();
365
-
366
390
ZEND_HASH_REVERSE_FOREACH_STR_KEY_VAL (EG (class_table ), key , zv ) {
367
391
if (_idx == EG (persistent_classes_count )) {
368
392
break ;
369
393
}
370
394
destroy_zend_class (zv );
371
395
zend_string_release_ex (key , 0 );
372
396
} ZEND_HASH_FOREACH_END_DEL ();
373
-
374
- /* Cleanup preloaded immutable classes */
375
- ZEND_HASH_REVERSE_FOREACH_VAL (EG (class_table ), zv ) {
376
- zend_class_entry * ce = Z_PTR_P (zv );
377
- if (ce -> type == ZEND_INTERNAL_CLASS ) {
378
- break ;
379
- }
380
- ZEND_ASSERT (ce -> ce_flags & ZEND_ACC_IMMUTABLE );
381
- if (ce -> default_static_members_count ) {
382
- zend_cleanup_internal_class_data (ce );
383
- }
384
- if (ce -> ce_flags & ZEND_HAS_STATIC_IN_METHODS ) {
385
- zend_op_array * op_array ;
386
- ZEND_HASH_FOREACH_PTR (& ce -> function_table , op_array ) {
387
- if (op_array -> type == ZEND_USER_FUNCTION ) {
388
- if (op_array -> static_variables ) {
389
- HashTable * ht = ZEND_MAP_PTR_GET (op_array -> static_variables_ptr );
390
- if (ht ) {
391
- ZEND_ASSERT (GC_REFCOUNT (ht ) == 1 );
392
- zend_array_destroy (ht );
393
- ZEND_MAP_PTR_SET (op_array -> static_variables_ptr , NULL );
394
- }
395
- }
396
- }
397
- } ZEND_HASH_FOREACH_END ();
398
- }
399
- } ZEND_HASH_FOREACH_END ();
400
397
}
401
398
402
399
zend_cleanup_internal_classes ();
0 commit comments