@@ -340,13 +340,57 @@ void shutdown_executor(void) /* {{{ */
340340 destroy_op_array (& func -> op_array );
341341 zend_string_release_ex (key , 0 );
342342 } ZEND_HASH_FOREACH_END_DEL ();
343+
344+ /* Cleanup preloaded immutable functions */
345+ ZEND_HASH_REVERSE_FOREACH_VAL (EG (function_table ), zv ) {
346+ zend_op_array * op_array = Z_PTR_P (zv );
347+ if (op_array -> type == ZEND_INTERNAL_FUNCTION ) {
348+ break ;
349+ }
350+ ZEND_ASSERT (op_array -> fn_flags & ZEND_ACC_IMMUTABLE );
351+ if (op_array -> static_variables ) {
352+ HashTable * ht = ZEND_MAP_PTR_GET (op_array -> static_variables_ptr );
353+ if (ht ) {
354+ ZEND_ASSERT (GC_REFCOUNT (ht ) == 1 );
355+ zend_array_destroy (ht );
356+ }
357+ }
358+ } ZEND_HASH_FOREACH_END ();
359+
343360 ZEND_HASH_REVERSE_FOREACH_STR_KEY_VAL (EG (class_table ), key , zv ) {
344361 if (_idx == EG (persistent_classes_count )) {
345362 break ;
346363 }
347364 destroy_zend_class (zv );
348365 zend_string_release_ex (key , 0 );
349366 } ZEND_HASH_FOREACH_END_DEL ();
367+
368+ /* Cleanup preloaded immutable classes */
369+ ZEND_HASH_REVERSE_FOREACH_VAL (EG (class_table ), zv ) {
370+ zend_class_entry * ce = Z_PTR_P (zv );
371+ if (ce -> type == ZEND_INTERNAL_CLASS ) {
372+ break ;
373+ }
374+ ZEND_ASSERT (ce -> ce_flags & ZEND_ACC_IMMUTABLE );
375+ if (ce -> default_static_members_count ) {
376+ zend_cleanup_internal_class_data (ce );
377+ }
378+ if (ce -> ce_flags & ZEND_HAS_STATIC_IN_METHODS ) {
379+ zend_op_array * op_array ;
380+
381+ ZEND_HASH_FOREACH_PTR (& ce -> function_table , op_array ) {
382+ if (op_array -> type == ZEND_USER_FUNCTION ) {
383+ if (op_array -> static_variables ) {
384+ HashTable * ht = ZEND_MAP_PTR_GET (op_array -> static_variables_ptr );
385+ if (ht ) {
386+ ZEND_ASSERT (GC_REFCOUNT (ht ) == 1 );
387+ zend_array_destroy (ht );
388+ }
389+ }
390+ }
391+ } ZEND_HASH_FOREACH_END ();
392+ }
393+ } ZEND_HASH_FOREACH_END ();
350394 }
351395
352396 zend_cleanup_internal_classes ();
0 commit comments