-
-
Save nikic/614e8c5da3450564ce675ba8227669b6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c | |
index 31bec4c..fbd86da 100644 | |
--- a/Zend/zend_gc.c | |
+++ b/Zend/zend_gc.c | |
@@ -1107,13 +1107,6 @@ ZEND_API int zend_gc_collect_cycles(void) | |
if (gc_flags & GC_HAS_DESTRUCTORS) { | |
GC_TRACE("Calling destructors"); | |
- /* Remember reference counters before calling destructors */ | |
- current = to_free.next; | |
- while (current != &to_free) { | |
- current->refcount = GC_REFCOUNT(current->ref); | |
- current = current->next; | |
- } | |
- | |
/* Call destructors */ | |
current = to_free.next; | |
while (current != &to_free) { | |
@@ -1124,27 +1117,25 @@ ZEND_API int zend_gc_collect_cycles(void) | |
if (IS_OBJ_VALID(EG(objects_store).object_buckets[obj->handle]) && | |
!(GC_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) { | |
- GC_TRACE_REF(obj, "calling destructor"); | |
GC_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED; | |
- if (obj->handlers->dtor_obj) { | |
+ if (obj->handlers->dtor_obj && | |
+ (obj->handlers->dtor_obj != zend_objects_destroy_object | |
+ || obj->ce->destructor != NULL)) { | |
+ GC_TRACE_REF(obj, "calling destructor"); | |
GC_REFCOUNT(obj)++; | |
obj->handlers->dtor_obj(obj); | |
GC_REFCOUNT(obj)--; | |
+ | |
+ /* New references to the object might have been added in the | |
+ * destructor. Remove it from the current GC, and leave it for | |
+ * the next one. */ | |
+ gc_remove_nested_data_from_buffer(p, current); | |
+ gc_possible_root(p); | |
} | |
} | |
} | |
current = GC_G(next_to_free); | |
} | |
- | |
- /* Remove values captured in destructors */ | |
- current = to_free.next; | |
- while (current != &to_free) { | |
- GC_G(next_to_free) = current->next; | |
- if (GC_REFCOUNT(current->ref) > current->refcount) { | |
- gc_remove_nested_data_from_buffer(current->ref, current); | |
- } | |
- current = GC_G(next_to_free); | |
- } | |
} | |
/* Destroy zvals */ | |
diff --git a/Zend/zend_gc.h b/Zend/zend_gc.h | |
index 10c881c..7063718 100644 | |
--- a/Zend/zend_gc.h | |
+++ b/Zend/zend_gc.h | |
@@ -64,7 +64,6 @@ typedef struct _gc_root_buffer { | |
zend_refcounted *ref; | |
struct _gc_root_buffer *next; /* double-linked list */ | |
struct _gc_root_buffer *prev; | |
- uint32_t refcount; | |
} gc_root_buffer; | |
#define GC_NUM_ADDITIONAL_ENTRIES \ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment