128 |
FILE *logfile; |
FILE *logfile; |
129 |
int loglevel; |
int loglevel; |
130 |
|
|
131 |
|
/* statistics */ |
132 |
|
static int tlb_flush_count; |
133 |
|
static int tb_flush_count; |
134 |
|
static int tb_phys_invalidate_count; |
135 |
|
|
136 |
static void page_init(void) |
static void page_init(void) |
137 |
{ |
{ |
138 |
/* NOTE: we can always suppose that qemu_host_page_size >= |
/* NOTE: we can always suppose that qemu_host_page_size >= |
341 |
code_gen_ptr = code_gen_buffer; |
code_gen_ptr = code_gen_buffer; |
342 |
/* XXX: flush processor icache at this point if cache flush is |
/* XXX: flush processor icache at this point if cache flush is |
343 |
expensive */ |
expensive */ |
344 |
|
tb_flush_count++; |
345 |
} |
} |
346 |
|
|
347 |
#ifdef DEBUG_TB_CHECK |
#ifdef DEBUG_TB_CHECK |
536 |
} |
} |
537 |
|
|
538 |
tb_invalidate(tb); |
tb_invalidate(tb); |
539 |
|
tb_phys_invalidate_count++; |
540 |
} |
} |
541 |
|
|
542 |
static inline void set_bits(uint8_t *tab, int start, int len) |
static inline void set_bits(uint8_t *tab, int start, int len) |
1305 |
#if !defined(CONFIG_SOFTMMU) |
#if !defined(CONFIG_SOFTMMU) |
1306 |
munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START); |
munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START); |
1307 |
#endif |
#endif |
1308 |
|
tlb_flush_count++; |
1309 |
} |
} |
1310 |
|
|
1311 |
static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr) |
static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr) |
2145 |
return 0; |
return 0; |
2146 |
} |
} |
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 |
|
|
2195 |
#if !defined(CONFIG_USER_ONLY) |
#if !defined(CONFIG_USER_ONLY) |
2196 |
|
|
2197 |
#define MMUSUFFIX _cmmu |
#define MMUSUFFIX _cmmu |