Commit 8b86d6d2 authored by Richard Henderson's avatar Richard Henderson
Browse files

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.

Reviewed-by: default avatarAlistair Francis <alistair.francis@wdc.com>
Reviewed-by: default avatarPhilippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
parent 464c2969
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -1674,7 +1674,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
    tb_page_addr_t phys_pc, phys_page2;
    target_ulong virt_page2;
    tcg_insn_unit *gen_code_buf;
    int gen_code_size, search_size;
    int gen_code_size, search_size, max_insns;
#ifdef CONFIG_PROFILER
    TCGProfile *prof = &tcg_ctx->prof;
    int64_t ti;
@@ -1692,6 +1692,17 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
    cflags &= ~CF_CLUSTER_MASK;
    cflags |= cpu->cluster_index << CF_CLUSTER_SHIFT;

    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;
    }
    if (cpu->singlestep_enabled || singlestep) {
        max_insns = 1;
    }

 buffer_overflow:
    tb = tb_alloc(pc);
    if (unlikely(!tb)) {
@@ -1721,7 +1732,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;

    trace_translate_block(tb, tb->pc, tb->tc.ptr);
+2 −13
Original line number Diff line number Diff line
@@ -32,7 +32,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;

@@ -42,20 +42,9 @@ 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;

    /* 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;
    }
    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 */

+2 −2
Original line number Diff line number Diff line
@@ -40,8 +40,8 @@ typedef ram_addr_t tb_page_addr_t;

#include "qemu/log.h"

void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb);
void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb,
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns);
void restore_state_to_opc(CPUArchState *env, TranslationBlock *tb,
                          target_ulong *data);

void cpu_gen_init(void);
+2 −1
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@ typedef struct TranslatorOps {
 * @db: Disassembly context.
 * @cpu: Target vCPU.
 * @tb: Translation block.
 * @max_insns: Maximum number of insns to translate.
 *
 * Generic translator loop.
 *
@@ -137,7 +138,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);

+2 −2
Original line number Diff line number Diff line
@@ -3049,10 +3049,10 @@ static const TranslatorOps alpha_tr_ops = {
    .disas_log          = alpha_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(&alpha_tr_ops, &dc.base, cpu, tb);
    translator_loop(&alpha_tr_ops, &dc.base, cpu, tb, max_insns);
}

void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb,
Loading