diff options
| author | Richard Henderson <rth@twiddle.net> | 2015-09-22 13:01:15 -0700 |
|---|---|---|
| committer | Richard Henderson <rth@twiddle.net> | 2015-10-07 20:36:53 +1100 |
| commit | b125f9dc7bd68cd4c57189db4da83b0620b28a72 (patch) | |
| tree | 8d2b7a06e64121738343a3abebb5070b64f4ff21 /tcg/tcg.c | |
| parent | f293709c6af7a65a9bcec09cdba7a60183657a3e (diff) | |
| download | focaccia-qemu-b125f9dc7bd68cd4c57189db4da83b0620b28a72.tar.gz focaccia-qemu-b125f9dc7bd68cd4c57189db4da83b0620b28a72.zip | |
tcg: Check for overflow via highwater mark
We currently pre-compute an worst case code size for any TB, which works out to be 122kB. Since the average TB size is near 1kB, this wastes quite a lot of storage. Instead, check for overflow in between generating code for each opcode. The overhead of the check isn't measurable and wastage is minimized. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'tcg/tcg.c')
| -rw-r--r-- | tcg/tcg.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/tcg/tcg.c b/tcg/tcg.c index 56091087a4..682af8a7c6 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -385,9 +385,10 @@ void tcg_prologue_init(TCGContext *s) total_size = s->code_gen_buffer_size - prologue_size; s->code_gen_buffer_size = total_size; - /* Compute a high-water mark, at which we voluntarily flush the - buffer and start over. */ - s->code_gen_buffer_max_size = total_size - TCG_MAX_OP_SIZE * OPC_BUF_SIZE; + /* Compute a high-water mark, at which we voluntarily flush the buffer + and start over. The size here is arbitrary, significantly larger + than we expect the code generation for any one opcode to require. */ + s->code_gen_highwater = s->code_gen_buffer + (total_size - 1024); tcg_register_jit(s->code_gen_buffer, total_size); @@ -2438,6 +2439,13 @@ int tcg_gen_code(TCGContext *s, tcg_insn_unit *gen_code_buf) #ifndef NDEBUG check_regs(s); #endif + /* Test for (pending) buffer overflow. The assumption is that any + one operation beginning below the high water mark cannot overrun + the buffer completely. Thus we can test for overflow after + generating code without having to check during generation. */ + if (unlikely(s->code_gen_ptr > s->code_gen_highwater)) { + return -1; + } } tcg_debug_assert(num_insns >= 0); s->gen_insn_end_off[num_insns] = tcg_current_code_size(s); |