PERFORCE change 133541 for review
John Birrell
jb at FreeBSD.org
Fri Jan 18 01:56:11 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=133541
Change 133541 by jb at jb_freebsd1 on 2008/01/18 09:55:34
Add a hash table for DIEs for future use.
Add a default name and use this when allocating every DIE.
When an attribute value is found with DW_AT_name, get the
pointer to the real name and use that.
The use of __anon__ as the default name causes like DIEs to
be matched when merging CTF data. The "die%d" name I was
using caused an enormous number of type entries to be created
and merged. The fact that the %d used a different number each
time made it look like they were all different when in fact
they weren't.
We're down to the same order of magnitude of types in a
GENERIC kernel as Solaris has in their 'genunix' kernel.
This solves the performance problem I was seeing when running
ctfmerge on the kernel object files.
Affected files ...
.. //depot/projects/dtrace/src/contrib/opensolaris/tools/ctf/cvt/dwarf.c#14 edit
.. //depot/projects/dtrace/src/lib/libdwarf/_libdwarf.h#2 edit
.. //depot/projects/dtrace/src/lib/libdwarf/dwarf_attrval.c#4 edit
.. //depot/projects/dtrace/src/lib/libdwarf/dwarf_die.c#2 edit
.. //depot/projects/dtrace/src/lib/libdwarf/dwarf_init.c#2 edit
Differences ...
==== //depot/projects/dtrace/src/contrib/opensolaris/tools/ctf/cvt/dwarf.c#14 (text) ====
@@ -1370,13 +1370,8 @@
*/
(void) die_unsigned(dw, base, DW_AT_byte_size, &sz, DW_ATTR_REQ);
- if (tdp->t_name == NULL) {
- /* terminate("die %llu: base type without name\n", off); */
- char dummy_name[64];
- snprintf(dummy_name, sizeof(dummy_name), "die%lx", (u_long) off);
- debug(1, "die %llu: has no name. Using a dummy one: '%s'\n", off, dummy_name);
- tdp->t_name = xstrdup(dummy_name);
- }
+ if (tdp->t_name == NULL)
+ terminate("die %llu: base type without name\n", off);
/* XXX make a name parser for float too */
if ((intr = die_base_name_parse(tdp->t_name, &new)) != NULL) {
@@ -1684,14 +1679,8 @@
tdesc_add(dw, tdp);
}
- if (tdp != NULL) {
+ if (tdp != NULL)
tdp->t_name = die_name(dw, die);
- if (tdp->t_name == NULL) {
- char dummy_name[64];
- snprintf(dummy_name, sizeof(dummy_name), "die%lx", (u_long) off);
- tdp->t_name = xstrdup(dummy_name);
- }
- }
dc->dc_create(dw, die, off, tdp);
}
==== //depot/projects/dtrace/src/lib/libdwarf/_libdwarf.h#2 (text+ko) ====
@@ -56,6 +56,8 @@
#define DWARF_strtab 17
#define DWARF_DEBUG_SNAMES 18
+#define DWARF_DIE_HASH_SIZE 8191
+
#define DWARF_SET_ERROR(_e, _err) do { \
_e->err_error = _err; \
_e->elf_error = 0; \
@@ -91,10 +93,13 @@
uint64_t die_abnum; /* Abbrev number. */
Dwarf_Abbrev die_a; /* Abbrev pointer. */
Dwarf_CU die_cu; /* Compilation unit pointer. */
+ const char *die_name; /* Ptr to the name string. */
STAILQ_HEAD(, _Dwarf_AttrValue)
die_attrval; /* List of attribute values. */
STAILQ_ENTRY(_Dwarf_Die)
- die_next; /* Next die. */
+ die_next; /* Next die in list. */
+ STAILQ_ENTRY(_Dwarf_Die)
+ die_hash; /* Next die in hash table. */
};
struct _Dwarf_Attribute {
@@ -130,6 +135,9 @@
cu_abbrev; /* List of abbrevs. */
STAILQ_HEAD(, _Dwarf_Die)
cu_die; /* List of dies. */
+ STAILQ_HEAD(, _Dwarf_Die)
+ cu_die_hash[DWARF_DIE_HASH_SIZE];
+ /* Hash of dies. */
STAILQ_ENTRY(_Dwarf_CU)
cu_next; /* Next compilation unit. */
};
==== //depot/projects/dtrace/src/lib/libdwarf/dwarf_attrval.c#4 (text+ko) ====
@@ -60,6 +60,19 @@
/* Add the attribute value to the list in the die. */
STAILQ_INSERT_TAIL(&die->die_attrval, av, av_next);
+ /* Save a pointer to the attribute name if this is one. */
+ if (av->av_attrib == DW_AT_name)
+ switch (av->av_form) {
+ case DW_FORM_strp:
+ die->die_name = av->u[1].s;
+ break;
+ case DW_FORM_string:
+ die->die_name = av->u[0].s;
+ break;
+ default:
+ break;
+ }
+
if (avp != NULL)
*avp = av;
@@ -118,7 +131,9 @@
*strp = NULL;
- if ((av = dwarf_attrval_find(die, attr)) == NULL) {
+ if (attr == DW_AT_name)
+ *strp = die->die_name;
+ else if ((av = dwarf_attrval_find(die, attr)) == NULL) {
DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
ret = DWARF_E_NO_ENTRY;
} else {
==== //depot/projects/dtrace/src/lib/libdwarf/dwarf_die.c#2 (text+ko) ====
@@ -29,10 +29,13 @@
#include <stdlib.h>
#include "_libdwarf.h"
+static const char *anon_name = "__anon__";
+
int
dwarf_die_add(Dwarf_CU cu, int level, uint64_t offset, uint64_t abnum, Dwarf_Abbrev a, Dwarf_Die *diep, Dwarf_Error *err)
{
Dwarf_Die die;
+ uint64_t key;
int ret = DWARF_E_NONE;
if (err == NULL)
@@ -54,6 +57,7 @@
die->die_abnum = abnum;
die->die_a = a;
die->die_cu = cu;
+ die->die_name = anon_name;
/* Initialise the list of attribute values. */
STAILQ_INIT(&die->die_attrval);
@@ -61,6 +65,10 @@
/* Add the die to the list in the compilation unit. */
STAILQ_INSERT_TAIL(&cu->cu_die, die, die_next);
+ /* Add the die to the hash table in the compilation unit. */
+ key = offset % DWARF_DIE_HASH_SIZE;
+ STAILQ_INSERT_TAIL(&cu->cu_die_hash[key], die, die_hash);
+
if (diep != NULL)
*diep = die;
@@ -68,7 +76,7 @@
}
int
-dwarf_dieoffset(Dwarf_Die die __unused, Dwarf_Off *ret_offset, Dwarf_Error *err __unused)
+dwarf_dieoffset(Dwarf_Die die, Dwarf_Off *ret_offset, Dwarf_Error *err __unused)
{
*ret_offset = die->die_offset;
==== //depot/projects/dtrace/src/lib/libdwarf/dwarf_init.c#2 (text+ko) ====
@@ -459,6 +459,7 @@
Dwarf_CU cu;
Elf_Data *d = NULL;
Elf_Scn *scn;
+ int i;
int level = 0;
int relocated = 0;
int ret = DWARF_E_NONE;
@@ -522,6 +523,10 @@
/* Initialise the list of dies. */
STAILQ_INIT(&cu->cu_die);
+ /* Initialise the hash table of dies. */
+ for (i = 0; i < DWARF_DIE_HASH_SIZE; i++)
+ STAILQ_INIT(&cu->cu_die_hash[i]);
+
/* Add the compilation unit to the list. */
STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next);
More information about the p4-projects
mailing list