[rfa] save space by using enum bitfields

Michael Elizabeth Chastain
2003-08-18T07:00:52Z

This adds an ENUM_BITFIELD macro to defs.h and uses it in the
symbol table to save space.

Per Andrew C, this version uses the same macro that gcc 3.3.1, for the
sake of inter-project consistency. The macro is in defs.h so that
any structure definition can use it, if they want.

In gcc land, Zack Weinberg originally did an autoconf test, but then he
ran into platforms where the autoconf test succeeded but the compiler
generated buggy code. So now gcc does an explicit test on the compiler
used (gcc version 2 or later). I wrote this patch the same way.

If the compiler does not give us enum bitfields, then we can choose
between integer bitfields (still save space) or full-width enum
(chew up space, improve debugability). The gcc code chose the
former, so I followed it.

Testing: I ran the test suite with gcc v2 and v3, dwarf-2 and stabs+,
binutils 2.14. I also tested the non-gcc case by putting an "#if 0"
into the feature test in order to get the non-gcc path.

Size reduction (on my vanilla native i686-pc-linux-gnu):

struct general_symbol_info 24 20
struct minimal_symbol 44 40
struct symbol 60 48
struct partial_symbol 32 24
struct symtab 68 64

I also loaded a medium-sized program (a specific version of gdb) with a
debugging version of libc and measured memory usage at the first command
prompt with 'ps axu'. Total memory usage dropped from 23420 kilobytes
to 23280 kilobytes, a savings of 0.6%. Sigh.

Comments?

OK to apply?

Michael C

2003-08-17 Michael Chastain <mec@shout.net>

* defs.h (ENUM_BITFIELD): New macro.
* symtab.h (ENUM_BITFIELD): Use it.
(BYTE_BITFIELD): Remove old macro, which was already disabled.

Index: defs.h
===================================================================
RCS file: /cvs/src/src/gdb/defs.h,v
retrieving revision 1.127
diff -c -3 -p -r1.127 defs.h
*** defs.h 9 Aug 2003 14:57:30 -0000 1.127
--- defs.h 17 Aug 2003 23:17:26 -0000
*************** struct cleanup
*** 285,290 ****
--- 285,299 ----
#endif
#endif

+ /* Be conservative and use enum bitfields only with GCC.
+ This is copied from gcc 3.3.1, system.h. */
+
+ #if defined(__GNUC__) && (__GNUC__ >= 2)
+ #define ENUM_BITFIELD(TYPE) enum TYPE
+ #else
+ #define ENUM_BITFIELD(TYPE) unsigned int
+ #endif
+
/* Needed for various prototypes */

struct symtab;
Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.77
diff -c -3 -p -r1.77 symtab.h
*** symtab.h 22 Jul 2003 15:41:59 -0000 1.77
--- symtab.h 17 Aug 2003 23:17:28 -0000
*************** struct blockvector;
*** 35,51 ****
struct axs_value;
struct agent_expr;

- /* Don't do this; it means that if some .o's are compiled with GNU C
- and some are not (easy to do accidentally the way we configure
- things; also it is a pain to have to "make clean" every time you
- want to switch compilers), then GDB dies a horrible death. */
- /* GNU C supports enums that are bitfields. Some compilers don't. */
- #if 0 && defined(__GNUC__) && !defined(BYTE_BITFIELD)
- #define BYTE_BITFIELD :8;
- #else
- #define BYTE_BITFIELD /*nothing */
- #endif
-
/* Define a structure for the information that is common to all symbol types,
including minimal symbols, partial symbols, and full symbols. In a
multilanguage environment, some language specific information may need to
--- 35,40 ----
*************** struct general_symbol_info
*** 107,113 ****
This is used to select one of the fields from the language specific
union above. */

! enum language language BYTE_BITFIELD;

/* Which section is this symbol in? This is an index into
section_offsets for this objfile. Negative means that the symbol
--- 96,102 ----
This is used to select one of the fields from the language specific
union above. */

