diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2021-01-23 12:11:17 -1000 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2021-01-24 08:03:27 -1000 |
commit | ae30e86661b0f48562cd95918d37cbeec5d02262 (patch) | |
tree | bd84c59f604bae6c128f02b06b4607433a13d2df /tcg | |
parent | 653b87eb36045b506b79f0bb433016ef1c54bc9a (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.c | 11 |
1 files changed, 8 insertions, 3 deletions
@@ -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; |