Skip to content

Commit c77d97f

Browse files
committed
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.
1 parent 018bcc6 commit c77d97f

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

ext/spl/spl_dllist.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ struct _spl_dllist_object {
9393
zend_function *fptr_offset_del;
9494
zend_function *fptr_count;
9595
zend_class_entry *ce_get_iterator;
96+
zval *gc_data;
97+
int gc_data_count;
9698
zend_object std;
9799
};
98100

@@ -354,6 +356,10 @@ static void spl_dllist_object_free_storage(zend_object *object) /* {{{ */
354356
zval_ptr_dtor(&tmp);
355357
}
356358

359+
if (intern->gc_data != NULL) {
360+
efree(intern->gc_data);
361+
};
362+
357363
spl_ptr_llist_destroy(intern->llist);
358364
SPL_LLIST_CHECK_DELREF(intern->traverse_pointer);
359365
}
@@ -531,6 +537,28 @@ static HashTable* spl_dllist_object_get_debug_info(zval *obj, int *is_temp) /* {
531537
}
532538
/* }}}} */
533539

540+
static HashTable *spl_dllist_object_get_gc(zval *obj, zval **gc_data, int *gc_data_count) /* {{{ */
541+
{
542+
spl_dllist_object *intern = Z_SPLDLLIST_P(obj);
543+
spl_ptr_llist_element *current = intern->llist->head;
544+
int i = 0;
545+
546+
if (intern->gc_data_count < intern->llist->count) {
547+
intern->gc_data_count = intern->llist->count;
548+
intern->gc_data = safe_erealloc(intern->gc_data, intern->gc_data_count, sizeof(zval), 0);
549+
}
550+
551+
while (current) {
552+
ZVAL_COPY_VALUE(&intern->gc_data[i++], &current->data);
553+
current = current->next;
554+
}
555+
556+
*gc_data = intern->gc_data;
557+
*gc_data_count = i;
558+
return zend_std_get_properties(obj);
559+
}
560+
/* }}} */
561+
534562
/* {{{ proto bool SplDoublyLinkedList::push(mixed $value)
535563
Push $value on the SplDoublyLinkedList */
536564
SPL_METHOD(SplDoublyLinkedList, push)
@@ -1366,6 +1394,7 @@ PHP_MINIT_FUNCTION(spl_dllist) /* {{{ */
13661394
spl_handler_SplDoublyLinkedList.clone_obj = spl_dllist_object_clone;
13671395
spl_handler_SplDoublyLinkedList.count_elements = spl_dllist_object_count_elements;
13681396
spl_handler_SplDoublyLinkedList.get_debug_info = spl_dllist_object_get_debug_info;
1397+
spl_handler_SplDoublyLinkedList.get_gc = spl_dllist_object_get_gc;
13691398
spl_handler_SplDoublyLinkedList.dtor_obj = zend_objects_destroy_object;
13701399
spl_handler_SplDoublyLinkedList.free_obj = spl_dllist_object_free_storage;
13711400

0 commit comments

Comments
 (0)