! ENUM_BITFIELD(language) language : 8;

/* Which section is this symbol in? This is an index into
section_offsets for this objfile. Negative means that the symbol
*************** struct minimal_symbol
*** 297,304 ****
mst_file_text, /* Static version of mst_text */
mst_file_data, /* Static version of mst_data */
mst_file_bss /* Static version of mst_bss */
! }
! type BYTE_BITFIELD;

/* Minimal symbols with the same hash key are kept on a linked
list. This is the link. */
--- 286,294 ----
mst_file_text, /* Static version of mst_text */
mst_file_data, /* Static version of mst_data */
mst_file_bss /* Static version of mst_bss */
! };
!
! ENUM_BITFIELD(minimal_symbol_type) type : 8;

/* Minimal symbols with the same hash key are kept on a linked
list. This is the link. */
*************** struct minimal_symbol
*** 321,327 ****
/* Different name domains for symbols. Looking up a symbol specifies a
domain and ignores symbol definitions in other name domains. */

! typedef enum
{
/* UNDEF_DOMAIN is used when a domain has not been discovered or
none of the following apply. This usually indicates an error either
--- 311,317 ----
/* Different name domains for symbols. Looking up a symbol specifies a
domain and ignores symbol definitions in other name domains. */

! typedef enum domain_enum_tag
{
/* UNDEF_DOMAIN is used when a domain has not been discovered or
none of the following apply. This usually indicates an error either
*************** struct symbol
*** 578,588 ****

/* Domain code. */

! domain_enum domain BYTE_BITFIELD;

/* Address class */

! enum address_class aclass BYTE_BITFIELD;

/* Line number of definition. FIXME: Should we really make the assumption
that nobody will try to debug files longer than 64K lines? What about
--- 568,578 ----

/* Domain code. */

! ENUM_BITFIELD(domain_enum_tag) domain : 8;

/* Address class */

! ENUM_BITFIELD(address_class) aclass : 8;

/* Line number of definition. FIXME: Should we really make the assumption
that nobody will try to debug files longer than 64K lines? What about
*************** struct partial_symbol
*** 655,665 ****

/* Name space code. */

! domain_enum domain BYTE_BITFIELD;

/* Address class (for info_symbols) */

! enum address_class aclass BYTE_BITFIELD;

};

--- 645,655 ----

/* Name space code. */

! ENUM_BITFIELD(domain_enum_tag) domain : 8;

/* Address class (for info_symbols) */

! ENUM_BITFIELD(address_class) aclass : 8;

};

*************** struct symtab
*** 775,793 ****

char *dirname;

- /* This component says how to free the data we point to:
- free_contents => do a tree walk and free each object.
- free_nothing => do nothing; some other symtab will free
- the data this one uses.
- free_linetable => free just the linetable. FIXME: Is this redundant
- with the primary field? */
-
- enum free_code
- {
- free_nothing, free_contents, free_linetable
- }
- free_code;
-
/* A function to call to free space, if necessary. This is IN
ADDITION to the action indicated by free_code. */

--- 765,770 ----
*************** struct symtab
*** 803,811 ****

int *line_charpos;

/* Language of this source file. */

! enum language language;

/* String that identifies the format of the debugging information, such
as "stabs", "dwarf 1", "dwarf 2", "coff", etc. This is mostly useful
--- 780,802 ----

int *line_charpos;

+ /* This component says how to free the data we point to:
+ free_contents => do a tree walk and free each object.
+ free_nothing => do nothing; some other symtab will free
+ the data this one uses.
+ free_linetable => free just the linetable. FIXME: Is this redundant
+ with the primary field? */
+
+ enum free_code
+ {
+ free_nothing, free_contents, free_linetable
+ };
+
+ ENUM_BITFIELD(free_code) free_code : 8;
+
/* Language of this source file. */

! ENUM_BITFIELD(language) language : 8;

/* String that identifies the format of the debugging information, such
as "stabs", "dwarf 1", "dwarf 2", "coff", etc. This is mostly useful