cpu: Move tb_jmp_cache field from CPU_COMMON to CPUState

Clear it on reset.

Signed-off-by: Andreas Färber <afaerber@suse.de>
This commit is contained in:
Andreas Färber 2013-08-26 06:03:38 +02:00
parent 28ecfd7a62
commit 8cd70437f3
6 changed files with 16 additions and 16 deletions

View file

@ -118,6 +118,7 @@ static TranslationBlock *tb_find_slow(CPUArchState *env,
target_ulong cs_base, target_ulong cs_base,
uint64_t flags) uint64_t flags)
{ {
CPUState *cpu = ENV_GET_CPU(env);
TranslationBlock *tb, **ptb1; TranslationBlock *tb, **ptb1;
unsigned int h; unsigned int h;
tb_page_addr_t phys_pc, phys_page1; tb_page_addr_t phys_pc, phys_page1;
@ -165,12 +166,13 @@ static TranslationBlock *tb_find_slow(CPUArchState *env,
tcg_ctx.tb_ctx.tb_phys_hash[h] = tb; tcg_ctx.tb_ctx.tb_phys_hash[h] = tb;
} }
/* we add the TB in the virtual pc hash table */ /* we add the TB in the virtual pc hash table */
env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb; cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
return tb; return tb;
} }
static inline TranslationBlock *tb_find_fast(CPUArchState *env) static inline TranslationBlock *tb_find_fast(CPUArchState *env)
{ {
CPUState *cpu = ENV_GET_CPU(env);
TranslationBlock *tb; TranslationBlock *tb;
target_ulong cs_base, pc; target_ulong cs_base, pc;
int flags; int flags;
@ -179,7 +181,7 @@ static inline TranslationBlock *tb_find_fast(CPUArchState *env)
always be the same before a given translated block always be the same before a given translated block
is executed. */ is executed. */
cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags); cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]; tb = cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base || if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
tb->flags != flags)) { tb->flags != flags)) {
tb = tb_find_slow(env, pc, cs_base, flags); tb = tb_find_slow(env, pc, cs_base, flags);

View file

@ -58,7 +58,7 @@ void tlb_flush(CPUArchState *env, int flush_global)
cpu->current_tb = NULL; cpu->current_tb = NULL;
memset(env->tlb_table, -1, sizeof(env->tlb_table)); memset(env->tlb_table, -1, sizeof(env->tlb_table));
memset(env->tb_jmp_cache, 0, sizeof(env->tb_jmp_cache)); memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache));
env->tlb_flush_addr = -1; env->tlb_flush_addr = -1;
env->tlb_flush_mask = 0; env->tlb_flush_mask = 0;

View file

@ -61,9 +61,6 @@ typedef uint64_t target_ulong;
#define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) */ #define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) */
#define EXCP_YIELD 0x10004 /* cpu wants to yield timeslice to another */ #define EXCP_YIELD 0x10004 /* cpu wants to yield timeslice to another */
#define TB_JMP_CACHE_BITS 12
#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
/* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for /* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for
addresses on the same page. The top bits are the same. This allows addresses on the same page. The top bits are the same. This allows
TLB invalidation to quickly clear a subset of the hash table. */ TLB invalidation to quickly clear a subset of the hash table. */
@ -135,7 +132,6 @@ typedef struct CPUWatchpoint {
#define CPU_COMMON \ #define CPU_COMMON \
/* soft mmu support */ \ /* soft mmu support */ \
CPU_COMMON_TLB \ CPU_COMMON_TLB \
struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \
\ \
/* from this point: preserved by CPU reset */ \ /* from this point: preserved by CPU reset */ \
/* ice debug support */ \ /* ice debug support */ \

View file

@ -153,6 +153,9 @@ typedef struct icount_decr_u16 {
struct KVMState; struct KVMState;
struct kvm_run; struct kvm_run;
#define TB_JMP_CACHE_BITS 12
#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
/** /**
* CPUState: * CPUState:
* @cpu_index: CPU index (informative). * @cpu_index: CPU index (informative).
@ -219,6 +222,7 @@ struct CPUState {
void *env_ptr; /* CPUArchState */ void *env_ptr; /* CPUArchState */
struct TranslationBlock *current_tb; struct TranslationBlock *current_tb;
struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];
struct GDBRegisterState *gdb_regs; struct GDBRegisterState *gdb_regs;
int gdb_num_regs; int gdb_num_regs;
int gdb_num_g_regs; int gdb_num_g_regs;

View file

@ -244,6 +244,7 @@ static void cpu_common_reset(CPUState *cpu)
cpu->icount_extra = 0; cpu->icount_extra = 0;
cpu->icount_decr.u32 = 0; cpu->icount_decr.u32 = 0;
cpu->can_do_io = 0; cpu->can_do_io = 0;
memset(cpu->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof(void *));
} }
static bool cpu_common_has_work(CPUState *cs) static bool cpu_common_has_work(CPUState *cs)

View file

@ -704,9 +704,7 @@ void tb_flush(CPUArchState *env1)
tcg_ctx.tb_ctx.nb_tbs = 0; tcg_ctx.tb_ctx.nb_tbs = 0;
CPU_FOREACH(cpu) { CPU_FOREACH(cpu) {
CPUArchState *env = cpu->env_ptr; memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache));
memset(env->tb_jmp_cache, 0, sizeof(env->tb_jmp_cache));
} }
memset(tcg_ctx.tb_ctx.tb_phys_hash, 0, sizeof(tcg_ctx.tb_ctx.tb_phys_hash)); memset(tcg_ctx.tb_ctx.tb_phys_hash, 0, sizeof(tcg_ctx.tb_ctx.tb_phys_hash));
@ -857,10 +855,8 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
/* remove the TB from the hash list */ /* remove the TB from the hash list */
h = tb_jmp_cache_hash_func(tb->pc); h = tb_jmp_cache_hash_func(tb->pc);
CPU_FOREACH(cpu) { CPU_FOREACH(cpu) {
CPUArchState *env = cpu->env_ptr; if (cpu->tb_jmp_cache[h] == tb) {
cpu->tb_jmp_cache[h] = NULL;
if (env->tb_jmp_cache[h] == tb) {
env->tb_jmp_cache[h] = NULL;
} }
} }
@ -1484,16 +1480,17 @@ void cpu_io_recompile(CPUArchState *env, uintptr_t retaddr)
void tb_flush_jmp_cache(CPUArchState *env, target_ulong addr) void tb_flush_jmp_cache(CPUArchState *env, target_ulong addr)
{ {
CPUState *cpu = ENV_GET_CPU(env);
unsigned int i; unsigned int i;
/* Discard jump cache entries for any tb which might potentially /* Discard jump cache entries for any tb which might potentially
overlap the flushed page. */ overlap the flushed page. */
i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE); i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE);
memset(&env->tb_jmp_cache[i], 0, memset(&cpu->tb_jmp_cache[i], 0,
TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *)); TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
i = tb_jmp_cache_hash_page(addr); i = tb_jmp_cache_hash_page(addr);
memset(&env->tb_jmp_cache[i], 0, memset(&cpu->tb_jmp_cache[i], 0,
TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *)); TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
} }