diff options
author | Nikita Popov <nikic@php.net> | 2015-04-16 15:13:15 +0200 |
---|---|---|
committer | Nikita Popov <nikic@php.net> | 2015-04-16 15:46:28 +0200 |
commit | c77d97f356d07b109058b399c47b14c798845dc0 (patch) | |
tree | 7de820ea12938c9c68ca516086352d388869a15d | |
parent | 018bcc638807d814f71acc78e5cbdbc18c1de649 (diff) | |
download | php-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.c | 29 |
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++], ¤t->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; |