aboutsummaryrefslogtreecommitdiff
path: root/tcg/tcg.c
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/tcg.c
parent653b87eb36045b506b79f0bb433016ef1c54bc9a (diff)
downloadqemu-ae30e86661b0f48562cd95918d37cbeec5d02262.zip
qemu-ae30e86661b0f48562cd95918d37cbeec5d02262.tar.gz
qemu-ae30e86661b0f48562cd95918d37cbeec5d02262.tar.bz2
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/tcg.c')
-rw-r--r--tcg/tcg.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 67b08f7..9e1b0d7 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;