--- src/compiler/blob.c | 24 +++++++++++++++++++++--- src/compiler/blob.h | 23 ++++++++++++++++++++++- 2 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/src/compiler/blob.c b/src/compiler/blob.c index 0b42871..59ad8a3 100644 --- a/src/compiler/blob.c +++ b/src/compiler/blob.c @@ -52,6 +52,11 @@ grow_to_fit(struct blob *blob, size_t additional) if (blob->size + additional <= blob->allocated) return true; + if (blob->fixed_allocation) { + blob->out_of_memory = true; + return false; + } + if (blob->allocated == 0) to_allocate = BLOB_INITIAL_SIZE; else @@ -86,7 +91,8 @@ align_blob(struct blob *blob, size_t alignment) if (!grow_to_fit(blob, new_size - blob->size)) return false; - memset(blob->data + blob->size, 0, new_size - blob->size); + if (blob->data) + memset(blob->data + blob->size, 0, new_size - blob->size); blob->size = new_size; } @@ -104,6 +110,16 @@ blob_init(struct blob *blob) { blob->data = NULL; blob->allocated = 0; + blob->fixed_allocation = false; + blob->size = 0; +} + +void +blob_init_fixed(struct blob *blob, void *data, size_t size) +{ + blob->data = data; + blob->allocated = size; + blob->fixed_allocation = true; blob->size = 0; } @@ -119,7 +135,8 @@ blob_overwrite_bytes(struct blob *blob, VG(VALGRIND_CHECK_MEM_IS_DEFINED(bytes, to_write)); - memcpy(blob->data + offset, bytes, to_write); + if (blob->data) + memcpy(blob->data + offset, bytes, to_write); return true; } @@ -132,7 +149,8 @@ blob_write_bytes(struct blob *blob, const void *bytes, size_t to_write) VG(VALGRIND_CHECK_MEM_IS_DEFINED(bytes, to_write)); - memcpy(blob->data + blob->size, bytes, to_write); + if (blob->data) + memcpy(blob->data + blob->size, bytes, to_write); blob->size += to_write; return true; diff --git a/src/compiler/blob.h b/src/compiler/blob.h index fd13a16..1ef6d99 100644 --- a/src/compiler/blob.h +++ b/src/compiler/blob.h @@ -56,6 +56,12 @@ struct blob { /** The number of bytes that have actual data written to them. */ size_t size; + /** True if \c data a fixed allocation that we cannot resize + * + * \see blob_init_fixed + */ + bool fixed_allocation; + /** * True if we've ever failed to realloc or if we go pas the end of a fixed * allocation blob. @@ -85,12 +91,27 @@ void blob_init(struct blob *blob); /** + * Init a new, fixed-size blob. + * + * A fixed-size blob has a fixed block of data that will not be freed on + * blob_finish and will never be grown. If we hit the end, we simply start + * returning false from the write functions. + * + * If a fixed-size blob has a NULL data pointer then the blob no data is + * written but it otherwise operates normally. This can be used to determine + * the size that will be required to write a given data structure. + */ +void +blob_init_fixed(struct blob *blob, void *data, size_t size); + +/** * Destroy a blob and free its memory. */ static inline void blob_finish(struct blob *blob) { - free(blob->data); + if (!blob->fixed_allocation) + free(blob->data); } /** -- 2.5.0.400.gff86faf _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev