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