From 0643301c758ecf89d588db391d55a453e56b1212 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 9 Jun 2021 11:13:15 +0200 Subject: [PATCH] Don't perform recursive get_gc call On further consideration, we should be making use of the fact that zend_object_iterator is also a zend_object here, and let GC handle the get_gc call on it. Calling get_gc recursively like this is generally not safe, because there is only one gc_buffer. This also happens to be much simpler... --- Zend/zend_gc.c | 6 ------ Zend/zend_gc.h | 10 ---------- ext/spl/spl_iterators.c | 11 ++--------- 3 files changed, 2 insertions(+), 25 deletions(-) diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index 3e66dae10db..f0c9a847b8c 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -1637,12 +1637,6 @@ ZEND_API void zend_get_gc_buffer_grow(zend_get_gc_buffer *gc_buffer) { gc_buffer->cur = gc_buffer->start + old_capacity; } -ZEND_API void zend_get_gc_buffer_add_zvals(zend_get_gc_buffer *gc_buffer, zval *zvs, size_t n) { - for (size_t i = 0; i < n; i++) { - zend_get_gc_buffer_add_zval(gc_buffer, &zvs[i]); - } -} - static void zend_get_gc_buffer_release() { zend_get_gc_buffer *gc_buffer = &EG(get_gc_buffer); efree(gc_buffer->start); diff --git a/Zend/zend_gc.h b/Zend/zend_gc.h index 0008b07845b..3221335733e 100644 --- a/Zend/zend_gc.h +++ b/Zend/zend_gc.h @@ -93,7 +93,6 @@ typedef struct { ZEND_API zend_get_gc_buffer *zend_get_gc_buffer_create(void); ZEND_API void zend_get_gc_buffer_grow(zend_get_gc_buffer *gc_buffer); -ZEND_API void zend_get_gc_buffer_add_zvals(zend_get_gc_buffer *gc_buffer, zval *zvs, size_t n); static zend_always_inline void zend_get_gc_buffer_add_zval( zend_get_gc_buffer *gc_buffer, zval *zv) { @@ -115,15 +114,6 @@ static zend_always_inline void zend_get_gc_buffer_add_obj( gc_buffer->cur++; } -static zend_always_inline void zend_get_gc_buffer_add_ht( - zend_get_gc_buffer *gc_buffer, HashTable *ht) { - if (UNEXPECTED(gc_buffer->cur == gc_buffer->end)) { - zend_get_gc_buffer_grow(gc_buffer); - } - ZVAL_ARR(gc_buffer->cur, ht); - gc_buffer->cur++; -} - static zend_always_inline void zend_get_gc_buffer_use( zend_get_gc_buffer *gc_buffer, zval **table, int *n) { *table = gc_buffer->start; diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index c72e0888d38..2718948b327 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -2103,15 +2103,8 @@ static HashTable *spl_dual_it_get_gc(zend_object *obj, zval **table, int *n) spl_dual_it_object *object = spl_dual_it_from_obj(obj); zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); - if (object->inner.iterator && object->inner.iterator->funcs->get_gc) { - zval *inner_table; - int inner_n; - HashTable *inner_ht = object->inner.iterator->funcs->get_gc( - object->inner.iterator, &inner_table, &inner_n); - zend_get_gc_buffer_add_zvals(gc_buffer, inner_table, inner_n); - if (inner_ht) { - zend_get_gc_buffer_add_ht(gc_buffer, inner_ht); - } + if (object->inner.iterator) { + zend_get_gc_buffer_add_obj(gc_buffer, &object->inner.iterator->std); } zend_get_gc_buffer_add_zval(gc_buffer, &object->current.data);