old-cross-binutils/gdb/block.h
Doug Evans 43f3e411c4 Split struct symtab into two: struct symtab and compunit_symtab.
Currently "symtabs" in gdb are stored as a single linked list of
struct symtab that contains both symbol symtabs (the blockvectors)
and file symtabs (the linetables).

This has led to confusion, bugs, and performance issues.

This patch is conceptually very simple: split struct symtab into
two pieces: one part containing things common across the entire
compilation unit, and one part containing things specific to each
source file.

Example.
For the case of a program built out of these files:

foo.c
  foo1.h
  foo2.h
bar.c
  foo1.h
  bar.h

Today we have a single list of struct symtabs:

objfile -> foo.c -> foo1.h -> foo2.h -> bar.c -> foo1.h -> bar.h -> NULL

where "->" means the "next" pointer in struct symtab.

With this patch, that turns into:

objfile -> foo.c(cu) -> bar.c(cu) -> NULL
            |            |
            v            v
           foo.c        bar.c
            |            |
            v            v
           foo1.h       foo1.h
            |            |
            v            v
           foo2.h       bar.h
            |            |
            v            v
           NULL         NULL

where "foo.c(cu)" and "bar.c(cu)" are struct compunit_symtab objects,
and the files foo.c, etc. are struct symtab objects.

So now, for example, when we want to iterate over all blockvectors
we can now just iterate over the compunit_symtab list.

Plus a lot of the data that was either unused or replicated for each
symtab in a compilation unit now lives in struct compunit_symtab.
E.g., the objfile pointer, the producer string, etc.
I thought of moving "language" out of struct symtab but there is
logic to try to compute the language based on previously seen files,
and I think that's best left as is for now.
With my standard monster benchmark with -readnow (which I can't actually
do, but based on my calculations), whereas today the list requires
77MB to store all the struct symtabs, it now only requires 37MB.
A modest space savings given the gigabytes needed for all the debug info,
etc.  Still, it's nice.  Plus, whereas today we create a copy of dirname
for each source file symtab in a compilation unit, we now only create one
for the compunit.

So this patch is basically just a data structure reorg,
I don't expect significant performance improvements from it.

Notes:

1) A followup patch can do a similar split for struct partial_symtab.
I have left that until after I get the changes I want in to
better utilize .gdb_index (it may affect how we do partial syms).

2) Another followup patch *could* rename struct symtab.
The term "symtab" is ambiguous and has been a source of confusion.
In this patch I'm leaving it alone, calling it the "historical" name
of "filetabs", which is what they are now: just the file-name + line-table.

