]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gprof: only process line numbers for intersection of vmas and histograms
authorRichard Allen <rsaxvc@gmail.com>
Sun, 16 Feb 2025 22:50:05 +0000 (16:50 -0600)
committerAlan Modra <amodra@gmail.com>
Sun, 2 Mar 2025 22:03:55 +0000 (08:33 +1030)
Some programs like RTOS firmware may have a large number of symbols.

By loading the histograms before loading symbols, we can look up
only the line numbers that were captured in the histogram file,
which reduces processing time for such a firmware from ~2 minutes
to ~2 seconds.

Signed-off-by: Richard Allen <rsaxvc@gmail.com>
gprof/corefile.c
gprof/gprof.c

index bc26bd7883e820feea761b5d16ca7b5d6a2af9c5..a8970b3200df0dc0d36ca4b6184ad2e792612115 100644 (file)
@@ -755,8 +755,9 @@ core_create_line_syms (void)
   Sym prev, *sym;
   const char *filename;
   Sym_Table ltab;
-  bfd_vma vma_high;
   size_t ltab_reserved;
+  bfd_vma bfd_vma_low = core_text_sect->vma;
+  bfd_vma bfd_vma_high = bfd_vma_low + bfd_section_size (core_text_sect);
 
   /* Create symbols for functions as usual.  This is necessary in
      cases where parts of a program were not compiled with -g.  For
@@ -786,53 +787,58 @@ core_create_line_syms (void)
      lot cleaner now.  */
   memset (&prev, 0, sizeof (prev));
 
-  vma_high = core_text_sect->vma + bfd_section_size (core_text_sect);
-  for (vma = core_text_sect->vma; vma < vma_high; vma += insn_boundary)
+  for (size_t i = 0; i < num_histograms; ++i)
     {
-      if (ltab.len >= ltab_reserved)
+      bfd_vma hist_vma_high = histograms[i].highpc;
+      bfd_vma vma_low = MAX (histograms[i].lowpc, bfd_vma_low);
+      bfd_vma vma_high = MIN (bfd_vma_high, hist_vma_high);
+      for (vma = vma_low; vma < vma_high; vma += insn_boundary)
        {
-         /* Reserve more space for line symbols.  */
-         ltab_reserved *= 2;
-         ltab.base = (Sym *) xrealloc (ltab.base, ltab_reserved * sizeof (Sym));
-         ltab.limit = ltab.base + ltab.len;
+         if (ltab.len >= ltab_reserved)
+           {
+             /* Reserve more space for line symbols.  */
+             ltab_reserved *= 2;
+             ltab.base = xrealloc (ltab.base, ltab_reserved * sizeof (Sym));
+             ltab.limit = ltab.base + ltab.len;
+           }
+         sym_init (ltab.limit);
+
+         if (!get_src_info (vma, &filename, &ltab.limit->name, &ltab.limit->line_num)
+             || (prev.name && prev.line_num == ltab.limit->line_num
+                 && strcmp (prev.name, ltab.limit->name) == 0
+                 && filename_cmp (prev.file->name, filename) == 0))
+           continue;
+
+         /* Make name pointer a malloc'ed string.  */
+         ltab.limit->name = xstrdup (ltab.limit->name);
+         ltab.limit->file = source_file_lookup_path (filename);
+
+         ltab.limit->addr = vma;
+
+         /* Set is_static based on the enclosing function, using either:
+            1) the previous symbol, if it's from the same function, or
+            2) a symtab lookup.  */
+         if (prev.name && ltab.limit->file == prev.file
+             && strcmp (ltab.limit->name, prev.name) == 0)
+           {
+             ltab.limit->is_static = prev.is_static;
+           }
+         else
+           {
+             sym = sym_lookup(&symtab, ltab.limit->addr);
+             if (sym)
+               ltab.limit->is_static = sym->is_static;
+           }
+
+         prev = *ltab.limit;
+
+         DBG (AOUTDEBUG, printf ("[core_create_line_syms] %lu %s 0x%lx\n",
+                                 (unsigned long) (ltab.limit - ltab.base),
+                                 ltab.limit->name,
+                                 (unsigned long) ltab.limit->addr));
+         ++ltab.limit;
+         ++ltab.len;
        }
-      sym_init (ltab.limit);
-
-      if (!get_src_info (vma, &filename, &ltab.limit->name, &ltab.limit->line_num)
-         || (prev.name && prev.line_num == ltab.limit->line_num
-             && strcmp (prev.name, ltab.limit->name) == 0
-             && filename_cmp (prev.file->name, filename) == 0))
-       continue;
-
-      /* Make name pointer a malloc'ed string.  */
-      ltab.limit->name = xstrdup (ltab.limit->name);
-      ltab.limit->file = source_file_lookup_path (filename);
-
-      ltab.limit->addr = vma;
-
-      /* Set is_static based on the enclosing function, using either:
-        1) the previous symbol, if it's from the same function, or
-        2) a symtab lookup.  */
-      if (ltab.limit->file == prev.file
-         && strcmp (ltab.limit->name, prev.name) == 0)
-       {
-         ltab.limit->is_static = prev.is_static;
-       }
-      else
-       {
-         sym = sym_lookup(&symtab, ltab.limit->addr);
-          if (sym)
-           ltab.limit->is_static = sym->is_static;
-       }
-
-      prev = *ltab.limit;
-
-      DBG (AOUTDEBUG, printf ("[core_create_line_syms] %lu %s 0x%lx\n",
-                             (unsigned long) (ltab.limit - ltab.base),
-                             ltab.limit->name,
-                             (unsigned long) ltab.limit->addr));
-      ++ltab.limit;
-      ++ltab.len;
     }
 
   /* Reserve space for function symbols and/or trim excess space.  */
index 9392575f7476348e6db8d111b3bf20aec44c1f0f..d1cbf25fa2809d08e798b109f0bca28be9551972 100644 (file)
@@ -527,17 +527,6 @@ This program is free software.  This program has absolutely no warranty.\n"));
   if (ignore_direct_calls)
     core_get_text_space (core_bfd);
 
-  /* Create symbols from core image.  */
-  if (external_symbol_table)
-    core_create_syms_from (external_symbol_table);
-  else if (line_granularity)
-    core_create_line_syms ();
-  else
-    core_create_function_syms ();
-
-  /* Translate sym specs into syms.  */
-  sym_id_parse ();
-
   if (file_format == FF_PROF)
     {
       fprintf (stderr,
@@ -557,6 +546,18 @@ This program is free software.  This program has absolutely no warranty.\n"));
       while (optind++ < argc);
     }
 
+  /* Create symbols from core image.  */
+  if (external_symbol_table)
+    core_create_syms_from (external_symbol_table);
+  else if (line_granularity)
+    core_create_line_syms ();
+  else
+    core_create_function_syms ();
+
+  /* Translate sym specs into syms.  */
+  sym_id_parse ();
+
+
   /* If user did not specify output style, try to guess something
      reasonable.  */
   if (output_style == 0)