Improving string builder growth and host allocator tracing. (#14557)
Differentiated tracing makes it easier to track reallocs and it
highlighted some inefficient growth. String building should never be on
a critical path in a real app but it's still better to avoid the silly
reallocs.
diff --git a/runtime/src/iree/base/allocator.c b/runtime/src/iree/base/allocator.c
index df537bb..c162dd2 100644
--- a/runtime/src/iree/base/allocator.c
+++ b/runtime/src/iree/base/allocator.c
@@ -78,9 +78,22 @@
"allocations must be >0 bytes");
}
- IREE_TRACE_ZONE_BEGIN(z0);
-
void* existing_ptr = *inout_ptr;
+
+ IREE_TRACE(iree_zone_id_t z0 = 0);
+ IREE_TRACE({
+ if (existing_ptr && command == IREE_ALLOCATOR_COMMAND_REALLOC) {
+ IREE_TRACE_ZONE_BEGIN_NAMED(z0_named, "iree_allocator_system_realloc");
+ z0 = z0_named;
+ } else if (command == IREE_ALLOCATOR_COMMAND_CALLOC) {
+ IREE_TRACE_ZONE_BEGIN_NAMED(z0_named, "iree_allocator_system_calloc");
+ z0 = z0_named;
+ } else {
+ IREE_TRACE_ZONE_BEGIN_NAMED(z0_named, "iree_allocator_system_malloc");
+ z0 = z0_named;
+ }
+ });
+
void* new_ptr = NULL;
if (existing_ptr && command == IREE_ALLOCATOR_COMMAND_REALLOC) {
new_ptr = realloc(existing_ptr, byte_length);
@@ -103,7 +116,7 @@
IREE_TRACE_ALLOC(new_ptr, byte_length);
*inout_ptr = new_ptr;
- IREE_TRACE_ZONE_END(z0);
+ IREE_TRACE(IREE_TRACE_ZONE_END(z0));
return iree_ok_status();
}
diff --git a/runtime/src/iree/base/string_builder.c b/runtime/src/iree/base/string_builder.c
index 2aa6994..3056ae4 100644
--- a/runtime/src/iree/base/string_builder.c
+++ b/runtime/src/iree/base/string_builder.c
@@ -79,23 +79,24 @@
IREE_API_EXPORT iree_status_t iree_string_builder_reserve(
iree_string_builder_t* builder, iree_host_size_t minimum_capacity) {
- iree_host_size_t new_capacity = builder->capacity;
- if (builder->capacity < minimum_capacity) {
- new_capacity =
- iree_host_align(minimum_capacity, IREE_STRING_BUILDER_ALIGNMENT);
- }
- if (builder->capacity >= new_capacity) {
+ if (IREE_LIKELY(builder->capacity >= minimum_capacity)) {
// Already at/above the requested minimum capacity.
return iree_ok_status();
- } else if (iree_allocator_is_null(builder->allocator)) {
- // No allocator provided and the builder cannot grow.
+ }
+
+ // If no allocator was provided the builder cannot grow.
+ if (iree_allocator_is_null(builder->allocator)) {
return iree_make_status(
IREE_STATUS_RESOURCE_EXHAUSTED,
"non-growable builder capacity exceeded (capacity=%" PRIhsz
- "; requested=%" PRIhsz ", adjusted=%" PRIhsz ")",
- builder->capacity, minimum_capacity, new_capacity);
+ "; requested>=%" PRIhsz ")",
+ builder->capacity, minimum_capacity);
}
+ // Grow by 2x. Note that the current capacity may be zero.
+ iree_host_size_t new_capacity = iree_max(
+ builder->capacity * 2,
+ iree_host_align(minimum_capacity, IREE_STRING_BUILDER_ALIGNMENT));
IREE_RETURN_IF_ERROR(iree_allocator_realloc(builder->allocator, new_capacity,
(void**)&builder->buffer));
builder->buffer[builder->size] = 0;