Commit e3db7226b411d767b9a3ac8e0d88f5cbd5782349
1 parent
d79284e0
JIT statistics
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1244 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
67 additions
and
2 deletions
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 */ | ... | ... |
exec.c
... | ... | @@ -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 | ... | ... |