btrace: compute line range when printing

The "record function-call-history" command prints the range of source lines
for a function segment when given the /l modifier.  This information is
computed for the entire execution history when processing the recorded branch
trace.

To speed up the initial trace processing, we compute the information when
we print a function segment and only if requested.  The computation is fast
enough (due to the limited scope) that it is not worth storing the data in
struct btrace_function, anymore.

gdb/
	* btrace.h (btrace_function) <lbegin, lend>: Remove.
	* btrace.c (ftrace_debug): Do not print the line range.
	(ftrace_skip_file, ftrace_update_lines): Remove.
	(ftrace_new_function): Remove lbegin and lend initialization.
	(btrace_compute_ftrace_bts): Remove call to ftrace_update_lines.
	* record-btrace.c (btrace_compute_src_line_range): New.
	(btrace_call_history_src_line): Call btrace_compute_src_line_range.
This commit is contained in:
Markus Metzger 2014-06-24 14:25:50 +02:00
parent 95e50b2723
commit ce0dfbeaad
4 changed files with 55 additions and 71 deletions

View File

@ -1,3 +1,13 @@
2015-03-03 Markus Metzger <markus.t.metzger@intel.com>
* btrace.h (btrace_function) <lbegin, lend>: Remove.
* btrace.c (ftrace_debug): Do not print the line range.
(ftrace_skip_file, ftrace_update_lines): Remove.
(ftrace_new_function): Remove lbegin and lend initialization.
(btrace_compute_ftrace_bts): Remove call to ftrace_update_lines.
* record-btrace.c (btrace_compute_src_line_range): New.
(btrace_call_history_src_line): Call btrace_compute_src_line_range.
2015-03-02 Pedro Alves <palves@redhat.com>
* infrun.c (follow_exec): Delete all threads of the process except

View File

@ -105,21 +105,17 @@ ftrace_debug (const struct btrace_function *bfun, const char *prefix)
{
const char *fun, *file;
unsigned int ibegin, iend;
int lbegin, lend, level;
int level;
fun = ftrace_print_function_name (bfun);
file = ftrace_print_filename (bfun);
level = bfun->level;
lbegin = bfun->lbegin;
lend = bfun->lend;
ibegin = bfun->insn_offset;
iend = ibegin + VEC_length (btrace_insn_s, bfun->insn);
DEBUG_FTRACE ("%s: fun = %s, file = %s, level = %d, lines = [%d; %d], "
"insn = [%u; %u)", prefix, fun, file, level, lbegin, lend,
ibegin, iend);
DEBUG_FTRACE ("%s: fun = %s, file = %s, level = %d, insn = [%u; %u)",
prefix, fun, file, level, ibegin, iend);
}
/* Return non-zero if BFUN does not match MFUN and FUN,
@ -168,26 +164,6 @@ ftrace_function_switched (const struct btrace_function *bfun,
return 0;
}
/* Return non-zero if we should skip this file when generating the function
call history, zero otherwise.
We would want to do that if, say, a macro that is defined in another file
is expanded in this function. */
static int
ftrace_skip_file (const struct btrace_function *bfun, const char *fullname)
{
struct symbol *sym;
const char *bfile;
sym = bfun->sym;
if (sym == NULL)
return 1;
bfile = symtab_to_fullname (symbol_symtab (sym));
return (filename_cmp (bfile, fullname) != 0);
}
/* Allocate and initialize a new branch trace function segment.
PREV is the chronologically preceding function segment.
MFUN and FUN are the symbol information we have for this function. */
@ -205,10 +181,6 @@ ftrace_new_function (struct btrace_function *prev,
bfun->sym = fun;
bfun->flow.prev = prev;
/* We start with the identities of min and max, respectively. */
bfun->lbegin = INT_MAX;
bfun->lend = INT_MIN;
if (prev == NULL)
{
/* Start counting at one. */
@ -543,39 +515,6 @@ ftrace_update_function (struct btrace_function *bfun, CORE_ADDR pc)
return bfun;
}
/* Update BFUN's source range with respect to the instruction at PC. */
static void
ftrace_update_lines (struct btrace_function *bfun, CORE_ADDR pc)
{
struct symtab_and_line sal;
const char *fullname;
sal = find_pc_line (pc, 0);
if (sal.symtab == NULL || sal.line == 0)
{
DEBUG_FTRACE ("no lines at %s", core_addr_to_string_nz (pc));
return;
}
/* Check if we switched files. This could happen if, say, a macro that
is defined in another file is expanded here. */
fullname = symtab_to_fullname (sal.symtab);
if (ftrace_skip_file (bfun, fullname))
{
DEBUG_FTRACE ("ignoring file at %s, file=%s",
core_addr_to_string_nz (pc), fullname);
return;
}
/* Update the line range. */
bfun->lbegin = min (bfun->lbegin, sal.line);
bfun->lend = max (bfun->lend, sal.line);
if (record_debug > 1)
ftrace_debug (bfun, "update lines");
}
/* Add the instruction at PC to BFUN's instructions. */
static void
@ -680,7 +619,6 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
insn.iclass = ftrace_classify_insn (gdbarch, pc);
ftrace_update_insns (end, &insn);
ftrace_update_lines (end, pc);
/* We're done once we pushed the instruction at the end. */
if (block->end == pc)

View File

@ -150,9 +150,6 @@ struct btrace_function
a fixup to normalize function levels so the smallest level is zero. */
int level;
/* The source line range of this function segment (both inclusive). */
int lbegin, lend;
/* A bit-vector of btrace_function_flag. */
enum btrace_function_flag flags;
};

View File

@ -721,6 +721,47 @@ btrace_call_history_insn_range (struct ui_out *uiout,
ui_out_field_uint (uiout, "insn end", end);
}
/* Compute the lowest and highest source line for the instructions in BFUN
and return them in PBEGIN and PEND.
Ignore instructions that can't be mapped to BFUN, e.g. instructions that
result from inlining or macro expansion. */
static void
btrace_compute_src_line_range (const struct btrace_function *bfun,
int *pbegin, int *pend)
{
struct btrace_insn *insn;
struct symtab *symtab;
struct symbol *sym;
unsigned int idx;
int begin, end;
begin = INT_MAX;
end = INT_MIN;
sym = bfun->sym;
if (sym == NULL)
goto out;
symtab = symbol_symtab (sym);
for (idx = 0; VEC_iterate (btrace_insn_s, bfun->insn, idx, insn); ++idx)
{
struct symtab_and_line sal;
sal = find_pc_line (insn->pc, 0);
if (sal.symtab != symtab || sal.line == 0)
continue;
begin = min (begin, sal.line);
end = max (end, sal.line);
}
out:
*pbegin = begin;
*pend = end;
}
/* Print the source line information for a function call history line. */
static void
@ -737,9 +778,7 @@ btrace_call_history_src_line (struct ui_out *uiout,
ui_out_field_string (uiout, "file",
symtab_to_filename_for_display (symbol_symtab (sym)));
begin = bfun->lbegin;
end = bfun->lend;
btrace_compute_src_line_range (bfun, &begin, &end);
if (end < begin)
return;