Commit b362e5e067835d04ddde5fb1277272d4b498b970
1 parent
d08b2a28
Speed up tlb_flush_page (Daniel Jacobowitz).
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2210 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
26 additions
and
9 deletions
cpu-defs.h
... | ... | @@ -80,6 +80,14 @@ typedef unsigned long ram_addr_t; |
80 | 80 | #define TB_JMP_CACHE_BITS 12 |
81 | 81 | #define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS) |
82 | 82 | |
83 | +/* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for | |
84 | + addresses on the same page. The top bits are the same. This allows | |
85 | + TLB invalidation to quickly clear a subset of the hash table. */ | |
86 | +#define TB_JMP_PAGE_BITS (TB_JMP_CACHE_BITS / 2) | |
87 | +#define TB_JMP_PAGE_SIZE (1 << TB_JMP_PAGE_BITS) | |
88 | +#define TB_JMP_ADDR_MASK (TB_JMP_PAGE_SIZE - 1) | |
89 | +#define TB_JMP_PAGE_MASK (TB_JMP_CACHE_SIZE - TB_JMP_PAGE_SIZE) | |
90 | + | |
83 | 91 | #define CPU_TLB_BITS 8 |
84 | 92 | #define CPU_TLB_SIZE (1 << CPU_TLB_BITS) |
85 | 93 | ... | ... |
exec-all.h
... | ... | @@ -196,9 +196,19 @@ typedef struct TranslationBlock { |
196 | 196 | struct TranslationBlock *jmp_first; |
197 | 197 | } TranslationBlock; |
198 | 198 | |
199 | +static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc) | |
200 | +{ | |
201 | + target_ulong tmp; | |
202 | + tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)); | |
203 | + return (tmp >> TB_JMP_PAGE_BITS) & TB_JMP_PAGE_MASK; | |
204 | +} | |
205 | + | |
199 | 206 | static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc) |
200 | 207 | { |
201 | - return (pc ^ (pc >> TB_JMP_CACHE_BITS)) & (TB_JMP_CACHE_SIZE - 1); | |
208 | + target_ulong tmp; | |
209 | + tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)); | |
210 | + return (((tmp >> TB_JMP_PAGE_BITS) & TB_JMP_PAGE_MASK) | | |
211 | + (tmp & TB_JMP_ADDR_MASK)); | |
202 | 212 | } |
203 | 213 | |
204 | 214 | static inline unsigned int tb_phys_hash_func(unsigned long pc) | ... | ... |
exec.c
... | ... | @@ -1288,14 +1288,13 @@ void tlb_flush_page(CPUState *env, target_ulong addr) |
1288 | 1288 | tlb_flush_entry(&env->tlb_table[0][i], addr); |
1289 | 1289 | tlb_flush_entry(&env->tlb_table[1][i], addr); |
1290 | 1290 | |
1291 | - for(i = 0; i < TB_JMP_CACHE_SIZE; i++) { | |
1292 | - tb = env->tb_jmp_cache[i]; | |
1293 | - if (tb && | |
1294 | - ((tb->pc & TARGET_PAGE_MASK) == addr || | |
1295 | - ((tb->pc + tb->size - 1) & TARGET_PAGE_MASK) == addr)) { | |
1296 | - env->tb_jmp_cache[i] = NULL; | |
1297 | - } | |
1298 | - } | |
1291 | + /* Discard jump cache entries for any tb which might potentially | |
1292 | + overlap the flushed page. */ | |
1293 | + i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE); | |
1294 | + memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb)); | |
1295 | + | |
1296 | + i = tb_jmp_cache_hash_page(addr); | |
1297 | + memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb)); | |
1299 | 1298 | |
1300 | 1299 | #if !defined(CONFIG_SOFTMMU) |
1301 | 1300 | if (addr < MMAP_AREA_END) | ... | ... |