Skip to content

Instantly share code, notes, and snippets.

@nikic

nikic/gc.diff Secret

Created June 23, 2017 17:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nikic/614e8c5da3450564ce675ba8227669b6 to your computer and use it in GitHub Desktop.
Save nikic/614e8c5da3450564ce675ba8227669b6 to your computer and use it in GitHub Desktop.
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