diff options
Diffstat (limited to 'exec.c')
-rw-r--r-- | exec.c | 55 |
1 files changed, 55 insertions, 0 deletions
@@ -128,6 +128,11 @@ char *logfilename = "/tmp/qemu.log"; FILE *logfile; int loglevel; +/* statistics */ +static int tlb_flush_count; +static int tb_flush_count; +static int tb_phys_invalidate_count; + static void page_init(void) { /* NOTE: we can always suppose that qemu_host_page_size >= @@ -336,6 +341,7 @@ void tb_flush(CPUState *env) code_gen_ptr = code_gen_buffer; /* XXX: flush processor icache at this point if cache flush is expensive */ + tb_flush_count++; } #ifdef DEBUG_TB_CHECK @@ -530,6 +536,7 @@ static inline void tb_phys_invalidate(TranslationBlock *tb, unsigned int page_ad } tb_invalidate(tb); + tb_phys_invalidate_count++; } static inline void set_bits(uint8_t *tab, int start, int len) @@ -1298,6 +1305,7 @@ void tlb_flush(CPUState *env, int flush_global) #if !defined(CONFIG_SOFTMMU) munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START); #endif + tlb_flush_count++; } static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr) @@ -2137,6 +2145,53 @@ int cpu_memory_rw_debug(CPUState *env, target_ulong addr, return 0; } +void dump_exec_info(FILE *f, + int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) +{ + int i, target_code_size, max_target_code_size; + int direct_jmp_count, direct_jmp2_count, cross_page; + TranslationBlock *tb; + + target_code_size = 0; + max_target_code_size = 0; + cross_page = 0; + direct_jmp_count = 0; + direct_jmp2_count = 0; + for(i = 0; i < nb_tbs; i++) { + tb = &tbs[i]; + target_code_size += tb->size; + if (tb->size > max_target_code_size) + max_target_code_size = tb->size; + if (tb->page_addr[1] != -1) + cross_page++; + if (tb->tb_next_offset[0] != 0xffff) { + direct_jmp_count++; + if (tb->tb_next_offset[1] != 0xffff) { + direct_jmp2_count++; + } + } + } + /* XXX: avoid using doubles ? */ + cpu_fprintf(f, "TB count %d\n", nb_tbs); + cpu_fprintf(f, "TB avg target size %d max=%d bytes\n", + nb_tbs ? target_code_size / nb_tbs : 0, + max_target_code_size); + cpu_fprintf(f, "TB avg host size %d bytes (expansion ratio: %0.1f)\n", + nb_tbs ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0, + target_code_size ? (double) (code_gen_ptr - code_gen_buffer) / target_code_size : 0); + cpu_fprintf(f, "cross page TB count %d (%d%%)\n", + cross_page, + nb_tbs ? (cross_page * 100) / nb_tbs : 0); + cpu_fprintf(f, "direct jump count %d (%d%%) (2 jumps=%d %d%%)\n", + direct_jmp_count, + nb_tbs ? (direct_jmp_count * 100) / nb_tbs : 0, + direct_jmp2_count, + nb_tbs ? (direct_jmp2_count * 100) / nb_tbs : 0); + cpu_fprintf(f, "TB flush count %d\n", tb_flush_count); + cpu_fprintf(f, "TB invalidate count %d\n", tb_phys_invalidate_count); + cpu_fprintf(f, "TLB flush count %d\n", tlb_flush_count); +} + #if !defined(CONFIG_USER_ONLY) #define MMUSUFFIX _cmmu |