This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 1/2] btrace: only search for lines in current symtab


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  <markus.t.metzger@intel.com>

	* btrace.h (btrace_function)<symtab>: 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 = "<unknown>";
 
@@ -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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]