From bca82cde848c0994c309ac033b60cd98d779506e Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 30 Apr 2019 09:49:55 -0400 Subject: [PATCH] tcg: Hoist max_insns computation to tb_gen_code In order to handle TB's that translate to too much code, we need to place the control of the length of the translation in the hands of the code gen master loop. Backports commit 8b86d6d25807e13a63ab6ea879f976b9f18cc45a from qemu --- qemu/accel/tcg/translate-all.c | 22 ++++++++++++++++------ qemu/accel/tcg/translator.c | 16 ++-------------- qemu/include/exec/exec-all.h | 2 +- qemu/include/exec/translator.h | 3 ++- qemu/target/arm/translate.c | 4 ++-- qemu/target/i386/translate.c | 4 ++-- qemu/target/m68k/translate.c | 4 ++-- qemu/target/mips/translate.c | 4 ++-- qemu/target/riscv/translate.c | 4 ++-- qemu/target/sparc/translate.c | 4 ++-- 10 files changed, 33 insertions(+), 34 deletions(-) diff --git a/qemu/accel/tcg/translate-all.c b/qemu/accel/tcg/translate-all.c index 3f476503..97ac88ae 100644 --- a/qemu/accel/tcg/translate-all.c +++ b/qemu/accel/tcg/translate-all.c @@ -1325,16 +1325,26 @@ TranslationBlock *tb_gen_code(CPUState *cpu, TranslationBlock *tb; tb_page_addr_t phys_pc, phys_page2; tcg_insn_unit *gen_code_buf; - int gen_code_size, search_size; + int gen_code_size, search_size, max_insns; #ifdef CONFIG_PROFILER int64_t ti; #endif phys_pc = get_page_addr_code(env, pc); - /* UNICORN: Commented out - if (use_icount) { - cflags |= CF_USE_ICOUNT; - }*/ + + /* Instruction counting */ + max_insns = cflags & CF_COUNT_MASK; + if (max_insns == 0) { + max_insns = CF_COUNT_MASK; + } + if (max_insns > TCG_MAX_INSNS) { + max_insns = TCG_MAX_INSNS; + } + // Unicorn: commented out + if (cpu->singlestep_enabled /*|| singlestep*/) { + max_insns = 1; + } + tb = tb_alloc(env->uc, pc); if (unlikely(!tb)) { buffer_overflow: @@ -1360,7 +1370,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, tcg_func_start(tcg_ctx); tcg_ctx->cpu = ENV_GET_CPU(env); - gen_intermediate_code(cpu, tb); + gen_intermediate_code(cpu, tb, max_insns); tcg_ctx->cpu = NULL; // Unicorn: FIXME: Needs to be amended to work with new TCG diff --git a/qemu/accel/tcg/translator.c b/qemu/accel/tcg/translator.c index 641e2330..d9eea7a7 100644 --- a/qemu/accel/tcg/translator.c +++ b/qemu/accel/tcg/translator.c @@ -30,7 +30,7 @@ void translator_loop_temp_check(DisasContextBase *db) } void translator_loop(const TranslatorOps *ops, DisasContextBase *db, - CPUState *cpu, TranslationBlock *tb) + CPUState *cpu, TranslationBlock *tb, int max_insns) { int bp_insn = 0; TCGContext *tcg_ctx = cpu->uc->tcg_ctx; @@ -41,24 +41,12 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db, db->pc_next = db->pc_first; db->is_jmp = DISAS_NEXT; db->num_insns = 0; + db->max_insns = max_insns; db->singlestep_enabled = cpu->singlestep_enabled; db->uc = cpu->uc; db->uc->block_full = false; - /* Instruction counting */ - db->max_insns = tb_cflags(db->tb) & CF_COUNT_MASK; - if (db->max_insns == 0) { - db->max_insns = CF_COUNT_MASK; - } - if (db->max_insns > TCG_MAX_INSNS) { - db->max_insns = TCG_MAX_INSNS; - } - // Unicorn: commented out - if (db->singlestep_enabled /*|| singlestep*/) { - db->max_insns = 1; - } - ops->init_disas_context(db, cpu); tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */ diff --git a/qemu/include/exec/exec-all.h b/qemu/include/exec/exec-all.h index 96a6e355..af92746d 100644 --- a/qemu/include/exec/exec-all.h +++ b/qemu/include/exec/exec-all.h @@ -39,7 +39,7 @@ typedef ram_addr_t tb_page_addr_t; #include "qemu/log.h" -void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb); +void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns); void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb, target_ulong *data); diff --git a/qemu/include/exec/translator.h b/qemu/include/exec/translator.h index 73307238..1714c51b 100644 --- a/qemu/include/exec/translator.h +++ b/qemu/include/exec/translator.h @@ -126,6 +126,7 @@ typedef struct TranslatorOps { * @db: Disassembly context. * @cpu: Target vCPU. * @tb: Translation block. + * @max_insns: Maximum number of insns to translate. * * Generic translator loop. * @@ -140,7 +141,7 @@ typedef struct TranslatorOps { * - When too many instructions have been translated. */ void translator_loop(const TranslatorOps *ops, DisasContextBase *db, - CPUState *cpu, TranslationBlock *tb); + CPUState *cpu, TranslationBlock *tb, int max_insns); void translator_loop_temp_check(DisasContextBase *db); diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index d36fbefe..bc739dfd 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -13959,7 +13959,7 @@ static const TranslatorOps thumb_translator_ops = { }; /* generate intermediate code for basic block 'tb'. */ -void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb) +void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns) { DisasContext dc; const TranslatorOps *ops = &arm_translator_ops; @@ -13973,7 +13973,7 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb) } #endif - translator_loop(ops, &dc.base, cpu, tb); + translator_loop(ops, &dc.base, cpu, tb, max_insns); } #if 0 diff --git a/qemu/target/i386/translate.c b/qemu/target/i386/translate.c index 45865605..b8904675 100644 --- a/qemu/target/i386/translate.c +++ b/qemu/target/i386/translate.c @@ -9241,11 +9241,11 @@ static const TranslatorOps i386_tr_ops = { }; /* generate intermediate code for basic block 'tb'. */ -void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb) +void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns) { DisasContext dc; - translator_loop(&i386_tr_ops, &dc.base, cpu, tb); + translator_loop(&i386_tr_ops, &dc.base, cpu, tb, max_insns); } void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, diff --git a/qemu/target/m68k/translate.c b/qemu/target/m68k/translate.c index bc2cdec3..f7a416d3 100644 --- a/qemu/target/m68k/translate.c +++ b/qemu/target/m68k/translate.c @@ -6424,10 +6424,10 @@ static const TranslatorOps m68k_tr_ops = { m68k_tr_disas_log, }; -void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb) +void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns) { DisasContext dc; - translator_loop(&m68k_tr_ops, &dc.base, cpu, tb); + translator_loop(&m68k_tr_ops, &dc.base, cpu, tb, max_insns); } void restore_state_to_opc(CPUM68KState *env, TranslationBlock *tb, diff --git a/qemu/target/mips/translate.c b/qemu/target/mips/translate.c index 591fe99f..241e95d6 100644 --- a/qemu/target/mips/translate.c +++ b/qemu/target/mips/translate.c @@ -29920,11 +29920,11 @@ static const TranslatorOps mips_tr_ops = { mips_tr_disas_log, }; -void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb) +void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb, int max_insns) { DisasContext ctx; - translator_loop(&mips_tr_ops, &ctx.base, cs, tb); + translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns); } #if 0 diff --git a/qemu/target/riscv/translate.c b/qemu/target/riscv/translate.c index 036210a6..bbd6f32f 100644 --- a/qemu/target/riscv/translate.c +++ b/qemu/target/riscv/translate.c @@ -822,11 +822,11 @@ static const TranslatorOps riscv_tr_ops = { .disas_log = riscv_tr_disas_log, }; -void gen_intermediate_code(CPUState *cs, TranslationBlock *tb) +void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) { DisasContext ctx; - translator_loop(&riscv_tr_ops, &ctx.base, cs, tb); + translator_loop(&riscv_tr_ops, &ctx.base, cs, tb, max_insns); } void riscv_translate_init(struct uc_struct *uc) diff --git a/qemu/target/sparc/translate.c b/qemu/target/sparc/translate.c index 61fa4d29..b184bb07 100644 --- a/qemu/target/sparc/translate.c +++ b/qemu/target/sparc/translate.c @@ -6048,11 +6048,11 @@ static const TranslatorOps sparc_tr_ops = { sparc_tr_disas_log, }; -void gen_intermediate_code(CPUState *cs, TranslationBlock *tb) +void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) { DisasContext dc = {{0}}; - translator_loop(&sparc_tr_ops, &dc.base, cs, tb); + translator_loop(&sparc_tr_ops, &dc.base, cs, tb, max_insns); } void sparc_tcg_init(struct uc_struct *uc)