This is the mail archive of the gdb-patches@sources.redhat.com 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]

[wip] Delete prev_func_name and ecs->stop_func_name


Hello,

`what smokin gun?'

More follow-up on prev_pc, I decided to just delete prev_func_name and ecs->stop_func_name and see what happens ...

Briefly ....

When identifying a PC in a signal trampoline, GDB uses a sequence like:

find_pc_partial_function (get_frame_pc (frame), &name,
(CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
PC_IN_SIGTRAMP (get_frame_pc (frame), name)


(map the PC onto a function name) where PC_IN_SIGTRAMP then contains something like:

  if (SIGTRAMP_START_P ())
    return (pc) >= SIGTRAMP_START (pc) && (pc) < SIGTRAMP_END (pc);
  else
    return name && strcmp ("_sigtramp", name) == 0;

use that function name to see if it is in the sigtramp function.

GDB contains two tweaks for improving performance:

- find_pc_partial_function() runs a single entry cache so that second and further requests for the same function, are handled without any symbol table lookup

- infrun.c caches (well tries to) the results (in prev_func_name) and (ecs->stop_func_name) from the find_pc_partial_function() lookup to avoid additional calls.

If prev_func_name and stop_func_name are eliminated, infrun.c will make additional calls to find_pc_partial_function(). That, I think, is ok, provided the hit rate of find_pc_partial_function's cache doesn't go down.

So ....

Running the i386 testsuite with gcov on an existing GDB reveals:

                int
                find_pc_sect_partial_function
       10133    {
       10133      struct partial_symtab *pst;
                  struct symbol *f;
                  struct minimal_symbol *msymbol;
                  struct partial_symbol *psb;
                  struct obj_section *osect;
                  int i;
                  CORE_ADDR mapped_pc;

10133 mapped_pc = overlay_mapped_address (pc, section);

       10133      if (mapped_pc >= cache_pc_function_low
                      && mapped_pc < cache_pc_function_high
                      && section == cache_pc_function_section)
        3565        goto return_cached_value;

3565 if (SIGTRAMP_START_P () && ...

that is, 10133 calls to find_pc_sect_partial_function, 3565 of which missed in the cache. Modifying infrun.c so that it doesn't cache the name turns up:

                int
                find_pc_sect_partial_function
       12087    {
       12087      struct partial_symtab *pst;
                  struct symbol *f;
                  struct minimal_symbol *msymbol;
                  struct partial_symbol *psb;
                  struct obj_section *osect;
                  int i;
                  CORE_ADDR mapped_pc;

12087 mapped_pc = overlay_mapped_address (pc, section);

       12087      if (mapped_pc >= cache_pc_function_low
                      && mapped_pc < cache_pc_function_high
                      && section == cache_pc_function_section)
        3569        goto return_cached_value;

That is, while the calls to find_pc_sect_partial_function were increased by 2000 the number of misses (which resulted in expensive symbol table lookups) increased by, er, 4!!

Given this, my conclusion is that prev_func_name and ecs->stop_func_name can be deleted. The the cost incured is an additional function call and not the very expensive PC->symbol lookup.

The more bits of infrun that get deleted the better :-)

thoughts?
Andrew


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