summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2015-04-17 12:37:51 +0200
committerNikita Popov <nikic@php.net>2015-04-18 17:31:11 +0200
commitaef96d5169111db7e17f06ff6b13d56cd980cb8c (patch)
tree5b6da35be905bfe9b887d1336b31e155900cac68
parentf616a6f1ebf7ec8ece54022791f078bea8a1e973 (diff)
downloadphp-git-aef96d5169111db7e17f06ff6b13d56cd980cb8c.tar.gz
Partially enable leak reports for objects
Cycle leaks are currently not reported, because this needs further work. The last GC run has been moved to run earlier (before the object store free), so that array cycles that hold references to objects don't show up as leaks. Fingers crossed that this doesn't adversely affect anything else.
-rw-r--r--Zend/zend.c6
-rw-r--r--Zend/zend_execute_API.c6
-rw-r--r--Zend/zend_objects_API.c8
3 files changed, 11 insertions, 9 deletions
diff --git a/Zend/zend.c b/Zend/zend.c
index 03082de4d6..cf87b2620c 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -967,12 +967,6 @@ ZEND_API void zend_deactivate(void) /* {{{ */
shutdown_compiler();
} zend_end_try();
-#if ZEND_DEBUG
- if (GC_G(gc_enabled) && !CG(unclean_shutdown)) {
- gc_collect_cycles();
- }
-#endif
-
zend_destroy_rsrc_list(&EG(regular_list));
#if GC_BENCH
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index ac9f4b1c5c..37a27150e5 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -331,6 +331,12 @@ void shutdown_executor(void) /* {{{ */
zend_close_rsrc_list(&EG(regular_list));
} zend_end_try();
+#if ZEND_DEBUG
+ if (GC_G(gc_enabled) && !CG(unclean_shutdown)) {
+ gc_collect_cycles();
+ }
+#endif
+
zend_try {
zend_objects_store_free_object_storage(&EG(objects_store));
diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c
index 92e36a5558..4be4723105 100644
--- a/Zend/zend_objects_API.c
+++ b/Zend/zend_objects_API.c
@@ -78,7 +78,7 @@ ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects
{
uint32_t i;
- /* Free object properties but don't free object their selves */
+ /* Free object contents, but don't free objects themselves */
for (i = objects->top - 1; i > 0 ; i--) {
zend_object *obj = objects->object_buckets[i];
@@ -94,11 +94,13 @@ ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects
}
}
- /* Now free objects theirselves */
+ /* Free objects themselves if they now have a refcount of 0, which means that
+ * they were previously part of a cycle. Everything else will report as a leak.
+ * Cycles are allowed because not all internal objects currently support GC. */
for (i = 1; i < objects->top ; i++) {
zend_object *obj = objects->object_buckets[i];
- if (IS_OBJ_VALID(obj)) {
+ if (IS_OBJ_VALID(obj) && GC_REFCOUNT(obj) == 0) {
/* Not adding to free list as we are shutting down anyway */
void *ptr = ((char*)obj) - obj->handlers->offset;
GC_REMOVE_FROM_BUFFER(obj);