This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[RFA/dwarf] Eliminate dwarf2_tmp_obstack
- From: Daniel Jacobowitz <drow at false dot org>
- To: gdb-patches at sources dot redhat dot com
- Cc: jimb at redhat dot com, ezannoni at redhat dot com
- Date: Sun, 18 Apr 2004 23:17:44 -0400
- Subject: [RFA/dwarf] Eliminate dwarf2_tmp_obstack
dwarf2_tmp_obstack serves as a general purpose dumping ground. After my
previous patches, there are only two things left on it: the linked list we
use to fudge GCC 2.95 line number tables (some day soon I think this hack
should go away; it was primarily for the benefit of the testsuite, and was
fixed at least as of GCC 3.1), and the block structures created in
read_attribute_value.
Both of these are clearly associated with a particular compilation unit.
If we put them on the comp_unit_obstack, then we don't have any need for
the global obstack any more.
Since my following patches change the lifetimes of individual CUs, I felt
this was a worthwhile cleanup. OK?
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
2004-04-18 Daniel Jacobowitz <drow@mvista.com>
* dwarf2read.c (dwarf2_tmp_obstack, dwarf2_free_tmp_obstack):
Delete.
(dwarf_alloc_block): Take a CU argument. Use the comp_unit_obstack.
(read_attribute_value): Update calls to dwarf_alloc_block.
(dwarf2_build_psymtabs_hard): Don't initialize or clean up
dwarf2_tmp_obstack.
(psymtab_to_symtab_1): Likewise. Clean up using
free_stack_comp_unit.
(add_to_cu_func_list): Use the comp_unit_obstack.
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.146
diff -u -p -r1.146 dwarf2read.c
--- dwarf2read.c 16 Apr 2004 16:12:52 -0000 1.146
+++ dwarf2read.c 19 Apr 2004 02:14:15 -0000
@@ -494,9 +494,6 @@ struct dwarf_block
static struct die_info *die_ref_table[REF_HASH_SIZE];
-/* Obstack for allocating temporary storage used during symbol reading. */
-static struct obstack dwarf2_tmp_obstack;
-
/* Allocate fields for structs, unions and enums in this size. */
#ifndef DW_FIELD_ALLOC_CHUNK
#define DW_FIELD_ALLOC_CHUNK 4
@@ -910,9 +907,7 @@ static struct type *dwarf2_fundamental_t
/* memory allocation interface */
-static void dwarf2_free_tmp_obstack (void *);
-
-static struct dwarf_block *dwarf_alloc_block (void);
+static struct dwarf_block *dwarf_alloc_block (struct dwarf2_cu *);
static struct abbrev_info *dwarf_alloc_abbrev (struct dwarf2_cu *);
@@ -1209,42 +1204,10 @@ dwarf2_build_psymtabs_hard (struct objfi
char *beg_of_comp_unit;
struct partial_die_info comp_unit_die;
struct partial_symtab *pst;
- struct cleanup *back_to;
CORE_ADDR lowpc, highpc, baseaddr;
info_ptr = dwarf2_per_objfile->info_buffer;
- /* We use dwarf2_tmp_obstack for objects that don't need to survive
- the partial symbol scan, like attribute values.
-
- We could reduce our peak memory consumption during partial symbol
- table construction by freeing stuff from this obstack more often
- --- say, after processing each compilation unit, or each die ---
- but it turns out that this saves almost nothing. For an
- executable with 11Mb of Dwarf 2 data, I found about 64k allocated
- on dwarf2_tmp_obstack. Some investigation showed:
-
- 1) 69% of the attributes used forms DW_FORM_addr, DW_FORM_data*,
- DW_FORM_flag, DW_FORM_[su]data, and DW_FORM_ref*. These are
- all fixed-length values not requiring dynamic allocation.
-
- 2) 30% of the attributes used the form DW_FORM_string. For
- DW_FORM_string, read_attribute simply hands back a pointer to
- the null-terminated string in info_buffer, so no dynamic
- allocation is needed there either.
-
- 3) The remaining 1% of the attributes all used DW_FORM_block1.
- 75% of those were DW_AT_frame_base location lists for
- functions; the rest were DW_AT_location attributes, probably
- for the global variables.
-
- Anyway, what this all means is that the memory the dwarf2
- reader uses as temporary space reading partial symbols is about
- 0.5% as much as we use for dwarf_*_buffer. That's noise. */
-
- obstack_init (&dwarf2_tmp_obstack);
- back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
-
/* Since the objects we're extracting from .debug_info vary in
length, only the individual functions to extract them (like
read_comp_unit_head and load_partial_die) can really know whether
@@ -1360,7 +1323,6 @@ dwarf2_build_psymtabs_hard (struct objfi
do_cleanups (back_to_inner);
}
- do_cleanups (back_to);
}
/* Process all loaded DIEs for compilation unit CU, starting at FIRST_DIE.
@@ -2053,8 +2015,8 @@ psymtab_to_symtab_1 (struct partial_symt
/* We're in the global namespace. */
processing_current_prefix = "";
- obstack_init (&dwarf2_tmp_obstack);
- back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
+ obstack_init (&cu.comp_unit_obstack);
+ back_to = make_cleanup (free_stack_comp_unit, &cu);
buildsym_init ();
make_cleanup (really_free_pendings, NULL);
@@ -2354,7 +2316,7 @@ add_to_cu_func_list (const char *name, C
struct function_range *thisfn;
thisfn = (struct function_range *)
- obstack_alloc (&dwarf2_tmp_obstack, sizeof (struct function_range));
+ obstack_alloc (&cu->comp_unit_obstack, sizeof (struct function_range));
thisfn->name = name;
thisfn->lowpc = lowpc;
thisfn->highpc = highpc;
@@ -5037,7 +4999,7 @@ read_attribute_value (struct attribute *
info_ptr += bytes_read;
break;
case DW_FORM_block2:
- blk = dwarf_alloc_block ();
+ blk = dwarf_alloc_block (cu);
blk->size = read_2_bytes (abfd, info_ptr);
info_ptr += 2;
blk->data = read_n_bytes (abfd, info_ptr, blk->size);
@@ -5045,7 +5007,7 @@ read_attribute_value (struct attribute *
DW_BLOCK (attr) = blk;
break;
case DW_FORM_block4:
- blk = dwarf_alloc_block ();
+ blk = dwarf_alloc_block (cu);
blk->size = read_4_bytes (abfd, info_ptr);
info_ptr += 4;
blk->data = read_n_bytes (abfd, info_ptr, blk->size);
@@ -5074,7 +5036,7 @@ read_attribute_value (struct attribute *
info_ptr += bytes_read;
break;
case DW_FORM_block:
- blk = dwarf_alloc_block ();
+ blk = dwarf_alloc_block (cu);
blk->size = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
blk->data = read_n_bytes (abfd, info_ptr, blk->size);
@@ -5082,7 +5044,7 @@ read_attribute_value (struct attribute *
DW_BLOCK (attr) = blk;
break;
case DW_FORM_block1:
- blk = dwarf_alloc_block ();
+ blk = dwarf_alloc_block (cu);
blk->size = read_1_byte (abfd, info_ptr);
info_ptr += 1;
blk->data = read_n_bytes (abfd, info_ptr, blk->size);
@@ -8098,19 +8060,13 @@ decode_locdesc (struct dwarf_block *blk,
/* memory allocation interface */
-static void
-dwarf2_free_tmp_obstack (void *ignore)
-{
- obstack_free (&dwarf2_tmp_obstack, NULL);
-}
-
static struct dwarf_block *
-dwarf_alloc_block (void)
+dwarf_alloc_block (struct dwarf2_cu *cu)
{
struct dwarf_block *blk;
blk = (struct dwarf_block *)
- obstack_alloc (&dwarf2_tmp_obstack, sizeof (struct dwarf_block));
+ obstack_alloc (&cu->comp_unit_obstack, sizeof (struct dwarf_block));
return (blk);
}