Fixing runtime flag string lists to not grow exponentially. (#12007)
Not noticable when there's a handful of repeated flags but when there
are 100+ things get sad.
diff --git a/runtime/src/iree/base/internal/flags.c b/runtime/src/iree/base/internal/flags.c
index 1dd3246..ed35a5f 100644
--- a/runtime/src/iree/base/internal/flags.c
+++ b/runtime/src/iree/base/internal/flags.c
@@ -34,8 +34,6 @@
return status;
}
-static void iree_flags_leaky_free(void* self, void* ptr) { free(ptr); }
-
// Allocates heap memory that is leaked without triggering leak checkers.
// We do this so that we have valid memory for the lifetime of the process.
// The memory may still be freed but if not will not hurt anything (besides the
@@ -155,26 +153,29 @@
iree_string_view_t value) {
iree_flag_string_list_storage_t* flag =
(iree_flag_string_list_storage_t*)storage;
- if (flag->count == 0) {
+ if (flag->count == 0) { // currently empty
// Inline storage (common case).
flag->count = 1;
flag->inline_value = value;
- } else if (flag->count == 1) {
+ } else if (flag->count == 1) { // currently inline
// Switching from inline storage to external storage.
iree_host_size_t new_capacity = 4;
iree_string_view_t* values = NULL;
IREE_RETURN_IF_ERROR(iree_allocator_malloc(
- iree_allocator_system(), sizeof(iree_string_view_t*) * new_capacity,
+ iree_flags_leaky_allocator(), sizeof(iree_string_view_t) * new_capacity,
(void**)&values));
values[0] = flag->inline_value;
flag->capacity = new_capacity;
flag->values = values;
flag->values[flag->count++] = value;
- } else {
+ } else if (flag->count < flag->capacity) { // external storage available
+ // Stash in external storage list.
+ flag->values[flag->count++] = value;
+ } else { // external storage full
// Growing external storage list.
iree_host_size_t new_capacity = iree_max(4, flag->capacity * 2);
IREE_RETURN_IF_ERROR(iree_allocator_realloc(
- iree_allocator_system(), sizeof(iree_string_view_t*) * new_capacity,
+ iree_flags_leaky_allocator(), sizeof(iree_string_view_t) * new_capacity,
(void**)&flag->values));
flag->capacity = new_capacity;
flag->values[flag->count++] = value;
diff --git a/runtime/src/iree/base/internal/flags_test.txt b/runtime/src/iree/base/internal/flags_test.txt
index d292d5b..2fb0ac9 100644
--- a/runtime/src/iree/base/internal/flags_test.txt
+++ b/runtime/src/iree/base/internal/flags_test.txt
@@ -74,6 +74,12 @@
// FLAG-LIST-1: FLAG[test_strings] = 1: a
// RUN: ( flags_demo --test_strings=a --test_strings=b ) | FileCheck --check-prefix=FLAG-LIST-2 %s
// FLAG-LIST-2: FLAG[test_strings] = 2: a, b
+// RUN: ( flags_demo --test_strings=a --test_strings=b --test_strings=c ) | FileCheck --check-prefix=FLAG-LIST-3 %s
+// FLAG-LIST-3: FLAG[test_strings] = 3: a, b, c
+// RUN: ( flags_demo --test_strings=a --test_strings=b --test_strings=c --test_strings=d ) | FileCheck --check-prefix=FLAG-LIST-4 %s
+// FLAG-LIST-4: FLAG[test_strings] = 4: a, b, c, d
+// RUN: ( flags_demo --test_strings=a --test_strings=b --test_strings=c --test_strings=d --test_strings=e ) | FileCheck --check-prefix=FLAG-LIST-5 %s
+// FLAG-LIST-5: FLAG[test_strings] = 5: a, b, c, d, e
// RUN: ( flags_demo arg1 ) | FileCheck --check-prefix=FLAG-POSITIONAL-1 %s
// FLAG-POSITIONAL-1: ARG(1) = arg1
diff --git a/tests/transform_dialect/cpu/matmul.mlir b/tests/transform_dialect/cpu/matmul.mlir
index c6cb04b..1a99cf9 100644
--- a/tests/transform_dialect/cpu/matmul.mlir
+++ b/tests/transform_dialect/cpu/matmul.mlir
@@ -64,7 +64,7 @@
// RUN: iree-run-module --entry_function=matmul_static \
// RUN: --function_input="3x5xf32=1" \
// RUN: --function_input="5x3xf32=2" \
-// RUN: --function_input="3x3xf32=42"| \
+// RUN: --function_input="3x3xf32=42" | \
// RUN: FileCheck %s --check-prefixes=EXEC
// EXEC: 3x3xf32=[52 52 52][52 52 52][52 52 52]