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
This commit is contained in:
Richard Henderson 2019-04-30 09:49:55 -04:00 committed by Lioncash
parent 2479bbd3b2
commit bca82cde84
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
10 changed files with 33 additions and 34 deletions

View file

@ -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

View file

@ -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 */

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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,

View file

@ -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,

View file

@ -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

View file

@ -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)

View file

@ -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)