* Re: Removal of demangled names from partial symbols
[not found] <200012042053.VAA28364@reisser.regent.e-technik.tu-muenchen.de>
@ 2000-12-04 14:13 ` Daniel Berlin
2000-12-04 15:36 ` Daniel Berlin
1 sibling, 0 replies; 2+ messages in thread
From: Daniel Berlin @ 2000-12-04 14:13 UTC (permalink / raw)
To: Peter.Schauer; +Cc: gdb, gdb-patches
On Mon, 4 Dec 2000, Peter.Schauer wrote:
> : Why do we not do a lookup_minimal_symbol in
> : a new function, add_psymbol_and_dem_name_to_list, on the mangled name,
> : and if we get back a symbol, use the demangled name from that,
> : otherwise, demangle it.
>
> For some symbol formats (e.g. a.out) the linkage and debugging symbols are
> intermixed. By the time you want to record a partial symbol, the minimal
> symbol might have not been seen yet. Or the minimal symbol has been seen,
> but the minimal symbols are not yet installed, so lookup_minimal_symbol
> will fail.
>
So i could just use the mapping structure i describe below, and have both
SYMBOL_INIT_DEMANGLED_NAME, et al (IE all the ways we init the demangled
name) attempt to look up the mangled name in it to see if we've demangled
it before. Then it wouldn't matter what order this happened it.
> You might be able to work around this by going over all psymbols and fill
> in the demangled name via lookup_minimal_symbol _after_ the minimal symbols
> are installed, but I am not yet convinced that you don't have to pay your
> price on slower systems. After all, 5 secs to 6 secs is a 20% slowdown.
Except we already pay the price on ELF, where unless you've stripped it,
your minsyms contain just about all the symbols used in the program.
It's also an issue of saving ~50% of the memory we use now (Remember, the
slowdown comes from the bcaching, which would also not be necessary with
the mapping structure), and making lookups dramatically faster.
Without the bcaching, profiling shows all the time being used because
the lookup_minimal symbol, as you would expect.
Further analysis shows msymbol_hash_iw function isn't very good, and even
if it was perfect we have 379 buckets, total, per object file, so on 100000
symbols, most concentrated in one object file (the main program in this
case, which has 100 meg of debug info, and 100k symbols) ,we have chains
with an average length of 286. If we assume we have to search half those,
we are doing 143 strcmps to find the minimal symbol to get the demangled
name out of. The ternary search tree i propose would require the equivalent of one strcmp to find the
name.
Users i've talked to are more annoyed that once gdb gets going, it takes
for ever to do anything, because the symbol lookups take so long, than
they are that gdb takes 3 minutes vs 3 minutes, 30 seconds, to start up.
Let me finish integrating the mapping structure (I have the ternary
search tree in libiberty, in case others wanted to use it), and do some
tests to see how much faster it is.
--Dan
From ac131313@cygnus.com Mon Dec 04 14:31:00 2000
From: Andrew Cagney <ac131313@cygnus.com>
To: Doug Evans <dje@transmeta.com>
Cc: Ben Elliston <bje@redhat.com>, gdb-patches@sources.redhat.com, cgen@sources.redhat.com
Subject: Re: [Sim] Patch to sim/common/cgen-ops.h
Date: Mon, 04 Dec 2000 14:31:00 -0000
Message-id: <3A2C1907.1D45F29E@cygnus.com>
References: <14891.9921.841994.631587@casey.transmeta.com> <Pine.LNX.4.30.0012041725200.4024-100000@moshpit.cygnus.com> <14891.59391.397233.55439@casey.transmeta.com>
X-SW-Source: 2000-12/msg00085.html
Content-length: 1636
Doug Evans wrote:
> Andrew may have just been refering to the name choice used in the
> generated code. Either way, this is just a naming choice issue.
> I like the current scheme.
Kind of.
My understanding is that there are three type systems kicking around:
host
target
abstract
host:
This is the compiler on which
the system is being run. It has types
such as int, long, unsigned, ...
Their semantics are host platform
dependant
target:
This is the type system of the target.
At one level there are the types for
the target compiler (eg int which
could be 16 bits). At another level
there are the concrete semantics of
specific operations.
abstract/portable:
For sim/common (which took things from PPC).
This was a type system that was platform
independant. The semantics of something
like:
unsigned64 = (signed32) val;
were well defined. It is more fully:
unsigned64 = (unsigned64)(signed64)(signed32) val;
The two important things were that:
o The semantics were not tied to either
the host or the target. Instead they
are defined abstractly.
o It used a very standard convention.
C9x adopted int8 etc. Some have
used __u8 et.al.
Programmers are going to be instantly
familar with such a convention. They
are going to simply be bamboozled by
a more obscure SI, DI, et.al. convention.
sim/common used signed8 et.al. I've
more recently seen a suggestion for
S8, U16, et.al.
I think there are strong technical arguments for avoiding the SI, DI
convention and instead using an abstract type system that more clearly
defines its own semantics.
enjoy,
Andrew
From cgd@sibyte.com Mon Dec 04 14:43:00 2000
From: cgd@sibyte.com (Chris G. Demetriou)
To: gdb-patches@sourceware.cygnus.com
Cc: ehs@sibyte.com
Subject: sim/igen: add gen-delay-slot generation option
Date: Mon, 04 Dec 2000 14:43:00 -0000
Message-id: <5tg0k3ajun.fsf@highland.sibyte.com>
X-SW-Source: 2000-12/msg00086.html
Content-length: 19973
The patch below:
(1) adds a new simulator generation option to igen, "gen-delay-slot".
This new option generates PC pipe manipulation operations in a way
that can be used to cleanly and correctly model MIPS branch delay
slots.
(2) changes the generated code so that any wired-zero registers are
cleared by common code (shared by all of the opcodes), rather than
by each individual opcode's implementation.
The changes were implemented by a coworker, Ed Satterthwaite (who's
CC'd on this message), then cleaned up for submission by me. We've
both got assignment paperwork on file.
I've tested this in the manner described in the message I recently
sent:
http://sources.redhat.com/ml/gdb/2000-12/msg00015.html
It doesn't change any test output for any of the targets there
(several of which -- all but fr30 and sparclite -- seem to
successfully run things through the resulting 'run' binaries). This
doesn't surprise me; as you would see by looking at the code, (1)
doesn't change the code unless you've specified the new option, and
(2) does changes the code in a fairly straightforward way. 8-)
goes in sim/igen.
2000-12-02 Ed Satterthwaite ehs@sibyte.com and
Chris Demetriou cgd@sibyte.com
* igen.c (main): Add gen-delay-slot option.
(print_semantic_function_formal,
print_semantic_function_actual, print_icache_function_formal,
print_icache_function_actual): Implement gen-delay-slot
option.
* igen.h (_igen_gen_options): Add delay_slot member.
* gen-engine.c (print_register_clear): New function
used to handle gen-zero-r option.
(print_run_body): Implement gen-delay-slot option. Use
print_register_clear.
(print_jump_body): Use print_register_clear.
* gen-semantics.c (print_semantic_body): Implement
gen-delay-slot option. Delete old code to handle
gen-zero-r option.
* gen-support.c (print_support_function_name,
gen_support_h): Implement gen-delay-slot option.
* ld-insn.c (option_names, option_map, parse_option_record):
Implement gen-delay-slot option.
chris
===================================================================
Index: gen-engine.c
===================================================================
RCS file: /cvs/src/src/sim/igen/gen-engine.c,v
retrieving revision 1.1.1.1
diff -c -p -r1.1.1.1 gen-engine.c
*** gen-engine.c 1999/04/16 01:35:04 1.1.1.1
--- gen-engine.c 2000/12/03 00:22:02
*************** print_engine_issue_postfix_hook (lf *fil
*** 66,71 ****
--- 66,85 ----
static void
+ print_register_clear (lf *file)
+ {
+ /* Architecture expects a REG to be zero. Instead of having to
+ check every read to see if it is refering to that REG just zap it
+ at the start of every instruction */
+ if (options.gen.zero_reg)
+ {
+ lf_printf (file, "/* Architecture expects REG to be zero */\n");
+ lf_printf (file, "GPR_CLEAR(%d);\n", options.gen.zero_reg_nr);
+ lf_printf (file, "\n");
+ }
+ }
+
+ static void
print_run_body (lf *file,
gen_entry *table)
{
*************** print_run_body (lf *file,
*** 84,89 ****
--- 98,107 ----
lf_printf (file, "%sinstruction_address cia;\n", options.module.global.prefix.l);
}
lf_printf (file, "int current_cpu = next_cpu_nr;\n");
+ if (!options.gen.smp && options.gen.delay_slot)
+ {
+ lf_putstr (file, "sim_cpu *cpu = STATE_CPU (sd, current_cpu);\n");
+ }
if (options.gen.icache)
{
*************** In this case, we can take advantage of t
*** 105,113 ****
instruction address (CIA) does not need to be read from / written to
the CPU object after the execution of an instruction.
! Instead, CIA is only saved when the main loop exits. This occures
! when either sim_engine_halt or sim_engine_restart is called. Both of
! these functions save the current instruction address before halting /
restarting the simulator.
As a variation, there may also be support for an instruction cracking
--- 123,131 ----
instruction address (CIA) does not need to be read from / written to
the CPU object after the execution of an instruction.
! CIA is only saved when the main loop exits. This occurs when either
! sim_engine_halt or sim_engine_restart is called. Both of these
! functions save the current instruction address before halting /
restarting the simulator.
As a variation, there may also be support for an instruction cracking
*************** cache. */
*** 120,126 ****
lf_putstr (file, "SIM_ASSERT (current_cpu == 0);\n");
lf_putstr (file, "SIM_ASSERT (nr_cpus == 1);\n");
lf_putstr (file, "cia = CIA_GET (CPU);\n");
-
lf_putstr (file, "\n");
lf_putstr (file, "while (1)\n");
lf_putstr (file, " {\n");
--- 138,143 ----
*************** cache. */
*** 132,141 ****
lf_printf (file, "\n");
if (!options.gen.icache)
{
! lf_printf (file, "%sinstruction_word instruction_0 = IMEM%d (cia);\n",
options.module.global.prefix.l,
options.insn_bit_size);
print_engine_issue_prefix_hook (file);
print_idecode_body (file, table, "nia = ");
print_engine_issue_postfix_hook (file);
}
--- 149,168 ----
lf_printf (file, "\n");
if (!options.gen.icache)
{
! if (options.gen.delay_slot)
! {
! lf_printf (file, "%sinstruction_word instruction_0;\n",
! options.module.global.prefix.l);
! lf_putstr (file, "\n");
! lf_printf (file, "instruction_0 = IMEM%d (cia);\n",
! options.insn_bit_size);
! }
! else
! lf_printf (file, "%sinstruction_word instruction_0 = IMEM%d (cia);\n",
options.module.global.prefix.l,
options.insn_bit_size);
print_engine_issue_prefix_hook (file);
+ print_register_clear (file);
print_idecode_body (file, table, "nia = ");
print_engine_issue_postfix_hook (file);
}
*************** cache. */
*** 169,174 ****
--- 196,202 ----
lf_putstr (file, "{\n");
lf_indent (file, +2);
print_engine_issue_prefix_hook (file);
+ print_register_clear (file);
print_idecode_body (file, table, "nia =");
print_engine_issue_postfix_hook (file);
lf_indent (file, -2);
*************** cache. */
*** 177,182 ****
--- 205,211 ----
else
{
print_engine_issue_prefix_hook (file);
+ print_register_clear (file);
print_idecode_body (file, table, "semantic =");
lf_putstr (file, "nia = semantic (cpu, cache_entry, cia);\n");
print_engine_issue_postfix_hook (file);
*************** cache. */
*** 197,202 ****
--- 226,235 ----
case nia_is_invalid:
ERROR ("engine gen when NIA complex");
}
+ if (options.gen.delay_slot)
+ {
+ lf_printf (file, "CLOCK_PC_PIPE (cpu);\n");
+ }
/* events */
lf_putstr (file, "\n");
*************** after all the other CPU's and the event
*** 230,259 ****
lf_printf (file, "SIM_ASSERT (current_cpu >= 0);\n");
lf_printf (file, "SIM_ASSERT (current_cpu <= nr_cpus - 1);\n");
lf_printf (file, "SIM_ASSERT (nr_cpus <= MAX_NR_PROCESSORS);\n");
-
lf_putstr (file, "\n");
lf_putstr (file, "while (1)\n");
lf_putstr (file, " {\n");
lf_indent (file, +4);
lf_putstr (file, "sim_cpu *cpu = STATE_CPU (sd, current_cpu);\n");
! lf_putstr (file, "instruction_address cia = CIA_GET (cpu);\n");
! lf_putstr (file, "\n");
if (!options.gen.icache)
{
! lf_printf (file, "instruction_word instruction_0 = IMEM%d (cia);\n",
! options.insn_bit_size);
print_engine_issue_prefix_hook (file);
! print_idecode_body (file, table, "cia =");
! lf_putstr (file, "CIA_SET (cpu, cia);\n");
print_engine_issue_postfix_hook (file);
}
if (options.gen.icache)
{
! lf_putstr (file, "engine_cache *cache_entry =\n");
! lf_putstr (file, " cpu_icache_entry(processor, cia);\n");
! lf_putstr (file, "\n");
lf_putstr (file, "if (cache_entry->address == cia) {\n");
{
lf_indent (file, +2);
--- 263,324 ----
lf_printf (file, "SIM_ASSERT (current_cpu >= 0);\n");
lf_printf (file, "SIM_ASSERT (current_cpu <= nr_cpus - 1);\n");
lf_printf (file, "SIM_ASSERT (nr_cpus <= MAX_NR_PROCESSORS);\n");
lf_putstr (file, "\n");
+
lf_putstr (file, "while (1)\n");
lf_putstr (file, " {\n");
lf_indent (file, +4);
lf_putstr (file, "sim_cpu *cpu = STATE_CPU (sd, current_cpu);\n");
! if (options.gen.delay_slot)
! {
! lf_putstr (file, "\n");
! lf_putstr (file, "if (! RESET (cpu))\n");
! lf_putstr (file, " {\n");
! lf_indent (file, +4);
! lf_putstr (file, "instruction_address cia;\n");
! }
! else
! lf_putstr (file, "instruction_address cia = CIA_GET (cpu);\n");
if (!options.gen.icache)
{
! if (options.gen.delay_slot)
! {
! lf_printf (file, "instruction_word instruction_0;\n");
! lf_putstr (file, "\n");
! lf_printf (file, "cia = CIA_GET (cpu);\n");
! lf_printf (file, "instruction_0 = IMEM%d (cia);\n",
! options.insn_bit_size);
! }
! else
! lf_printf (file, "instruction_word instruction_0 = IMEM%d (cia);\n",
! options.insn_bit_size);
print_engine_issue_prefix_hook (file);
! print_register_clear (file);
! print_idecode_body (file, table, "cia = ");
print_engine_issue_postfix_hook (file);
+ lf_putstr (file, "CIA_SET (cpu, cia);\n");
+ if (options.gen.delay_slot)
+ {
+ lf_printf (file, "CLOCK_PC_PIPE (cpu);\n");
+ }
}
if (options.gen.icache)
{
! if (options.gen.delay_slot)
! {
! lf_putstr (file, "engine_cache *cache_entry;\n");
! lf_putstr (file, "\n");
! lf_printf (file, "cia = CIA_GET (cpu);\n");
! lf_putstr (file, "cache_entry = cpu_icache_entry(processor, cia);\n");
! }
! else
! {
! lf_putstr (file, "engine_cache *cache_entry =\n");
! lf_putstr (file, " cpu_icache_entry(processor, cia);\n");
! lf_putstr (file, "\n");
! }
lf_putstr (file, "if (cache_entry->address == cia) {\n");
{
lf_indent (file, +2);
*************** after all the other CPU's and the event
*** 285,290 ****
--- 350,356 ----
lf_putstr (file, "{\n");
lf_indent (file, +2);
print_engine_issue_prefix_hook (file);
+ print_register_clear (file);
print_idecode_body(file, table, "cia =");
print_engine_issue_postfix_hook (file);
lf_indent (file, -2);
*************** after all the other CPU's and the event
*** 293,298 ****
--- 359,365 ----
else
{
print_engine_issue_prefix_hook (file);
+ print_register_clear (file);
print_idecode_body(file, table, "semantic = ");
lf_putstr (file, "cia = semantic(processor, cache_entry, cia);\n");
print_engine_issue_postfix_hook (file);
*************** after all the other CPU's and the event
*** 305,310 ****
--- 372,382 ----
lf_putstr (file, "}\n");
}
+ if (options.gen.delay_slot)
+ {
+ lf_indent (file, -4);
+ lf_putstr (file, " }\n");
+ }
lf_putstr (file, "\n");
lf_putstr (file, "current_cpu += 1;\n");
lf_putstr (file, "if (current_cpu == nr_cpus)\n");
*************** print_jump_body (lf *file,
*** 653,663 ****
lf_indent (file, +1);
}
! print_engine_issue_prefix_hook (file);
lf_putstr (file, "instruction\n");
lf_putstr (file, " = vm_instruction_map_read(cpu_instruction_map(processor),\n");
lf_putstr (file, " processor, nia);\n");
print_engine_issue_prefix_hook (file);
print_idecode_body (file, entry, "/*IGORE*/");
print_engine_issue_postfix_hook (file);
--- 725,736 ----
lf_indent (file, +1);
}
! print_engine_issue_prefix_hook (file); /* XXX also 4 lines below? */
lf_putstr (file, "instruction\n");
lf_putstr (file, " = vm_instruction_map_read(cpu_instruction_map(processor),\n");
lf_putstr (file, " processor, nia);\n");
print_engine_issue_prefix_hook (file);
+ print_register_clear (file);
print_idecode_body (file, entry, "/*IGORE*/");
print_engine_issue_postfix_hook (file);
Index: gen-semantics.c
===================================================================
RCS file: /cvs/src/src/sim/igen/gen-semantics.c,v
retrieving revision 1.2
diff -c -p -r1.2 gen-semantics.c
*** gen-semantics.c 2000/05/29 19:28:53 1.2
--- gen-semantics.c 2000/12/03 00:22:02
*************** print_semantic_body (lf *file,
*** 219,226 ****
}
else
{
! lf_printf (file, "nia = cia + %d;\n",
! options.insn_bit_size / 8);
}
}
}
--- 219,233 ----
}
else
{
! if (options.gen.delay_slot)
! {
! lf_printf (file, "nia = NIA_GET (CPU); ");
! lf_printf (file, "ADVANCE_PC_PIPE (CPU, %d);\n",
! options.insn_bit_size / 8);
! }
! else
! lf_printf (file, "nia = cia + %d;\n",
! options.insn_bit_size / 8);
}
}
}
*************** print_semantic_body (lf *file,
*** 237,252 ****
lf_printf (file, " {\n");
lf_indent (file, +4);
/* FIXME - need to log a conditional failure */
- }
-
- /* Architecture expects a REG to be zero. Instead of having to
- check every read to see if it is refering to that REG just zap it
- at the start of every instruction */
- if (options.gen.zero_reg)
- {
- lf_printf (file, "\n");
- lf_printf (file, "/* Architecture expects REG to be zero */\n");
- lf_printf (file, "GPR_CLEAR(%d);\n", options.gen.zero_reg_nr);
}
/* generate the code (or at least something */
--- 244,249 ----
Index: gen-support.c
===================================================================
RCS file: /cvs/src/src/sim/igen/gen-support.c,v
retrieving revision 1.1.1.1
diff -c -p -r1.1.1.1 gen-support.c
*** gen-support.c 1999/04/16 01:35:04 1.1.1.1
--- gen-support.c 2000/12/03 00:22:02
*************** print_support_function_name (lf *file,
*** 77,83 ****
lf_printf (file, "%s%s\n(",
options.module.support.prefix.l,
function->name);
! if (options.gen.smp)
lf_printf (file,
"sim_cpu *cpu, %sinstruction_address cia, int MY_INDEX",
options.module.support.prefix.l);
--- 77,83 ----
lf_printf (file, "%s%s\n(",
options.module.support.prefix.l,
function->name);
! if (options.gen.smp || options.gen.delay_slot)
lf_printf (file,
"sim_cpu *cpu, %sinstruction_address cia, int MY_INDEX",
options.module.support.prefix.l);
*************** gen_support_h (lf *file,
*** 111,117 ****
insn_table *table)
{
/* output the definition of `SD_'*/
! if (options.gen.smp)
{
lf_printf(file, "#define SD CPU_STATE (cpu)\n");
lf_printf(file, "#define CPU cpu\n");
--- 111,117 ----
insn_table *table)
{
/* output the definition of `SD_'*/
! if (options.gen.smp || options.gen.delay_slot)
{
lf_printf(file, "#define SD CPU_STATE (cpu)\n");
lf_printf(file, "#define CPU cpu\n");
Index: igen.c
===================================================================
RCS file: /cvs/src/src/sim/igen/igen.c,v
retrieving revision 1.1.1.1
diff -c -p -r1.1.1.1 igen.c
*** igen.c 1999/04/16 01:35:04 1.1.1.1
--- igen.c 2000/12/03 00:22:02
*************** print_semantic_function_formal (lf *file
*** 65,71 ****
nr += lf_printf (file, "%sinstruction_address cia",
options.module.global.prefix.l);
}
! else if (options.gen.smp)
{
nr += lf_printf (file, "sim_cpu *cpu,\n");
for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
--- 65,71 ----
nr += lf_printf (file, "%sinstruction_address cia",
options.module.global.prefix.l);
}
! else if (options.gen.smp || options.gen.delay_slot)
{
nr += lf_printf (file, "sim_cpu *cpu,\n");
for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++)
*************** print_semantic_function_actual (lf *file
*** 104,110 ****
}
else
{
! if (options.gen.smp)
nr += lf_printf (file, "cpu");
else
nr += lf_printf (file, "sd");
--- 104,110 ----
}
else
{
! if (options.gen.smp || options.gen.delay_slot)
nr += lf_printf (file, "cpu");
else
nr += lf_printf (file, "sd");
*************** print_icache_function_formal (lf *file,
*** 133,139 ****
{
int nr = 0;
int word_nr;
! if (options.gen.smp)
nr += lf_printf (file, "sim_cpu *cpu,\n");
else
nr += lf_printf (file, "SIM_DESC sd,\n");
--- 133,139 ----
{
int nr = 0;
int word_nr;
! if (options.gen.smp || options.gen.delay_slot)
nr += lf_printf (file, "sim_cpu *cpu,\n");
else
nr += lf_printf (file, "SIM_DESC sd,\n");
*************** print_icache_function_actual (lf *file,
*** 153,159 ****
{
int nr = 0;
int word_nr;
! if (options.gen.smp)
nr += lf_printf (file, "cpu");
else
nr += lf_printf (file, "sd");
--- 153,159 ----
{
int nr = 0;
int word_nr;
! if (options.gen.smp || options.gen.delay_slot)
nr += lf_printf (file, "cpu");
else
nr += lf_printf (file, "sd");
*************** main (int argc,
*** 1086,1091 ****
--- 1086,1092 ----
printf ("\n");
printf ("\t gen-conditional-issue - conditionally issue each instruction\n");
printf ("\t gen-delayed-branch - need both cia and nia passed around\n");
+ printf ("\t gen-delay-slot - variant of gen-delayed-branch (in the MIPS style)\n");
printf ("\t gen-direct-access - use #defines to directly access values\n");
printf ("\t gen-zero-r<N> - arch assumes GPR(<N>) == 0, keep it that way\n");
printf ("\t gen-icache[=<N> - generate an instruction cracking cache of size <N>\n");
*************** main (int argc,
*** 1367,1372 ****
--- 1368,1377 ----
{
options.gen.delayed_branch = enable_p;
options.warning (NULL, "Option delayed-branch replaced by gen-delayed-branch\n");
+ }
+ else if (strcmp (argp, "gen-delay-slot") == 0)
+ {
+ options.gen.delay_slot = enable_p;
}
else if (strcmp (argp, "gen-direct-access") == 0)
{
Index: igen.h
===================================================================
RCS file: /cvs/src/src/sim/igen/igen.h,v
retrieving revision 1.1.1.1
diff -c -p -r1.1.1.1 igen.h
*** igen.h 1999/04/16 01:35:04 1.1.1.1
--- igen.h 2000/12/03 00:22:02
*************** struct _igen_gen_options {
*** 51,56 ****
--- 51,57 ----
int conditional_issue;
int slot_verification;
int delayed_branch;
+ int delay_slot;
/* If zeroing a register, which one? */
int zero_reg;
Index: ld-insn.c
===================================================================
RCS file: /cvs/src/src/sim/igen/ld-insn.c,v
retrieving revision 1.1.1.1
diff -c -p -r1.1.1.1 ld-insn.c
*** ld-insn.c 1999/04/16 01:35:05 1.1.1.1
--- ld-insn.c 2000/12/03 00:22:02
*************** typedef enum {
*** 618,623 ****
--- 618,624 ----
multi_sim_option,
format_names_option,
gen_delayed_branch,
+ gen_delay_slot,
unknown_option,
} option_names;
*************** static const name_map option_map[] = {
*** 630,635 ****
--- 631,637 ----
{ "multi-sim", multi_sim_option },
{ "format-names", format_names_option },
{ "gen-delayed-branch", gen_delayed_branch },
+ { "gen-delay-slot", gen_delay_slot },
{ NULL, unknown_option },
};
*************** parse_option_record (table *file,
*** 723,728 ****
--- 725,735 ----
case gen_delayed_branch:
{
options.gen.delayed_branch = a2i (value);
+ break;
+ }
+ case gen_delay_slot:
+ {
+ options.gen.delay_slot = a2i (value);
break;
}
case unknown_option:
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Removal of demangled names from partial symbols
[not found] <200012042053.VAA28364@reisser.regent.e-technik.tu-muenchen.de>
2000-12-04 14:13 ` Removal of demangled names from partial symbols Daniel Berlin
@ 2000-12-04 15:36 ` Daniel Berlin
1 sibling, 0 replies; 2+ messages in thread
From: Daniel Berlin @ 2000-12-04 15:36 UTC (permalink / raw)
To: Peter.Schauer; +Cc: gdb, gdb-patches
"Peter.Schauer" <Peter.Schauer@regent.e-technik.tu-muenchen.de> writes:
Just a little more data.
I rigged lookup_minimal_symbol to print the number of times (to a
file, one number per line) it had to
do "msymbol = msymbol->hash_next", if the number was > 0.
All I did for this print out is start gdb like "gdb ~/corr101", then
quit as soon as we got a prompt.
corr101 has 27905 minsyms in it (according to maint print msymbols).
We do at least 1 strcmp, possibly 2, for each of the compares in the
loop looking for the minimal symbol name (which ends when we find the
symbol, or msymbol is NULL), because it uses SYMBOL_MATCHES_NAME.
The max number of times we ended up doing this SYMBOL_MATCHES_NAME, is
559 (which occurs ~1500 times).
We had 544476 lookups which took greater than 0 of these "compares"
(which each is 1 strcmp, and maybe 1 strcmp_iw).
We did 40875096 "compares" in these lookups.
Or, an average of 75 "compares" per lookup of a given name.
So, even if the ternary search tree was the equivalent of 3 compares
(due to overhead or whatever.), we'd still be able to do the partial
demangling fillin (which is completely dominated, at 99.99% of the
time being spent looking up the minsym to get the demangled name right
now) an average 25 times faster than lookup_minimal_symbol does it. So
i'm pretty confident we can completely eliminate the 20% slowdown i
was seeing.
Note, i'm not counting the compares both passes lookup_minimal_symbol does, just
the first pass. The second pass is over the minsym demangled hash
table, and goes slower, and is a waste of time for looking up the
symbol to get the mangled name, but i'm just trying to prove a point about how
much faster the demangling by lookup i want to use in the partial
symbol stuff could be.
Let me finish implementing and see if i'm right.
--Dan
> : Why do we not do a lookup_minimal_symbol in
> : a new function, add_psymbol_and_dem_name_to_list, on the mangled name,
> : and if we get back a symbol, use the demangled name from that,
> : otherwise, demangle it.
>
> For some symbol formats (e.g. a.out) the linkage and debugging symbols are
> intermixed. By the time you want to record a partial symbol, the minimal
> symbol might have not been seen yet. Or the minimal symbol has been seen,
> but the minimal symbols are not yet installed, so lookup_minimal_symbol
> will fail.
>
> You might be able to work around this by going over all psymbols and fill
> in the demangled name via lookup_minimal_symbol _after_ the minimal symbols
> are installed, but I am not yet convinced that you don't have to pay your
> price on slower systems. After all, 5 secs to 6 secs is a 20% slowdown.
>
> > Demangled names were removed from partial symbols to speed start up
> > times a few years ago.
> >
> > However, with the minsym demangled hash table now around, we demangle
> > all minimal symbols when we install minimal symbols (IE we init the
> > demangled name on them,unconditionally).
> >
> > Since the minimal symbol table ends up including a large subset of the
> > mangled partial symbols (if not all of them), this means we already have a large
> > subset of the partial symbol names demangled for us at start up
> > anyway.
> >
> > Why do we not do a lookup_minimal_symbol in
> > a new function, add_psymbol_and_dem_name_to_list, on the mangled name,
> > and if we get back a symbol, use the demangled name from that,
> > otherwise, demangle it.
> >
> > Even tests on 100 meg of debug info show we barely add any startup
> > time at all (5 seconds without, 6 seconds with) .
> > In fact, all added startup time is attributable to the
> > fact that to save memory, I had it bcache the demangled name in
> > SYMBOL_INIT_DEMANGLED_NAME. If you don't bcache it (like right now),
> > it's in memory in at least the full symbol, and the minimal
> > symbol (it's actually in memory once for every time
> > SYMBOL_INIT_DEMANGLED_NAME is called on a symbol, and the demangling succeeds).
> >
> > I think 1 second on 100 meg of debug info is worth it to not have to
> > linear search on every symbol lookup, which is amazingly
> > slow, and if you have gdb using swap at all because of the number of
> > symbols, you are almost guaranteed to hit the swap
> > hard on *every* single lookup, since we have to go through every
> > single symbol.
> >
> > This would solve the problem of not being able to lookup partial
> > symbols by demangled name, and allow us to binary search them without
> > fear of missing a symbol.
> >
> > Would this be acceptable?
> >
> > My next trick after that would be to add a mangled->demangled mapping
> > structure, if it's necessary to improve speed, and just use that to
> > lookup the names before demangling the
> > name over again, in cases where we do (ie SYMBOL_INIT_DEMANGLED) need
> > to find a demangled name for a mangled one, and use that
> > rather than the minimal symbol table to try to find the name.
> > The reason for this is that a hash table (in this case, we are
> > using the minimal symbol demangled hash table as a lookup table) is the wrong structure
> > for this, since demangled names can be *very* large (average of 82
> > chars on my large C++ programs), and we always have to hash the entire
> > string, then do a whole bunch of string compares, because the chains are
> > long. This is okay when we hit (except for the long chains), but on
> > misses we waste the same amount of times as hits, if not more. The
> > string compares on hits also cost a lot because of the length of the string.
> > We really should use a ternary search tree or some structure like it,
> > which on hits is actually faster (since we don't need multiple
> > string compares), and on misses is a whole ton faster, since we abort
> > much sooner.
> >
> > --Dan
> >
> >
> >
>
> --
> Peter Schauer pes@regent.e-technik.tu-muenchen.de
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2000-12-04 15:36 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <200012042053.VAA28364@reisser.regent.e-technik.tu-muenchen.de>
2000-12-04 14:13 ` Removal of demangled names from partial symbols Daniel Berlin
2000-12-04 15:36 ` Daniel Berlin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox