diff options
-rw-r--r-- | gdb/ChangeLog | 12 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 70 |
2 files changed, 54 insertions, 28 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 412d84a..42ac5a6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,17 @@ 2008-08-20 Daniel Jacobowitz <dan@codesourcery.com> + * dwarf2read.c (REF_HASH_SIZE): Delete. + (struct dwarf2_cu): Replace die_ref_table with die_hash. + (struct die_info): Remove next_ref. + (store_in_ref_table): Remove offset argument. Rewrite to use + htab_find_slot_with_hash. + (die_hash, die_eq): New. + (read_comp_unit): Allocate the die_hash. + (read_die_and_children): Update call to store_die_ref. + (follow_die_ref): Rewrite to use htab_find_with_hash. + +2008-08-20 Daniel Jacobowitz <dan@codesourcery.com> + * dwarf2read.c (free_die_list, copy_die): Delete. (dwarf_alloc_die): Take a CU argument. Allocate the new DIE on the obstack. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 111b948..4d16494 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -259,11 +259,6 @@ struct comp_unit_head int base_known; }; -/* Fixed size for the DIE hash table. */ -#ifndef REF_HASH_SIZE -#define REF_HASH_SIZE 1021 -#endif - /* Internal state when decoding a particular compilation unit. */ struct dwarf2_cu { @@ -329,7 +324,7 @@ struct dwarf2_cu int last_used; /* A hash table of die offsets for following references. */ - struct die_info *die_ref_table[REF_HASH_SIZE]; + htab_t die_hash; /* Full DIEs if read in. */ struct die_info *dies; @@ -534,7 +529,6 @@ struct die_info unsigned int offset; /* Offset in .debug_info section */ unsigned int num_attrs; /* Number of attributes */ struct attribute *attrs; /* An array of attributes */ - struct die_info *next_ref; /* Next die in ref hash table */ /* The dies in a compilation unit form an n-ary tree. PARENT points to this die's parent; CHILD points to the first child of @@ -985,7 +979,7 @@ static void dump_die (struct die_info *); static void dump_die_list (struct die_info *); -static void store_in_ref_table (unsigned int, struct die_info *, +static void store_in_ref_table (struct die_info *, struct dwarf2_cu *); static unsigned int dwarf2_get_ref_die_offset (struct attribute *, @@ -5112,11 +5106,41 @@ read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu) return set_die_type (die, type, cu); } +/* Trivial hash function for die_info: the hash value of a DIE + is its offset in .debug_info for this objfile. */ + +static hashval_t +die_hash (const void *item) +{ + const struct die_info *die = item; + return die->offset; +} + +/* Trivial comparison function for die_info structures: two DIEs + are equal if they have the same offset. */ + +static int +die_eq (const void *item_lhs, const void *item_rhs) +{ + const struct die_info *die_lhs = item_lhs; + const struct die_info *die_rhs = item_rhs; + return die_lhs->offset == die_rhs->offset; +} + /* Read a whole compilation unit into a linked list of dies. */ static struct die_info * read_comp_unit (gdb_byte *info_ptr, bfd *abfd, struct dwarf2_cu *cu) { + cu->die_hash + = htab_create_alloc_ex (cu->header.length / 12, + die_hash, + die_eq, + NULL, + &cu->comp_unit_obstack, + hashtab_obstack_allocate, + dummy_obstack_deallocate); + return read_die_and_children (info_ptr, abfd, cu, &info_ptr, NULL); } @@ -5142,7 +5166,7 @@ read_die_and_children (gdb_byte *info_ptr, bfd *abfd, *new_info_ptr = cur_ptr; return NULL; } - store_in_ref_table (die->offset, die, cu); + store_in_ref_table (die, cu); if (has_children) { @@ -9091,16 +9115,13 @@ dump_die_list (struct die_info *die) } static void -store_in_ref_table (unsigned int offset, struct die_info *die, - struct dwarf2_cu *cu) +store_in_ref_table (struct die_info *die, struct dwarf2_cu *cu) { - int h; - struct die_info *old; + void **slot; + + slot = htab_find_slot_with_hash (cu->die_hash, die, die->offset, INSERT); - h = (offset % REF_HASH_SIZE); - old = cu->die_ref_table[h]; - die->next_ref = old; - cu->die_ref_table[h] = die; + *slot = die; } static unsigned int @@ -9154,7 +9175,6 @@ follow_die_ref (struct die_info *src_die, struct attribute *attr, { struct die_info *die; unsigned int offset; - int h; struct die_info temp_die; struct dwarf2_cu *target_cu; @@ -9171,20 +9191,14 @@ follow_die_ref (struct die_info *src_die, struct attribute *attr, else target_cu = cu; - h = (offset % REF_HASH_SIZE); - die = target_cu->die_ref_table[h]; - while (die) - { - if (die->offset == offset) - return die; - die = die->next_ref; - } + temp_die.offset = offset; + die = htab_find_with_hash (target_cu->die_hash, &temp_die, offset); + if (die) + return die; error (_("Dwarf Error: Cannot find DIE at 0x%lx referenced from DIE " "at 0x%lx [in module %s]"), (long) offset, (long) src_die->offset, cu->objfile->name); - - return NULL; } /* Decode simple location descriptions. |