[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 2/2] input: Optimize macro tail-call memory usage
From: |
Eric Blake |
Subject: |
[PATCH 2/2] input: Optimize macro tail-call memory usage |
Date: |
Thu, 1 Apr 2021 18:42:53 -0500 |
I encountered an m4 program that performed over 20 million iterations
of a tail-call recursion paradigm. Without this patch, memory usage
grew to over 6 gigabytes, pausing the program for several seconds when
the recursion finally ended just to reclaim the memory. But with the
patch, m4 never needed more than 3 megabytes of resident memory.
* src/input.c (push_string_init): Prune empty string blocks before
starting another one.
---
src/input.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/input.c b/src/input.c
index 23d200bd..f8f57234 100644
--- a/src/input.c
+++ b/src/input.c
@@ -165,6 +165,9 @@ static struct re_registers regs;
#ifdef DEBUG_INPUT
static const char *token_type_string (token_type);
#endif
+
+static void pop_input (void);
+
/*-------------------------------------------------------------------.
@@ -250,6 +253,9 @@ push_string_init (void)
abort ();
}
+ /* Prefer reusing an older block, for tail-call optimization. */
+ while (isp && isp->type == INPUT_STRING && !isp->u.u_s.string[0])
+ pop_input ();
next = (input_block *) obstack_alloc (current_input,
sizeof (struct input_block));
next->type = INPUT_STRING;
--
2.31.1