Skip to content

Commit 86152b1

Browse files
committed
Add GC support to SPL heap and PQ
ctor/dtor are now no longer called for insert/delete_top operations, only for cloning and freeing of the object. Otherwise elements will have a minimum rc of 2 and GC won't be able to free them.
1 parent dc764bf commit 86152b1

File tree

1 file changed

+15
-17
lines changed

1 file changed

+15
-17
lines changed

ext/spl/spl_heap.c

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,6 @@ static void spl_ptr_heap_insert(spl_ptr_heap *heap, zval *elem, void *cmp_userda
248248
heap->max_size *= 2;
249249
}
250250

251-
heap->ctor(elem);
252-
253251
/* sifting up */
254252
for (i = heap->count++; i > 0 && heap->cmp(&heap->elements[(i-1)/2], elem, cmp_userdata) < 0; i = (i-1)/2) {
255253
heap->elements[i] = heap->elements[(i-1)/2];
@@ -307,7 +305,6 @@ static void spl_ptr_heap_delete_top(spl_ptr_heap *heap, zval *elem, void *cmp_us
307305
}
308306

309307
ZVAL_COPY_VALUE(&heap->elements[i], bottom);
310-
heap->dtor(elem);
311308
}
312309
/* }}} */
313310

@@ -350,23 +347,15 @@ static int spl_ptr_heap_count(spl_ptr_heap *heap) { /* {{{ */
350347
return heap->count;
351348
}
352349
/* }}} */
353-
/* }}} */
354350

355351
zend_object_iterator *spl_heap_get_iterator(zend_class_entry *ce, zval *object, int by_ref);
356352

357353
static void spl_heap_object_free_storage(zend_object *object) /* {{{ */
358354
{
359-
int i;
360355
spl_heap_object *intern = spl_heap_from_obj(object);
361356

362357
zend_object_std_dtor(&intern->std);
363358

364-
for (i = 0; i < intern->heap->count; ++i) {
365-
if (!Z_ISUNDEF(intern->heap->elements[i])) {
366-
zval_ptr_dtor(&intern->heap->elements[i]);
367-
}
368-
}
369-
370359
spl_ptr_heap_destroy(intern->heap);
371360
}
372361
/* }}} */
@@ -496,7 +485,7 @@ static int spl_heap_object_count_elements(zval *object, zend_long *count) /* {{{
496485
/* }}} */
497486

498487
static HashTable* spl_heap_object_get_debug_info_helper(zend_class_entry *ce, zval *obj, int *is_temp) { /* {{{ */
499-
spl_heap_object *intern = Z_SPLHEAP_P(obj);
488+
spl_heap_object *intern = Z_SPLHEAP_P(obj);
500489
zval tmp, heap_array;
501490
zend_string *pnstr;
502491
HashTable *debug_info;
@@ -539,6 +528,16 @@ static HashTable* spl_heap_object_get_debug_info_helper(zend_class_entry *ce, zv
539528
}
540529
/* }}} */
541530

531+
static HashTable *spl_heap_object_get_gc(zval *obj, zval **gc_data, int *gc_data_count) /* {{{ */
532+
{
533+
spl_heap_object *intern = Z_SPLHEAP_P(obj);
534+
*gc_data = intern->heap->elements;
535+
*gc_data_count = intern->heap->count;
536+
537+
return std_object_handlers.get_properties(obj);
538+
}
539+
/* }}} */
540+
542541
static HashTable* spl_heap_object_get_debug_info(zval *obj, int *is_temp) /* {{{ */
543542
{
544543
return spl_heap_object_get_debug_info_helper(spl_ce_SplHeap, obj, is_temp);
@@ -610,7 +609,6 @@ SPL_METHOD(SplHeap, insert)
610609
extract the element out of the top of the heap */
611610
SPL_METHOD(SplHeap, extract)
612611
{
613-
zval value;
614612
spl_heap_object *intern;
615613

616614
if (zend_parse_parameters_none() == FAILURE) {
@@ -624,14 +622,12 @@ SPL_METHOD(SplHeap, extract)
624622
return;
625623
}
626624

627-
spl_ptr_heap_delete_top(intern->heap, &value, getThis());
625+
spl_ptr_heap_delete_top(intern->heap, return_value, getThis());
628626

629-
if (Z_ISUNDEF(value)) {
627+
if (Z_ISUNDEF_P(return_value)) {
630628
zend_throw_exception(spl_ce_RuntimeException, "Can't extract from an empty heap", 0);
631629
return;
632630
}
633-
634-
RETURN_ZVAL(&value, 1, 1);
635631
}
636632
/* }}} */
637633

@@ -1216,6 +1212,7 @@ PHP_MINIT_FUNCTION(spl_heap) /* {{{ */
12161212
spl_handler_SplHeap.clone_obj = spl_heap_object_clone;
12171213
spl_handler_SplHeap.count_elements = spl_heap_object_count_elements;
12181214
spl_handler_SplHeap.get_debug_info = spl_heap_object_get_debug_info;
1215+
spl_handler_SplHeap.get_gc = spl_heap_object_get_gc;
12191216
spl_handler_SplHeap.dtor_obj = zend_objects_destroy_object;
12201217
spl_handler_SplHeap.free_obj = spl_heap_object_free_storage;
12211218

@@ -1237,6 +1234,7 @@ PHP_MINIT_FUNCTION(spl_heap) /* {{{ */
12371234
spl_handler_SplPriorityQueue.clone_obj = spl_heap_object_clone;
12381235
spl_handler_SplPriorityQueue.count_elements = spl_heap_object_count_elements;
12391236
spl_handler_SplPriorityQueue.get_debug_info = spl_pqueue_object_get_debug_info;
1237+
spl_handler_SplPriorityQueue.get_gc = spl_heap_object_get_gc;
12401238
spl_handler_SplPriorityQueue.dtor_obj = zend_objects_destroy_object;
12411239
spl_handler_SplPriorityQueue.free_obj = spl_heap_object_free_storage;
12421240

0 commit comments

Comments
 (0)