From b125f9dc7bd68cd4c57189db4da83b0620b28a72 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 22 Sep 2015 13:01:15 -0700 Subject: 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 Signed-off-by: Richard Henderson --- tcg/tcg.c | 14 +++++++++++--- tcg/tcg.h | 5 +++-- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'tcg') diff --git a/tcg/tcg.c b/tcg/tcg.c index 5609108..682af8a 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); diff --git a/tcg/tcg.h b/tcg/tcg.h index 5fbbd15..a696922 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -559,10 +559,11 @@ struct TCGContext { void *code_gen_prologue; void *code_gen_buffer; size_t code_gen_buffer_size; - /* threshold to flush the translated code buffer */ - size_t code_gen_buffer_max_size; void *code_gen_ptr; + /* Threshold to flush the translated code buffer. */ + void *code_gen_highwater; + TBContext tb_ctx; /* The TCGBackendData structure is private to tcg-target.c. */ -- cgit v1.1