gdb/ChangeLog:

	Split struct symtab into two: struct symtab and compunit_symtab.
	* amd64-tdep.c (amd64_skip_xmm_prologue): Fetch producer from compunit.
	* block.c (blockvector_for_pc_sect): Change "struct symtab *" argument
	to "struct compunit_symtab *".  All callers updated.
	(set_block_compunit_symtab): Renamed from set_block_symtab.  Change
	"struct symtab *" argument to "struct compunit_symtab *".
	All callers updated.
	(get_block_compunit_symtab): Renamed from get_block_symtab.  Change
	result to "struct compunit_symtab *".  All callers updated.
	(find_iterator_compunit_symtab): Renamed from find_iterator_symtab.
	Change result to "struct compunit_symtab *".  All callers updated.
	* block.h (struct global_block) <compunit_symtab>: Renamed from symtab.
	hange type to "struct compunit_symtab *".  All uses updated.
	(struct block_iterator) <d.compunit_symtab>: Renamed from "d.symtab".
	Change type to "struct compunit_symtab *".  All uses updated.
	* buildsym.c (struct buildsym_compunit): New struct.
	(subfiles, buildsym_compdir, buildsym_objfile, main_subfile): Delete.
	(buildsym_compunit): New static global.
	(finish_block_internal): Update to fetch objfile from
	buildsym_compunit.
	(make_blockvector): Delete objfile argument.
	(start_subfile): Rewrite to use buildsym_compunit.  Don't initialize
	debugformat, producer.
	(start_buildsym_compunit): New function.
	(free_buildsym_compunit): Renamed from free_subfiles_list.
	All callers updated.
	(patch_subfile_names): Rewrite to use buildsym_compunit.
	(get_compunit_symtab): New function.
	(get_macro_table): Delete argument comp_dir.  All callers updated.
	(start_symtab): Change result to "struct compunit_symtab *".
	All callers updated.  Create the subfile of the main source file.
	(watch_main_source_file_lossage): Rewrite to use buildsym_compunit.
	(reset_symtab_globals): Update.
	(end_symtab_get_static_block): Update to use buildsym_compunit.
	(end_symtab_without_blockvector): Rewrite.
	(end_symtab_with_blockvector): Change result to
	"struct compunit_symtab *".  All callers updated.
	Update to use buildsym_compunit.  Don't set symtab->dirname,
	instead set it in the compunit.
	Explicitly make sure main symtab is first in its list.
	Set debugformat, producer, blockvector, block_line_section, and
	macrotable in the compunit.
	(end_symtab_from_static_block): Change result to
	"struct compunit_symtab *".  All callers updated.
	(end_symtab, end_expandable_symtab): Ditto.
	(set_missing_symtab): Change symtab argument to
	"struct compunit_symtab *".  All callers updated.
	(augment_type_symtab): Ditto.
	(record_debugformat): Update to use buildsym_compunit.
	(record_producer): Update to use buildsym_compunit.
	* buildsym.h (struct subfile) <dirname>: Delete.
	<producer, debugformat>: Delete.
	<buildsym_compunit>: New member.
	(get_compunit_symtab): Declare.
	* dwarf2read.c (struct type_unit_group) <compunit_symtab>: Renamed
	from primary_symtab.  Change type to "struct compunit_symtab *".
	All uses updated.
	(dwarf2_start_symtab): Change result to "struct compunit_symtab *".
	All callers updated.
	(dwarf_decode_macros): Delete comp_dir argument.  All callers updated.
	(struct dwarf2_per_cu_quick_data) <compunit_symtab>: Renamed from
	symtab.  Change type to "struct compunit_symtab *".  All uses updated.
	(dw2_instantiate_symtab): Change result to "struct compunit_symtab *".
	All callers updated.
	(dw2_find_last_source_symtab): Ditto.
	(dw2_lookup_symbol): Ditto.
	(recursively_find_pc_sect_compunit_symtab): Renamed from
	recursively_find_pc_sect_symtab.  Change result to
	"struct compunit_symtab *".  All callers updated.
	(dw2_find_pc_sect_compunit_symtab): Renamed from
	dw2_find_pc_sect_symtab.  Change result to
	"struct compunit_symtab *".  All callers updated.
	(get_compunit_symtab): Renamed from get_symtab.  Change result to
	"struct compunit_symtab *".  All callers updated.
	(recursively_compute_inclusions): Change type of immediate_parent
	argument to "struct compunit_symtab *".  All callers updated.
	(compute_compunit_symtab_includes): Renamed from
	compute_symtab_includes.  All callers updated.  Rewrite to compute
	includes of compunit_symtabs and not symtabs.
	(process_full_comp_unit): Update to work with struct compunit_symtab.
	(process_full_type_unit): Ditto.
	(dwarf_decode_lines_1): Delete argument comp_dir.  All callers updated.
	(dwarf_decode_lines): Remove special case handling of main subfile.
	(macro_start_file): Delete argument comp_dir.  All callers updated.
	(dwarf_decode_macro_bytes): Ditto.
	* guile/scm-block.c (bkscm_print_block_syms_progress_smob): Update to
	use struct compunit_symtab.
	* i386-tdep.c (i386_skip_prologue): Fetch producer from compunit.
	* jit.c (finalize_symtab): Build compunit_symtab.
	* jv-lang.c (get_java_class_symtab): Change result to
	"struct compunit_symtab *".  All callers updated.
	* macroscope.c (sal_macro_scope): Fetch macro table from compunit.
	* macrotab.c (struct macro_table) <compunit_symtab>: Renamed from
	comp_dir.  Change type to "struct compunit_symtab *".
	All uses updated.
	(new_macro_table): Change comp_dir argument to cust,
	"struct compunit_symtab *".  All callers updated.
	* maint.c (struct cmd_stats) <nr_compunit_symtabs>: Renamed from
	nr_primary_symtabs.  All uses updated.
	(count_symtabs_and_blocks): Update to handle compunits.
	(report_command_stats): Update output, "primary symtabs" renamed to
	"compunits".
	* mdebugread.c (new_symtab): Change result to
	"struct compunit_symtab *".  All callers updated.
	(parse_procedure): Change type of search_symtab argument to
	"struct compunit_symtab *".  All callers updated.
	* objfiles.c (objfile_relocate1): Loop over blockvectors in a
	separate loop.
	* objfiles.h (struct objfile) <compunit_symtabs>: Renamed from
	symtabs.  Change type to "struct compunit_symtab *".  All uses updated.
	(ALL_OBJFILE_FILETABS): Renamed from ALL_OBJFILE_SYMTABS.
	All uses updated.
	(ALL_OBJFILE_COMPUNITS): Renamed from ALL_OBJFILE_PRIMARY_SYMTABS.
	All uses updated.
	(ALL_FILETABS): Renamed from ALL_SYMTABS.  All uses updated.
	(ALL_COMPUNITS): Renamed from ALL_PRIMARY_SYMTABS.  All uses updated.
	* psympriv.h (struct partial_symtab) <compunit_symtab>: Renamed from
	symtab.  Change type to "struct compunit_symtab *".  All uses updated.
	* psymtab.c (psymtab_to_symtab): Change result type to
	"struct compunit_symtab *".  All callers updated.
	(find_pc_sect_compunit_symtab_from_partial): Renamed from
	find_pc_sect_symtab_from_partial.  Change result type to
	"struct compunit_symtab *".  All callers updated.
	(lookup_symbol_aux_psymtabs): Change result type to
	"struct compunit_symtab *".  All callers updated.
	(find_last_source_symtab_from_partial): Ditto.
	* python/py-symtab.c (stpy_get_producer): Fetch producer from compunit.
	* source.c (forget_cached_source_info_for_objfile): Fetch debugformat
	and macro_table from compunit.
	* symfile-debug.c (debug_qf_find_last_source_symtab): Change result
	type to "struct compunit_symtab *".  All callers updated.
	(debug_qf_lookup_symbol): Ditto.
	(debug_qf_find_pc_sect_compunit_symtab): Renamed from
	debug_qf_find_pc_sect_symtab, change result type to
	"struct compunit_symtab *".  All callers updated.
	* symfile.c (allocate_symtab): Delete objfile argument.
	New argument cust.
	(allocate_compunit_symtab): New function.
	(add_compunit_symtab_to_objfile): New function.
	* symfile.h (struct quick_symbol_functions) <lookup_symbol>:
	Change result type to "struct compunit_symtab *".  All uses updated.
	<find_pc_sect_compunit_symtab>: Renamed from find_pc_sect_symtab.
	Change result type to "struct compunit_symtab *".  All uses updated.
	* symmisc.c (print_objfile_statistics): Compute blockvector count in
	separate loop.
	(dump_symtab_1): Update test for primary source symtab.
	(maintenance_info_symtabs): Update to handle compunit symtabs.
	(maintenance_check_symtabs): Ditto.
	* symtab.c (set_primary_symtab): Delete.
	(compunit_primary_filetab): New function.
	(compunit_language): New function.
	(iterate_over_some_symtabs): Change type of arguments "first",
	"after_last" to "struct compunit_symtab *".  All callers updated.
	Update to loop over symtabs in each compunit.
	(error_in_psymtab_expansion): Rename symtab argument to cust,
	and change type to "struct compunit_symtab *".  All callers updated.
	(find_pc_sect_compunit_symtab): Renamed from find_pc_sect_symtab.
	Change result type to "struct compunit_symtab *".  All callers updated.
	(find_pc_compunit_symtab): Renamed from find_pc_symtab.
	Change result type to "struct compunit_symtab *".  All callers updated.
	(find_pc_sect_line): Only loop over symtabs within selected compunit
	instead of all symtabs in the objfile.
	* symtab.h (struct symtab) <blockvector>: Moved to compunit_symtab.
	<compunit_symtab> New member.
	<block_line_section>: Moved to compunit_symtab.
	<locations_valid>: Ditto.
	<epilogue_unwind_valid>: Ditto.
	<macro_table>: Ditto.
	<dirname>: Ditto.
	<debugformat>: Ditto.
	<producer>: Ditto.
	<objfile>: Ditto.
	<call_site_htab>: Ditto.
	<includes>: Ditto.
	<user>: Ditto.
	<primary>: Delete
	(SYMTAB_COMPUNIT): New macro.
	(SYMTAB_BLOCKVECTOR): Update definition.
	(SYMTAB_OBJFILE): Update definition.
	(SYMTAB_DIRNAME): Update definition.
	(struct compunit_symtab): New type.  Common members among all source
	symtabs within a compilation unit moved here.  All uses updated.
	(COMPUNIT_OBJFILE): New macro.
	(COMPUNIT_FILETABS): New macro.
	(COMPUNIT_DEBUGFORMAT): New macro.
	(COMPUNIT_PRODUCER): New macro.
	(COMPUNIT_DIRNAME): New macro.
	(COMPUNIT_BLOCKVECTOR): New macro.
	(COMPUNIT_BLOCK_LINE_SECTION): New macro.
	(COMPUNIT_LOCATIONS_VALID): New macro.
	(COMPUNIT_EPILOGUE_UNWIND_VALID): New macro.
	(COMPUNIT_CALL_SITE_HTAB): New macro.
	(COMPUNIT_MACRO_TABLE): New macro.
	(ALL_COMPUNIT_FILETABS): New macro.
	(compunit_symtab_ptr): New typedef.
	(DEF_VEC_P (compunit_symtab_ptr)): New vector type.

