diff --git a/qemu/tcg/tcg.c b/qemu/tcg/tcg.c index dd8d1ac3..92b425ae 100644 --- a/qemu/tcg/tcg.c +++ b/qemu/tcg/tcg.c @@ -504,6 +504,7 @@ void tcg_func_start(TCGContext *s) /* No temps have been previously allocated for size or locality. */ memset(s->free_temps, 0, sizeof(s->free_temps)); + s->nb_ops = 0; s->nb_labels = 0; s->current_frame_offset = s->frame_start; @@ -1677,6 +1678,7 @@ void tcg_op_remove(TCGContext *s, TCGOp *op) { QTAILQ_REMOVE(&s->ops, op, link); QTAILQ_INSERT_TAIL(&s->free_ops, op, link); + s->nb_ops--; #ifdef CONFIG_PROFILER atomic_set(&s->prof.del_op_count, s->prof.del_op_count + 1); @@ -1695,6 +1697,7 @@ static TCGOp *tcg_op_alloc(TCGContext *s, TCGOpcode opc) } memset(op, 0, offsetof(TCGOp, link)); op->opc = opc; + s->nb_ops++; return op; } diff --git a/qemu/tcg/tcg.h b/qemu/tcg/tcg.h index 2388974d..12d5bd59 100644 --- a/qemu/tcg/tcg.h +++ b/qemu/tcg/tcg.h @@ -723,6 +723,7 @@ struct TCGContext { int nb_globals; int nb_temps; int nb_indirects; + int nb_ops; /* goto_tb support */ tcg_insn_unit *code_buf; @@ -1055,7 +1056,12 @@ static inline TCGOp *tcg_last_op(TCGContext *tcg_ctx) /* Test for whether to terminate the TB for using too many opcodes. */ static inline bool tcg_op_buf_full(TCGContext *tcg_ctx) { - return false; + /* This is not a hard limit, it merely stops translation when + * we have produced "enough" opcodes. We want to limit TB size + * such that a RISC host can reasonably use a 16-bit signed + * branch within the TB. + */ + return tcg_ctx->nb_ops >= 8000; } TCGTemp *tcg_global_mem_new_internal(TCGContext *s, TCGType type, TCGv_ptr base,