From ce0dfbeaadee82ffae390e4515433d3b6b1e0084 Mon Sep 17 00:00:00 2001 From: Markus Metzger Date: Tue, 24 Jun 2014 14:25:50 +0200 Subject: [PATCH] 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) : 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. --- gdb/ChangeLog | 10 ++++++++ gdb/btrace.c | 68 +++-------------------------------------------------- gdb/btrace.h | 3 --- gdb/record-btrace.c | 45 ++++++++++++++++++++++++++++++++--- 4 files changed, 55 insertions(+), 71 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 68c55c1..09a675f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2015-03-03 Markus Metzger + + * btrace.h (btrace_function) : 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 * infrun.c (follow_exec): Delete all threads of the process except diff --git a/gdb/btrace.c b/gdb/btrace.c index 206e692..c5d3ee1 100644 --- a/gdb/btrace.c +++ b/gdb/btrace.c @@ -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) diff --git a/gdb/btrace.h b/gdb/btrace.h index 0ddd4c1..36bf500 100644 --- a/gdb/btrace.h +++ b/gdb/btrace.h @@ -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; }; diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index 35c775a..af7b65f 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -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; -- 2.7.4