From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10493 invoked by alias); 7 Mar 2014 08:57:51 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 10459 invoked by uid 89); 7 Mar 2014 08:57:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mga11.intel.com Received: from mga11.intel.com (HELO mga11.intel.com) (192.55.52.93) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 07 Mar 2014 08:57:49 +0000 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 07 Mar 2014 00:57:47 -0800 X-ExtLoop1: 1 Received: from irvmail001.ir.intel.com ([163.33.26.43]) by fmsmga002.fm.intel.com with ESMTP; 07 Mar 2014 00:57:46 -0800 Received: from ulvlx001.iul.intel.com (ulvlx001.iul.intel.com [172.28.207.17]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id s278vjCw020385; Fri, 7 Mar 2014 08:57:46 GMT Received: from ulvlx001.iul.intel.com (localhost [127.0.0.1]) by ulvlx001.iul.intel.com with ESMTP id s278vjWA014442; Fri, 7 Mar 2014 09:57:45 +0100 Received: (from mmetzger@localhost) by ulvlx001.iul.intel.com with œ id s278vjuR014438; Fri, 7 Mar 2014 09:57:45 +0100 From: Markus Metzger To: jan.kratochvil@redhat.com Cc: gdb-patches@sourceware.org Subject: [PATCH 1/2] btrace: only search for lines in current symtab Date: Fri, 07 Mar 2014 08:57:00 -0000 Message-Id: <1394182665-14164-2-git-send-email-markus.t.metzger@intel.com> In-Reply-To: <1394182665-14164-1-git-send-email-markus.t.metzger@intel.com> References: <1394182665-14164-1-git-send-email-markus.t.metzger@intel.com> X-IsSubscribed: yes X-SW-Source: 2014-03/txt/msg00177.txt.bz2 When computing the function trace, we lookup the line number from the PC for each instruction in the trace. This is very expensive. Instead, lookup the symtab once when we create the btrace function and then only search in the linetable for that symtab. Also use the stored symtab to print the filename. 2014-03-07 Markus Metzger * btrace.h (btrace_function): New. * btrace.c (ftrace_skip_file): Remove. (ftrace_print_filename): Use symtab. (ftrace_new_function): Update parameters. Lookup symtab. (ftrace_new_call, ftrace_new_tailcall, ftrace_new_return, ftrace_new_switch): Update parameters. (ftrace_update_function): Pass pc. (ftrace_update_lines): Only search in BFUN->SYMTAB. * record-btrace.c (btrace_call_history_src_line): Use symtab. --- gdb/btrace.c | 116 +++++++++++++++++++++++++--------------------------- gdb/btrace.h | 3 ++ gdb/record-btrace.c | 8 ++-- 3 files changed, 63 insertions(+), 64 deletions(-) diff --git a/gdb/btrace.c b/gdb/btrace.c index 601eb41..b2e34b7 100644 --- a/gdb/btrace.c +++ b/gdb/btrace.c @@ -73,13 +73,12 @@ ftrace_print_function_name (const struct btrace_function *bfun) static const char * ftrace_print_filename (const struct btrace_function *bfun) { - struct symbol *sym; + struct symtab *symtab; const char *filename; - sym = bfun->sym; - - if (sym != NULL) - filename = symtab_to_filename_for_display (sym->symtab); + symtab = bfun->symtab; + if (symtab != NULL) + filename = symtab_to_filename_for_display (symtab); else filename = ""; @@ -168,26 +167,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 (sym->symtab); - - 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. */ @@ -195,7 +174,8 @@ ftrace_skip_file (const struct btrace_function *bfun, const char *fullname) static struct btrace_function * ftrace_new_function (struct btrace_function *prev, struct minimal_symbol *mfun, - struct symbol *fun) + struct symbol *fun, + CORE_ADDR pc) { struct btrace_function *bfun; @@ -205,6 +185,11 @@ ftrace_new_function (struct btrace_function *prev, bfun->sym = fun; bfun->flow.prev = prev; + if (fun != NULL) + bfun->symtab = SYMBOL_SYMTAB (fun); + else + bfun->symtab = find_pc_symtab (pc); + /* We start with the identities of min and max, respectively. */ bfun->lbegin = INT_MAX; bfun->lend = INT_MIN; @@ -270,11 +255,12 @@ ftrace_fixup_caller (struct btrace_function *bfun, static struct btrace_function * ftrace_new_call (struct btrace_function *caller, struct minimal_symbol *mfun, - struct symbol *fun) + struct symbol *fun, + CORE_ADDR pc) { struct btrace_function *bfun; - bfun = ftrace_new_function (caller, mfun, fun); + bfun = ftrace_new_function (caller, mfun, fun, pc); bfun->up = caller; bfun->level = caller->level + 1; @@ -290,11 +276,12 @@ ftrace_new_call (struct btrace_function *caller, static struct btrace_function * ftrace_new_tailcall (struct btrace_function *caller, struct minimal_symbol *mfun, - struct symbol *fun) + struct symbol *fun, + CORE_ADDR pc) { struct btrace_function *bfun; - bfun = ftrace_new_function (caller, mfun, fun); + bfun = ftrace_new_function (caller, mfun, fun, pc); bfun->up = caller; bfun->level = caller->level + 1; bfun->flags |= BFUN_UP_LINKS_TO_TAILCALL; @@ -358,11 +345,12 @@ static struct btrace_function * ftrace_new_return (struct gdbarch *gdbarch, struct btrace_function *prev, struct minimal_symbol *mfun, - struct symbol *fun) + struct symbol *fun, + CORE_ADDR pc) { struct btrace_function *bfun, *caller; - bfun = ftrace_new_function (prev, mfun, fun); + bfun = ftrace_new_function (prev, mfun, fun, pc); /* It is important to start at PREV's caller. Otherwise, we might find PREV itself, if PREV is a recursive function. */ @@ -433,13 +421,14 @@ ftrace_new_return (struct gdbarch *gdbarch, static struct btrace_function * ftrace_new_switch (struct btrace_function *prev, struct minimal_symbol *mfun, - struct symbol *fun) + struct symbol *fun, + CORE_ADDR pc) { struct btrace_function *bfun; /* This is an unexplained function switch. The call stack will likely be wrong at this point. */ - bfun = ftrace_new_function (prev, mfun, fun); + bfun = ftrace_new_function (prev, mfun, fun, pc); /* We keep the function level. */ bfun->level = prev->level; @@ -474,7 +463,7 @@ ftrace_update_function (struct gdbarch *gdbarch, /* If we didn't have a function before, we create one. */ if (bfun == NULL) - return ftrace_new_function (bfun, mfun, fun); + return ftrace_new_function (bfun, mfun, fun, pc); /* Check the last instruction, if we have one. We do this check first, since it allows us to fill in the call stack @@ -491,7 +480,7 @@ ftrace_update_function (struct gdbarch *gdbarch, /* Check for returns. */ if (gdbarch_insn_is_ret (gdbarch, lpc)) - return ftrace_new_return (gdbarch, bfun, mfun, fun); + return ftrace_new_return (gdbarch, bfun, mfun, fun, pc); /* Check for calls. */ if (gdbarch_insn_is_call (gdbarch, lpc)) @@ -502,7 +491,7 @@ ftrace_update_function (struct gdbarch *gdbarch, /* Ignore calls to the next instruction. They are used for PIC. */ if (lpc + size != pc) - return ftrace_new_call (bfun, mfun, fun); + return ftrace_new_call (bfun, mfun, fun, pc); } } @@ -529,10 +518,10 @@ ftrace_update_function (struct gdbarch *gdbarch, /* Jumps indicate optimized tail calls. */ if (start == pc && gdbarch_insn_is_jump (gdbarch, lpc)) - return ftrace_new_tailcall (bfun, mfun, fun); + return ftrace_new_tailcall (bfun, mfun, fun, pc); } - return ftrace_new_switch (bfun, mfun, fun); + return ftrace_new_switch (bfun, mfun, fun, pc); } return bfun; @@ -543,32 +532,39 @@ ftrace_update_function (struct gdbarch *gdbarch, static void ftrace_update_lines (struct btrace_function *bfun, CORE_ADDR pc) { - struct symtab_and_line sal; - const char *fullname; + struct linetable *lines; + struct symtab *symtab; + int i; - 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; - } + symtab = bfun->symtab; + if (symtab == NULL) + return; + + lines = LINETABLE (symtab); + if (lines == NULL) + 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)) + for (i = 0; i < lines->nitems; ++i) { - DEBUG_FTRACE ("ignoring file at %s, file=%s", - core_addr_to_string_nz (pc), fullname); - return; - } + struct linetable_entry *entry; - /* Update the line range. */ - bfun->lbegin = min (bfun->lbegin, sal.line); - bfun->lend = max (bfun->lend, sal.line); + entry = &lines->item[i]; + if (entry->pc == pc) + { + int line; - if (record_debug > 1) - ftrace_debug (bfun, "update lines"); + line = entry->line; + + /* Update the line range. */ + bfun->lbegin = min (bfun->lbegin, line); + bfun->lend = max (bfun->lend, line); + + if (record_debug > 1) + ftrace_debug (bfun, "update lines"); + + break; + } + } } /* Add the instruction at PC to BFUN's instructions. */ diff --git a/gdb/btrace.h b/gdb/btrace.h index f83a80f..67ba577 100644 --- a/gdb/btrace.h +++ b/gdb/btrace.h @@ -76,6 +76,9 @@ struct btrace_function struct minimal_symbol *msym; struct symbol *sym; + /* The symbol table. May be NULL. */ + struct symtab *symtab; + /* The previous and next segment belonging to the same function. If a function calls another function, the former will have at least two segments: one before the call and another after the return. */ diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index d4c0d42..1851823 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -507,15 +507,15 @@ static void btrace_call_history_src_line (struct ui_out *uiout, const struct btrace_function *bfun) { - struct symbol *sym; + struct symtab *symtab; int begin, end; - sym = bfun->sym; - if (sym == NULL) + symtab = bfun->symtab; + if (symtab == NULL) return; ui_out_field_string (uiout, "file", - symtab_to_filename_for_display (sym->symtab)); + symtab_to_filename_for_display (symtab)); begin = bfun->lbegin; end = bfun->lend; -- 1.8.3.1