gdb/testsuite/ChangeLog:

	* gdb.base/maint.exp: Update expected output.
2014-11-20 07:47:44 -08:00

297 lines
10 KiB
C

/* Code dealing with blocks for GDB.
Copyright (C) 2003-2014 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef BLOCK_H
#define BLOCK_H
#include "dictionary.h"
/* Opaque declarations. */
struct symbol;
struct compunit_symtab;
struct block_namespace_info;
struct using_direct;
struct obstack;
struct addrmap;
/* All of the name-scope contours of the program
are represented by `struct block' objects.
All of these objects are pointed to by the blockvector.
Each block represents one name scope.
Each lexical context has its own block.
The blockvector begins with some special blocks.
The GLOBAL_BLOCK contains all the symbols defined in this compilation
whose scope is the entire program linked together.
The STATIC_BLOCK contains all the symbols whose scope is the
entire compilation excluding other separate compilations.
Blocks starting with the FIRST_LOCAL_BLOCK are not special.
Each block records a range of core addresses for the code that
is in the scope of the block. The STATIC_BLOCK and GLOBAL_BLOCK
give, for the range of code, the entire range of code produced
by the compilation that the symbol segment belongs to.
The blocks appear in the blockvector
in order of increasing starting-address,
and, within that, in order of decreasing ending-address.
This implies that within the body of one function
the blocks appear in the order of a depth-first tree walk. */
struct block
{
/* Addresses in the executable code that are in this block. */
CORE_ADDR startaddr;
CORE_ADDR endaddr;
/* The symbol that names this block, if the block is the body of a
function (real or inlined); otherwise, zero. */
struct symbol *function;
/* The `struct block' for the containing block, or 0 if none.
The superblock of a top-level local block (i.e. a function in the
case of C) is the STATIC_BLOCK. The superblock of the
STATIC_BLOCK is the GLOBAL_BLOCK. */
struct block *superblock;
/* This is used to store the symbols in the block. */
struct dictionary *dict;
/* Used for language-specific info. */
union
{
struct
{
/* Contains information about namespace-related info relevant to
this block: using directives and the current namespace
scope. */
struct block_namespace_info *namespace;
}
cplus_specific;
}
language_specific;
};
/* The global block is singled out so that we can provide a back-link
to the compunit symtab. */
struct global_block
{
/* The block. */
struct block block;
/* This holds a pointer to the compunit symtab holding this block. */
struct compunit_symtab *compunit_symtab;
};
#define BLOCK_START(bl) (bl)->startaddr
#define BLOCK_END(bl) (bl)->endaddr
#define BLOCK_FUNCTION(bl) (bl)->function
#define BLOCK_SUPERBLOCK(bl) (bl)->superblock
#define BLOCK_DICT(bl) (bl)->dict
#define BLOCK_NAMESPACE(bl) (bl)->language_specific.cplus_specific.namespace
struct blockvector
{
/* Number of blocks in the list. */
int nblocks;
/* An address map mapping addresses to blocks in this blockvector.
This pointer is zero if the blocks' start and end addresses are
enough. */
struct addrmap *map;
/* The blocks themselves. */
struct block *block[1];
};
#define BLOCKVECTOR_NBLOCKS(blocklist) (blocklist)->nblocks
#define BLOCKVECTOR_BLOCK(blocklist,n) (blocklist)->block[n]
#define BLOCKVECTOR_MAP(blocklist) ((blocklist)->map)
extern struct symbol *block_linkage_function (const struct block *);
extern struct symbol *block_containing_function (const struct block *);
extern int block_inlined_p (const struct block *block);
extern int contained_in (const struct block *, const struct block *);
extern const struct blockvector *blockvector_for_pc (CORE_ADDR,
const struct block **);
extern const struct blockvector *
blockvector_for_pc_sect (CORE_ADDR, struct obj_section *,
const struct block **, struct compunit_symtab *);
extern int blockvector_contains_pc (const struct blockvector *bv, CORE_ADDR pc);
extern struct call_site *call_site_for_pc (struct gdbarch *gdbarch,
CORE_ADDR pc);
extern const struct block *block_for_pc (CORE_ADDR);
extern const struct block *block_for_pc_sect (CORE_ADDR, struct obj_section *);
extern const char *block_scope (const struct block *block);
extern void block_set_scope (struct block *block, const char *scope,
struct obstack *obstack);
extern struct using_direct *block_using (const struct block *block);
extern void block_set_using (struct block *block,
struct using_direct *using,
struct obstack *obstack);
extern const struct block *block_static_block (const struct block *block);
extern const struct block *block_global_block (const struct block *block);
extern struct block *allocate_block (struct obstack *obstack);
extern struct block *allocate_global_block (struct obstack *obstack);
extern void set_block_compunit_symtab (struct block *,
struct compunit_symtab *);
/* A block iterator. This structure should be treated as though it
were opaque; it is only defined here because we want to support
stack allocation of iterators. */
struct block_iterator
{
/* If we're iterating over a single block, this holds the block.
Otherwise, it holds the canonical compunit. */
union
{
struct compunit_symtab *compunit_symtab;
const struct block *block;
} d;
/* If we're iterating over a single block, this is always -1.
Otherwise, it holds the index of the current "included" symtab in
the canonical symtab (that is, d.symtab->includes[idx]), with -1
meaning the canonical symtab itself. */
int idx;
/* Which block, either static or global, to iterate over. If this
is FIRST_LOCAL_BLOCK, then we are iterating over a single block.
This is used to select which field of 'd' is in use. */
enum block_enum which;
/* The underlying dictionary iterator. */
struct dict_iterator dict_iter;
};
/* Initialize ITERATOR to point at the first symbol in BLOCK, and
return that first symbol, or NULL if BLOCK is empty. */
extern struct symbol *block_iterator_first (const struct block *block,
struct block_iterator *iterator);
/* Advance ITERATOR, and return the next symbol, or NULL if there are
no more symbols. Don't call this if you've previously received
NULL from block_iterator_first or block_iterator_next on this
iteration. */
extern struct symbol *block_iterator_next (struct block_iterator *iterator);
/* Initialize ITERATOR to point at the first symbol in BLOCK whose
SYMBOL_SEARCH_NAME is NAME (as tested using strcmp_iw), and return
that first symbol, or NULL if there are no such symbols. */
extern struct symbol *block_iter_name_first (const struct block *block,
const char *name,
struct block_iterator *iterator);
/* Advance ITERATOR to point at the next symbol in BLOCK whose
SYMBOL_SEARCH_NAME is NAME (as tested using strcmp_iw), or NULL if
there are no more such symbols. Don't call this if you've
previously received NULL from block_iterator_first or
block_iterator_next on this iteration. And don't call it unless
ITERATOR was created by a previous call to block_iter_name_first
with the same NAME. */
extern struct symbol *block_iter_name_next (const char *name,
struct block_iterator *iterator);
/* Initialize ITERATOR to point at the first symbol in BLOCK whose
SYMBOL_SEARCH_NAME is NAME, as tested using COMPARE (which must use
the same conventions as strcmp_iw and be compatible with any
block hashing function), and return that first symbol, or NULL
if there are no such symbols. */
extern struct symbol *block_iter_match_first (const struct block *block,
const char *name,
symbol_compare_ftype *compare,
struct block_iterator *iterator);
/* Advance ITERATOR to point at the next symbol in BLOCK whose
SYMBOL_SEARCH_NAME is NAME, as tested using COMPARE (see
block_iter_match_first), or NULL if there are no more such symbols.
Don't call this if you've previously received NULL from
block_iterator_match_first or block_iterator_match_next on this
iteration. And don't call it unless ITERATOR was created by a
previous call to block_iter_match_first with the same NAME and COMPARE. */
extern struct symbol *block_iter_match_next (const char *name,
symbol_compare_ftype *compare,
struct block_iterator *iterator);
/* Search BLOCK for symbol NAME in DOMAIN. */
extern struct symbol *block_lookup_symbol (const struct block *block,
const char *name,
const domain_enum domain);
/* Macro to loop through all symbols in BLOCK, in no particular
order. ITER helps keep track of the iteration, and must be a
struct block_iterator. SYM points to the current symbol. */
#define ALL_BLOCK_SYMBOLS(block, iter, sym) \
for ((sym) = block_iterator_first ((block), &(iter)); \
(sym); \
(sym) = block_iterator_next (&(iter)))
/* Macro to loop through all symbols with name NAME in BLOCK,
in no particular order. ITER helps keep track of the iteration, and
must be a struct block_iterator. SYM points to the current symbol. */
#define ALL_BLOCK_SYMBOLS_WITH_NAME(block, name, iter, sym) \
for ((sym) = block_iter_name_first ((block), (name), &(iter)); \
(sym) != NULL; \
(sym) = block_iter_name_next ((name), &(iter)))
#endif /* BLOCK_H */