[PATCH 6/6] gprof: only process line numbers for intersection of vmas and histograms
Richard Allen
rsaxvc@gmail.com
Sun Feb 16 22:50:05 GMT 2025
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 | 100 +++++++++++++++++++++++++----------------------
gprof/gprof.c | 23 +++++------
2 files changed, 65 insertions(+), 58 deletions(-)
diff --git a/gprof/corefile.c b/gprof/corefile.c
index 8441dc26584..57281295207 100644
--- a/gprof/corefile.c
+++ b/gprof/corefile.c
@@ -771,8 +771,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
@@ -802,54 +803,59 @@ 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 += gcd_insn_size)
+ 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 += gcd_insn_size)
{
- /* 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;
- }
- sym_init (ltab.limit);
-
- if (!get_src_info (vma, &filename, <ab.limit->name, <ab.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;
- }
+ 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, <ab.limit->name, <ab.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;
+ }
+ }
/* Reserve space for function symbols and/or trim excess space */
ltab_reserved = ltab.len + symtab.len;
diff --git a/gprof/gprof.c b/gprof/gprof.c
index 9392575f747..d1cbf25fa28 100644
--- a/gprof/gprof.c
+++ b/gprof/gprof.c
@@ -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)
--
2.39.5
More information about the Binutils
mailing list