summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2015-04-16 15:13:15 +0200
committerNikita Popov <nikic@php.net>2015-04-16 15:46:28 +0200
commitc77d97f356d07b109058b399c47b14c798845dc0 (patch)
tree7de820ea12938c9c68ca516086352d388869a15d
parent018bcc638807d814f71acc78e5cbdbc18c1de649 (diff)
downloadphp-git-c77d97f356d07b109058b399c47b14c798845dc0.tar.gz
Implement GC for spl dll
As far as I can discern this should be safe, because the rc on the linked list elements is only > 1 if an iterator points to it and the iterator will also hold a reference to the list object. The implementation for mangagement of the GC array is the same as with the spl object storage.
-rw-r--r--ext/spl/spl_dllist.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c
index 6406670e2e..6dc2e23b3d 100644
--- a/ext/spl/spl_dllist.c
+++ b/ext/spl/spl_dllist.c
@@ -93,6 +93,8 @@ struct _spl_dllist_object {
zend_function *fptr_offset_del;
zend_function *fptr_count;
zend_class_entry *ce_get_iterator;
+ zval *gc_data;
+ int gc_data_count;
zend_object std;
};
@@ -354,6 +356,10 @@ static void spl_dllist_object_free_storage(zend_object *object) /* {{{ */
zval_ptr_dtor(&tmp);
}
+ if (intern->gc_data != NULL) {
+ efree(intern->gc_data);
+ };
+
spl_ptr_llist_destroy(intern->llist);
SPL_LLIST_CHECK_DELREF(intern->traverse_pointer);
}
@@ -531,6 +537,28 @@ static HashTable* spl_dllist_object_get_debug_info(zval *obj, int *is_temp) /* {
}
/* }}}} */
+static HashTable *spl_dllist_object_get_gc(zval *obj, zval **gc_data, int *gc_data_count) /* {{{ */
+{
+ spl_dllist_object *intern = Z_SPLDLLIST_P(obj);
+ spl_ptr_llist_element *current = intern->llist->head;
+ int i = 0;
+
+ if (intern->gc_data_count < intern->llist->count) {
+ intern->gc_data_count = intern->llist->count;
+ intern->gc_data = safe_erealloc(intern->gc_data, intern->gc_data_count, sizeof(zval), 0);
+ }
+
+ while (current) {
+ ZVAL_COPY_VALUE(&intern->gc_data[i++], &current->data);
+ current = current->next;
+ }
+
+ *gc_data = intern->gc_data;
+ *gc_data_count = i;
+ return zend_std_get_properties(obj);
+}
+/* }}} */
+
/* {{{ proto bool SplDoublyLinkedList::push(mixed $value)
Push $value on the SplDoublyLinkedList */
SPL_METHOD(SplDoublyLinkedList, push)
@@ -1366,6 +1394,7 @@ PHP_MINIT_FUNCTION(spl_dllist) /* {{{ */
spl_handler_SplDoublyLinkedList.clone_obj = spl_dllist_object_clone;
spl_handler_SplDoublyLinkedList.count_elements = spl_dllist_object_count_elements;
spl_handler_SplDoublyLinkedList.get_debug_info = spl_dllist_object_get_debug_info;
+ spl_handler_SplDoublyLinkedList.get_gc = spl_dllist_object_get_gc;
spl_handler_SplDoublyLinkedList.dtor_obj = zend_objects_destroy_object;
spl_handler_SplDoublyLinkedList.free_obj = spl_dllist_object_free_storage;