]> granicus.if.org Git - php/commitdiff
Partially enable leak reports for objects
authorNikita Popov <nikic@php.net>
Fri, 17 Apr 2015 10:37:51 +0000 (12:37 +0200)
committerNikita Popov <nikic@php.net>
Sat, 18 Apr 2015 15:31:11 +0000 (17:31 +0200)
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.

Zend/zend.c
Zend/zend_execute_API.c
Zend/zend_objects_API.c

index 03082de4d6e214a1d313943727f2bfead1d41bda..cf87b2620c5e45829767abe9e82ac72bacce6028 100644 (file)
@@ -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
index ac9f4b1c5c10f991deded1e5a5d0d03681a2eb2b..37a27150e5a1619da2d5e8423d4f600eda7f9ac8 100644 (file)
@@ -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));
 
index 92e36a5558e25aa1aeeedf2bc70b7ce9c7527e51..4be47231053764d22f29bbc041d6fbd725489c81 100644 (file)
@@ -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);