aboutsummaryrefslogtreecommitdiff
path: root/tcg
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2021-01-23 12:11:17 -1000
committerRichard Henderson <richard.henderson@linaro.org>2021-01-24 08:03:27 -1000
commitae30e86661b0f48562cd95918d37cbeec5d02262 (patch)
treebd84c59f604bae6c128f02b06b4607433a13d2df /tcg
parent653b87eb36045b506b79f0bb433016ef1c54bc9a (diff)
tcg: Restart code generation when we run out of temps
Some large translation blocks can generate so many unique constants that we run out of temps to hold them. In this case, longjmp back to the start of code generation and restart with a smaller translation block. Buglink: https://bugs.launchpad.net/bugs/1912065 Tested-by: BALATON Zoltan <balaton@eik.bme.hu> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg')
-rw-r--r--tcg/tcg.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 67b08f708d..9e1b0d73c7 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1205,18 +1205,23 @@ void tcg_func_start(TCGContext *s)
QSIMPLEQ_INIT(&s->labels);
}
-static inline TCGTemp *tcg_temp_alloc(TCGContext *s)
+static TCGTemp *tcg_temp_alloc(TCGContext *s)
{
int n = s->nb_temps++;
- tcg_debug_assert(n < TCG_MAX_TEMPS);
+
+ if (n >= TCG_MAX_TEMPS) {
+ /* Signal overflow, starting over with fewer guest insns. */
+ siglongjmp(s->jmp_trans, -2);
+ }
return memset(&s->temps[n], 0, sizeof(TCGTemp));
}
-static inline TCGTemp *tcg_global_alloc(TCGContext *s)
+static TCGTemp *tcg_global_alloc(TCGContext *s)
{
TCGTemp *ts;
tcg_debug_assert(s->nb_globals == s->nb_temps);
+ tcg_debug_assert(s->nb_globals < TCG_MAX_TEMPS);
s->nb_globals++;
ts = tcg_temp_alloc(s);
ts->kind = TEMP_GLOBAL;