mirror of
https://github.com/php/php-src.git
synced 2026-04-28 02:33:17 +02:00
Merge branch 'PHP-7.4'
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
--TEST--
|
||||
Bug #78335: Static properties/variables containing cycles report as leak
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Test {
|
||||
public static $test;
|
||||
|
||||
public static function method() {
|
||||
static $foo;
|
||||
$foo = [&$foo];
|
||||
}
|
||||
}
|
||||
|
||||
function test() {
|
||||
static $foo;
|
||||
$foo = [&$foo];
|
||||
}
|
||||
|
||||
$foo = [&$foo];
|
||||
Test::$test = $foo;
|
||||
test();
|
||||
Test::method();
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
===DONE===
|
||||
+45
-48
@@ -268,9 +268,54 @@ void shutdown_executor(void) /* {{{ */
|
||||
zend_close_rsrc_list(&EG(regular_list));
|
||||
} zend_end_try();
|
||||
|
||||
/* No PHP callback functions should be called after this point. */
|
||||
EG(active) = 0;
|
||||
|
||||
if (!fast_shutdown) {
|
||||
zend_hash_graceful_reverse_destroy(&EG(symbol_table));
|
||||
|
||||
/* Release static properties and static variables prior to the final GC run,
|
||||
* as they may hold GC roots. */
|
||||
ZEND_HASH_REVERSE_FOREACH_VAL(EG(function_table), zv) {
|
||||
zend_op_array *op_array = Z_PTR_P(zv);
|
||||
if (op_array->type == ZEND_INTERNAL_FUNCTION) {
|
||||
break;
|
||||
}
|
||||
if (op_array->static_variables) {
|
||||
HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
|
||||
if (ht) {
|
||||
ZEND_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
zend_array_destroy(ht);
|
||||
ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
|
||||
}
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
ZEND_HASH_REVERSE_FOREACH_VAL(EG(class_table), zv) {
|
||||
zend_class_entry *ce = Z_PTR_P(zv);
|
||||
if (ce->type == ZEND_INTERNAL_CLASS) {
|
||||
break;
|
||||
}
|
||||
if (ce->default_static_members_count) {
|
||||
zend_cleanup_internal_class_data(ce);
|
||||
}
|
||||
if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) {
|
||||
zend_op_array *op_array;
|
||||
ZEND_HASH_FOREACH_PTR(&ce->function_table, op_array) {
|
||||
if (op_array->type == ZEND_USER_FUNCTION) {
|
||||
if (op_array->static_variables) {
|
||||
HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
|
||||
if (ht) {
|
||||
if (GC_DELREF(ht) == 0) {
|
||||
zend_array_destroy(ht);
|
||||
}
|
||||
ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
#if ZEND_DEBUG
|
||||
if (gc_enabled() && !CG(unclean_shutdown)) {
|
||||
gc_collect_cycles();
|
||||
@@ -282,10 +327,6 @@ void shutdown_executor(void) /* {{{ */
|
||||
|
||||
zend_weakrefs_shutdown();
|
||||
|
||||
/* All resources and objects are destroyed. */
|
||||
/* No PHP callback functions may be called after this point. */
|
||||
EG(active) = 0;
|
||||
|
||||
zend_try {
|
||||
zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator);
|
||||
} zend_end_try();
|
||||
@@ -346,23 +387,6 @@ void shutdown_executor(void) /* {{{ */
|
||||
zend_string_release_ex(key, 0);
|
||||
} ZEND_HASH_FOREACH_END_DEL();
|
||||
|
||||
/* Cleanup preloaded immutable functions */
|
||||
ZEND_HASH_REVERSE_FOREACH_VAL(EG(function_table), zv) {
|
||||
zend_op_array *op_array = Z_PTR_P(zv);
|
||||
if (op_array->type == ZEND_INTERNAL_FUNCTION) {
|
||||
break;
|
||||
}
|
||||
ZEND_ASSERT(op_array->fn_flags & ZEND_ACC_IMMUTABLE);
|
||||
if (op_array->static_variables) {
|
||||
HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
|
||||
if (ht) {
|
||||
ZEND_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
zend_array_destroy(ht);
|
||||
ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
|
||||
}
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
ZEND_HASH_REVERSE_FOREACH_STR_KEY_VAL(EG(class_table), key, zv) {
|
||||
if (_idx == EG(persistent_classes_count)) {
|
||||
break;
|
||||
@@ -370,33 +394,6 @@ void shutdown_executor(void) /* {{{ */
|
||||
destroy_zend_class(zv);
|
||||
zend_string_release_ex(key, 0);
|
||||
} ZEND_HASH_FOREACH_END_DEL();
|
||||
|
||||
/* Cleanup preloaded immutable classes */
|
||||
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_ASSERT(ce->ce_flags & ZEND_ACC_IMMUTABLE);
|
||||
if (ce->default_static_members_count) {
|
||||
zend_cleanup_internal_class_data(ce);
|
||||
}
|
||||
if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) {
|
||||
zend_op_array *op_array;
|
||||
ZEND_HASH_FOREACH_PTR(&ce->function_table, op_array) {
|
||||
if (op_array->type == ZEND_USER_FUNCTION) {
|
||||
if (op_array->static_variables) {
|
||||
HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
|
||||
if (ht) {
|
||||
ZEND_ASSERT(GC_REFCOUNT(ht) == 1);
|
||||
zend_array_destroy(ht);
|
||||
ZEND_MAP_PTR_SET(op_array->static_variables_ptr, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
|
||||
zend_cleanup_internal_classes();
|
||||
|
||||
Reference in New Issue
Block a user