Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Jan 2008 09:56:10 GMT
From:      John Birrell <jb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 133541 for review
Message-ID:  <200801180956.m0I9uAgj000614@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=133541

Change 133541 by jb@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);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200801180956.m0I9uAgj000614>