vandersonmr <vanderson...@gmail.com> writes:
> add option to dump the N most hot TB blocks. > -d hot_tbs:N > > Signed-off-by: vandersonmr <vanderson...@gmail.com> > --- > include/qemu/log-for-trace.h | 2 ++ > linux-user/exit.c | 3 +++ > util/log.c | 9 +++++++++ > 3 files changed, 14 insertions(+) > > diff --git a/include/qemu/log-for-trace.h b/include/qemu/log-for-trace.h > index 2f0a5b080e..d65eb83037 100644 > --- a/include/qemu/log-for-trace.h > +++ b/include/qemu/log-for-trace.h > @@ -21,6 +21,8 @@ > /* Private global variable, don't use */ > extern int qemu_loglevel; > > +extern int32_t max_num_hot_tbs_to_dump; > + This might as well be an int (especially as your using atoi to scan it). > #define LOG_TRACE (1 << 15) > > /* Returns true if a bit is set in the current loglevel mask */ > diff --git a/linux-user/exit.c b/linux-user/exit.c > index bdda720553..08b86dfd61 100644 > --- a/linux-user/exit.c > +++ b/linux-user/exit.c > @@ -28,6 +28,9 @@ extern void __gcov_dump(void); > > void preexit_cleanup(CPUArchState *env, int code) > { > + if (qemu_loglevel_mask(CPU_LOG_HOT_TBS)) { > + tb_dump_exec_freq(max_num_hot_tbs_to_dump); > + } Rather than baking the individual flags here and the fact you'll need to duplicate the test for system emulation why not have a common helper which you call unconditionally here and in the tail end of vl.c's main: qemu_do_exit_logs() where: void qemu_do_exit_logs(void) { if (qemu_loglevel_mask(CPU_LOG_HOT_TBS)) { tb_dump_exec_freq(max_num_hot_tbs_to_dump); } } and we can extend that for other reports later... > #ifdef TARGET_GPROF > _mcleanup(); > #endif > diff --git a/util/log.c b/util/log.c > index 1d1b33f7d9..e71c663143 100644 > --- a/util/log.c > +++ b/util/log.c > @@ -30,6 +30,7 @@ FILE *qemu_logfile; > int qemu_loglevel; > static int log_append = 0; > static GArray *debug_regions; > +int32_t max_num_hot_tbs_to_dump; > > /* Return the number of characters emitted. */ > int qemu_log(const char *fmt, ...) > @@ -273,6 +274,9 @@ const QEMULogItem qemu_log_items[] = { > { CPU_LOG_TB_NOCHAIN, "nochain", > "do not chain compiled TBs so that \"exec\" and \"cpu\" show\n" > "complete traces" }, > + { CPU_LOG_HOT_TBS, "hot_tbs(:limit)", > + "show TBs (until given a limit) ordered by their hotness.\n" > + "(if no limit is given, show all)" }, > { 0, NULL, NULL }, > }; > > @@ -294,6 +298,11 @@ int qemu_str_to_log_mask(const char *str) > trace_enable_events((*tmp) + 6); > mask |= LOG_TRACE; > #endif > + } else if (g_str_has_prefix(*tmp, "hot_tbs")) { > + if (g_str_has_prefix(*tmp, "hot_tbs:") && (*tmp)[8] != '\0') { > + max_num_hot_tbs_to_dump = atoi((*tmp) + 8); > + } > + mask |= CPU_LOG_HOT_TBS; > } else { > for (item = qemu_log_items; item->mask != 0; item++) { > if (g_str_equal(*tmp, item->name)) { -- Alex Bennée