summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-04-24 18:59:13 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-04-27 10:48:22 +0200
commit48a34bc1202e9664121c9e9aa004c79ac71af3f5 (patch)
tree84d112e40324b30d72a7d604b7914d4fb7a94f47 /ext
parent41c7d28c113d1c8e9c98cc834e8479f8567e5e3a (diff)
downloadphp-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.c18
-rw-r--r--ext/spl/spl_observer.c22
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++], &current->data);
+ zend_get_gc_buffer_add_zval(gc_buffer, &current->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);
}
/* }}} */