diff --git a/src/util/u_dynarray.h b/src/util/u_dynarray.h index b41b0d4b032..769669e1e70 100644 --- a/src/util/u_dynarray.h +++ b/src/util/u_dynarray.h @@ -36,6 +36,8 @@ extern "C" { #endif +static unsigned util_dynarray_is_data_stack_allocated; + /* A zero-initialized version of this is guaranteed to represent an * empty array. * @@ -57,11 +59,21 @@ util_dynarray_init(struct util_dynarray *buf, void *mem_ctx) buf->mem_ctx = mem_ctx; } +static inline void +util_dynarray_init_from_stack(struct util_dynarray *buf, void *data, unsigned capacity) +{ + memset(buf, 0, sizeof(*buf)); + buf->mem_ctx = &util_dynarray_is_data_stack_allocated; + buf->data = data; + buf->capacity = capacity; +} + static inline void util_dynarray_fini(struct util_dynarray *buf) { if (buf->data) { - if (buf->mem_ctx) { + if (buf->mem_ctx == &util_dynarray_is_data_stack_allocated) { + } else if (buf->mem_ctx) { ralloc_free(buf->data); } else { free(buf->data); @@ -85,7 +97,13 @@ util_dynarray_ensure_cap(struct util_dynarray *buf, unsigned newcap) unsigned capacity = MAX3(DYN_ARRAY_INITIAL_SIZE, buf->capacity * 2, newcap); void *data; - if (buf->mem_ctx) { + if (buf->mem_ctx == &util_dynarray_is_data_stack_allocated) { + data = malloc(capacity); + if (data) { + memcpy(data, buf->data, buf->size); + buf->mem_ctx = NULL; + } + } else if (buf->mem_ctx) { data = reralloc_size(buf->mem_ctx, buf->data, capacity); } else { data = realloc(buf->data, capacity); @@ -148,6 +166,9 @@ util_dynarray_grow_bytes(struct util_dynarray *buf, unsigned ngrow, size_t eltsi static inline void util_dynarray_trim(struct util_dynarray *buf) { + if (buf->mem_ctx == &util_dynarray_is_data_stack_allocated) + return; + if (buf->size != buf->capacity) { if (buf->size) { if (buf->mem_ctx) {