diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-04-24 18:59:13 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-04-27 10:48:22 +0200 |
commit | 48a34bc1202e9664121c9e9aa004c79ac71af3f5 (patch) | |
tree | 84d112e40324b30d72a7d604b7914d4fb7a94f47 /ext | |
parent | 41c7d28c113d1c8e9c98cc834e8479f8567e5e3a (diff) | |
download | php-git-48a34bc1202e9664121c9e9aa004c79ac71af3f5.tar.gz |
Add helper APIs for get_gc implementations
get_gc() implementations that need to explore heterogeneous data
currently work by computing how many GC entries they need,
allocating a buffer for that and storing it on the object. This
is inefficient and wastes memory, because the buffer is retained
after the GC run.
This commit adds an API for a single global GC buffer, which can
be reused by get_gc implementations (as only one get_gc call is
ever active at the same time). The GC buffer will automatically
grow during the GC run and be discarded at the end.
Diffstat (limited to 'ext')
-rw-r--r-- | ext/spl/spl_dllist.c | 18 | ||||
-rw-r--r-- | ext/spl/spl_observer.c | 22 |
2 files changed, 7 insertions, 33 deletions
diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index 306aefa5d8..ef0e5b60ff 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -91,8 +91,6 @@ 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; }; @@ -356,10 +354,6 @@ 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); } @@ -534,21 +528,15 @@ static inline HashTable* spl_dllist_object_get_debug_info(zend_object *obj) /* { static HashTable *spl_dllist_object_get_gc(zend_object *obj, zval **gc_data, int *gc_data_count) /* {{{ */ { spl_dllist_object *intern = spl_dllist_from_obj(obj); + zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); 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); + zend_get_gc_buffer_add_zval(gc_buffer, ¤t->data); current = current->next; } - *gc_data = intern->gc_data; - *gc_data_count = i; + zend_get_gc_buffer_use(gc_buffer, gc_data, gc_data_count); return zend_std_get_properties(obj); } /* }}} */ diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index 09f27595d9..bcf3a39535 100644 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -50,8 +50,6 @@ typedef struct _spl_SplObjectStorage { /* {{{ */ HashPosition pos; zend_long flags; zend_function *fptr_get_hash; - zval *gcdata; - size_t gcdata_num; zend_object std; } spl_SplObjectStorage; /* }}} */ @@ -75,11 +73,6 @@ void spl_SplObjectStorage_free_storage(zend_object *object) /* {{{ */ zend_object_std_dtor(&intern->std); zend_hash_destroy(&intern->storage); - - if (intern->gcdata != NULL) { - efree(intern->gcdata); - } - } /* }}} */ static int spl_object_storage_get_hash(zend_hash_key *key, spl_SplObjectStorage *intern, zval *obj) { @@ -285,23 +278,16 @@ static inline HashTable* spl_object_storage_debug_info(zend_object *obj) /* {{{ /* overridden for garbage collection */ static HashTable *spl_object_storage_get_gc(zend_object *obj, zval **table, int *n) /* {{{ */ { - int i = 0; spl_SplObjectStorage *intern = spl_object_storage_from_obj(obj); spl_SplObjectStorageElement *element; - - if (intern->storage.nNumOfElements * 2 > intern->gcdata_num) { - intern->gcdata_num = intern->storage.nNumOfElements * 2; - intern->gcdata = (zval*)erealloc(intern->gcdata, sizeof(zval) * intern->gcdata_num); - } + zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); ZEND_HASH_FOREACH_PTR(&intern->storage, element) { - ZVAL_COPY_VALUE(&intern->gcdata[i++], &element->obj); - ZVAL_COPY_VALUE(&intern->gcdata[i++], &element->inf); + zend_get_gc_buffer_add_zval(gc_buffer, &element->obj); + zend_get_gc_buffer_add_zval(gc_buffer, &element->inf); } ZEND_HASH_FOREACH_END(); - *table = intern->gcdata; - *n = i; - + zend_get_gc_buffer_use(gc_buffer, table, n); return zend_std_get_properties(obj); } /* }}} */ |