Commit e3db7226b411d767b9a3ac8e0d88f5cbd5782349

Authored by bellard
1 parent d79284e0

JIT statistics


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1244 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-all.h
... ... @@ -742,4 +742,7 @@ static inline void cpu_physical_memory_set_dirty(target_ulong addr)
742 742  
743 743 void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end);
744 744  
  745 +void dump_exec_info(FILE *f,
  746 + int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
  747 +
745 748 #endif /* CPU_ALL_H */
... ...
... ... @@ -128,6 +128,11 @@ char *logfilename = "/tmp/qemu.log";
128 128 FILE *logfile;
129 129 int loglevel;
130 130  
  131 +/* statistics */
  132 +static int tlb_flush_count;
  133 +static int tb_flush_count;
  134 +static int tb_phys_invalidate_count;
  135 +
131 136 static void page_init(void)
132 137 {
133 138 /* NOTE: we can always suppose that qemu_host_page_size >=
... ... @@ -336,6 +341,7 @@ void tb_flush(CPUState *env)
336 341 code_gen_ptr = code_gen_buffer;
337 342 /* XXX: flush processor icache at this point if cache flush is
338 343 expensive */
  344 + tb_flush_count++;
339 345 }
340 346  
341 347 #ifdef DEBUG_TB_CHECK
... ... @@ -530,6 +536,7 @@ static inline void tb_phys_invalidate(TranslationBlock *tb, unsigned int page_ad
530 536 }
531 537  
532 538 tb_invalidate(tb);
  539 + tb_phys_invalidate_count++;
533 540 }
534 541  
535 542 static inline void set_bits(uint8_t *tab, int start, int len)
... ... @@ -1298,6 +1305,7 @@ void tlb_flush(CPUState *env, int flush_global)
1298 1305 #if !defined(CONFIG_SOFTMMU)
1299 1306 munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START);
1300 1307 #endif
  1308 + tlb_flush_count++;
1301 1309 }
1302 1310  
1303 1311 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,
2137 2145 return 0;
2138 2146 }
2139 2147  
  2148 +void dump_exec_info(FILE *f,
  2149 + int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
  2150 +{
  2151 + int i, target_code_size, max_target_code_size;
  2152 + int direct_jmp_count, direct_jmp2_count, cross_page;
  2153 + TranslationBlock *tb;
  2154 +
  2155 + target_code_size = 0;
  2156 + max_target_code_size = 0;
  2157 + cross_page = 0;
  2158 + direct_jmp_count = 0;
  2159 + direct_jmp2_count = 0;
  2160 + for(i = 0; i < nb_tbs; i++) {
  2161 + tb = &tbs[i];
  2162 + target_code_size += tb->size;
  2163 + if (tb->size > max_target_code_size)
  2164 + max_target_code_size = tb->size;
  2165 + if (tb->page_addr[1] != -1)
  2166 + cross_page++;
  2167 + if (tb->tb_next_offset[0] != 0xffff) {
  2168 + direct_jmp_count++;
  2169 + if (tb->tb_next_offset[1] != 0xffff) {
  2170 + direct_jmp2_count++;
  2171 + }
  2172 + }
  2173 + }
  2174 + /* XXX: avoid using doubles ? */
  2175 + cpu_fprintf(f, "TB count %d\n", nb_tbs);
  2176 + cpu_fprintf(f, "TB avg target size %d max=%d bytes\n",
  2177 + nb_tbs ? target_code_size / nb_tbs : 0,
  2178 + max_target_code_size);
  2179 + cpu_fprintf(f, "TB avg host size %d bytes (expansion ratio: %0.1f)\n",
  2180 + nb_tbs ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0,
  2181 + target_code_size ? (double) (code_gen_ptr - code_gen_buffer) / target_code_size : 0);
  2182 + cpu_fprintf(f, "cross page TB count %d (%d%%)\n",
  2183 + cross_page,
  2184 + nb_tbs ? (cross_page * 100) / nb_tbs : 0);
  2185 + cpu_fprintf(f, "direct jump count %d (%d%%) (2 jumps=%d %d%%)\n",
  2186 + direct_jmp_count,
  2187 + nb_tbs ? (direct_jmp_count * 100) / nb_tbs : 0,
  2188 + direct_jmp2_count,
  2189 + nb_tbs ? (direct_jmp2_count * 100) / nb_tbs : 0);
  2190 + cpu_fprintf(f, "TB flush count %d\n", tb_flush_count);
  2191 + cpu_fprintf(f, "TB invalidate count %d\n", tb_phys_invalidate_count);
  2192 + cpu_fprintf(f, "TLB flush count %d\n", tlb_flush_count);
  2193 +}
  2194 +
2140 2195 #if !defined(CONFIG_USER_ONLY)
2141 2196  
2142 2197 #define MMUSUFFIX _cmmu
... ...
monitor.c
... ... @@ -220,14 +220,19 @@ static void do_info_block(void)
220 220 static void do_info_registers(void)
221 221 {
222 222 #ifdef TARGET_I386
223   - cpu_dump_state(cpu_single_env, stdout, monitor_fprintf,
  223 + cpu_dump_state(cpu_single_env, NULL, monitor_fprintf,
224 224 X86_DUMP_FPU | X86_DUMP_CCOP);
225 225 #else
226   - cpu_dump_state(cpu_single_env, stdout, monitor_fprintf,
  226 + cpu_dump_state(cpu_single_env, NULL, monitor_fprintf,
227 227 0);
228 228 #endif
229 229 }
230 230  
  231 +static void do_info_jit(void)
  232 +{
  233 + dump_exec_info(NULL, monitor_fprintf);
  234 +}
  235 +
231 236 static void do_info_history (void)
232 237 {
233 238 int i;
... ... @@ -893,6 +898,8 @@ static term_cmd_t info_cmds[] = {
893 898 { "mem", "", mem_info,
894 899 "", "show the active virtual memory mappings", },
895 900 #endif
  901 + { "jit", "", do_info_jit,
  902 + "", "show dynamic compiler info", },
896 903 { NULL, NULL, },
897 904 };
898 905  
... ...