stringpool.c revision 225736
11844Swollman/* String pool for GCC.
250476Speter   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
31844Swollman   Free Software Foundation, Inc.
41638Srgrimes
594940SruThis file is part of GCC.
61638Srgrimes
742915SjdpGCC is free software; you can redistribute it and/or modify it under
842915Sjdpthe terms of the GNU General Public License as published by the Free
942915SjdpSoftware Foundation; either version 2, or (at your option) any later
1042915Sjdpversion.
1142915Sjdp
1242915SjdpGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1342915SjdpWARRANTY; without even the implied warranty of MERCHANTABILITY or
1442915SjdpFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1599362Srufor more details.
1642915Sjdp
1729141SpeterYou should have received a copy of the GNU General Public License
18125119Srualong with GCC; see the file COPYING.  If not, write to the Free
19100332SruSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20100332Sru02110-1301, USA.  */
2142915Sjdp
2242915Sjdp/* String text, identifier text and identifier node allocator.  Strings
2329141Speter   allocated by ggc_alloc_string are stored in an obstack which is
24119607Sru   never shrunk.  Identifiers are uniquely stored in a hash table.
25117034Sgordon
26119607Sru   We use cpplib's hash table implementation.  libiberty's
27117034Sgordon   hashtab.c is not used because it requires 100% average space
282827Sjkh   overhead per string, which is unacceptable.  Also, this algorithm
292827Sjkh   is faster.  */
302827Sjkh
312827Sjkh#include "config.h"
322827Sjkh#include "system.h"
331638Srgrimes#include "coretypes.h"
342827Sjkh#include "tm.h"
351638Srgrimes#include "ggc.h"
3618529Sbde#include "tree.h"
3718529Sbde#include "symtab.h"
381638Srgrimes#include "cpplib.h"
3942450Sjdp
401638Srgrimes/* The "" allocated string.  */
41117173Sruconst char empty_string[] = "";
421638Srgrimes
4396512Sru/* Character strings, each containing a single decimal digit.
4496512Sru   Written this way to save space.  */
4596512Sruconst char digit_vector[] = {
4696512Sru  '0', 0, '1', 0, '2', 0, '3', 0, '4', 0,
4796512Sru  '5', 0, '6', 0, '7', 0, '8', 0, '9', 0
4896512Sru};
4996512Sru
5096512Srustruct ht *ident_hash;
51126890Strhodesstatic struct obstack string_stack;
52126890Strhodes
53126890Strhodesstatic hashnode alloc_node (hash_table *);
54126890Strhodesstatic int mark_ident (struct cpp_reader *, hashnode, const void *);
55126890Strhodes
56126890Strhodesstatic void *
571638Srgrimesstringpool_ggc_alloc (size_t x)
58126890Strhodes{
591638Srgrimes  return ggc_alloc (x);
6042450Sjdp}
611844Swollman
621844Swollman/* Initialize the string pool.  */
6336673Sdtvoid
64126890Strhodesinit_stringpool (void)
651844Swollman{
6642450Sjdp  /* Create with 16K (2^14) entries.  */
671844Swollman  ident_hash = ht_create (14);
681844Swollman  ident_hash->alloc_node = alloc_node;
691844Swollman  ident_hash->alloc_subobject = stringpool_ggc_alloc;
70127027Strhodes  gcc_obstack_init (&string_stack);
711844Swollman}
7242450Sjdp
731844Swollman/* Allocate a hash node.  */
741844Swollmanstatic hashnode
7536054Sbdealloc_node (hash_table *table ATTRIBUTE_UNUSED)
7636054Sbde{
7736054Sbde  return GCC_IDENT_TO_HT_IDENT (make_node (IDENTIFIER_NODE));
7842450Sjdp}
7936054Sbde
8036054Sbde/* Allocate and return a string constant of length LENGTH, containing
81117173Sru   CONTENTS.  If LENGTH is -1, CONTENTS is assumed to be a
82117159Sru   nul-terminated string, and the length is calculated using strlen.
831638Srgrimes   If the same string constant has been allocated before, that copy is
84117173Sru   returned this time too.  */
85117173Sru
86117173Sruconst char *
87117173Sruggc_alloc_string (const char *contents, int length)
88117173Sru{
89117173Sru  if (length == -1)
90117173Sru    length = strlen (contents);
911844Swollman
92117122Sru  if (length == 0)
931844Swollman    return empty_string;
9442450Sjdp  if (length == 1 && ISDIGIT (contents[0]))
95117122Sru    return digit_string (contents[0] - '0');
961844Swollman
9796512Sru  obstack_grow0 (&string_stack, contents, length);
981638Srgrimes  return XOBFINISH (&string_stack, const char *);
9999362Sru}
10099362Sru
10199362Sru/* Return an IDENTIFIER_NODE whose name is TEXT (a null-terminated string).
10299362Sru   If an identifier with that name has previously been referred to,
10396512Sru   the same node is returned this time.  */
10496512Sru
1051638Srgrimes#undef get_identifier
10696512Sru
10796512Srutree
10896512Sruget_identifier (const char *text)
10996512Sru{
11096512Sru  hashnode ht_node = ht_lookup (ident_hash,
11199362Sru				(const unsigned char *) text,
1121638Srgrimes				strlen (text), HT_ALLOC);
11396512Sru
11495114Sobrien  /* ht_node can't be NULL here.  */
11599362Sru  return HT_IDENT_TO_GCC_IDENT (ht_node);
11696512Sru}
11796512Sru
11895306Sru/* Identical to get_identifier, except that the length is assumed
11996512Sru   known.  */
12096512Sru
12196512Srutree
12296512Sruget_identifier_with_length (const char *text, size_t length)
12396512Sru{
12474805Sru  hashnode ht_node = ht_lookup (ident_hash,
1251844Swollman				(const unsigned char *) text,
12699362Sru				length, HT_ALLOC);
12799362Sru
12896512Sru  /* ht_node can't be NULL here.  */
12999362Sru  return HT_IDENT_TO_GCC_IDENT (ht_node);
1301844Swollman}
13196512Sru
13296512Sru/* If an identifier with the name TEXT (a null-terminated string) has
1331638Srgrimes   previously been referred to, return that node; otherwise return
13442915Sjdp   NULL_TREE.  */
13542915Sjdp
13696512Srutree
13742915Sjdpmaybe_get_identifier (const char *text)
13896512Sru{
13942915Sjdp  hashnode ht_node;
14096343Sobrien
14196512Sru  ht_node = ht_lookup (ident_hash, (const unsigned char *) text,
14291011Sru		       strlen (text), HT_NO_INSERT);
14328945Speter  if (ht_node)
1441844Swollman    return HT_IDENT_TO_GCC_IDENT (ht_node);
14599362Sru
14696512Sru  return NULL_TREE;
14796512Sru}
14896512Sru
1492353Sbde/* Report some basic statistics about the string pool.  */
15096512Sru
15196512Sruvoid
15296512Srustringpool_statistics (void)
1533859Sbde{
1541844Swollman  ht_dump_statistics (ident_hash);
155103713Smarkm}
15696512Sru
15796512Sru/* Mark an identifier for GC.  */
15896512Sru
15996512Srustatic int
16092491Smarkmmark_ident (struct cpp_reader *pfile ATTRIBUTE_UNUSED, hashnode h,
16196512Sru	    const void *v ATTRIBUTE_UNUSED)
16296512Sru{
16392491Smarkm  gt_ggc_m_9tree_node (HT_IDENT_TO_GCC_IDENT (h));
16492491Smarkm  return 1;
1651638Srgrimes}
166126938Strhodes
16796512Sru/* Mark the trees hanging off the identifier node for GGC.  These are
16896512Sru   handled specially (not using gengtype) because of the special
16996512Sru   treatment for strings.  */
17096512Sru
17196512Sruvoid
1721638Srgrimesggc_mark_stringpool (void)
1731638Srgrimes{
17434179Sbde  ht_forall (ident_hash, mark_ident, NULL);
17524750Sbde}
17642450Sjdp
17724750Sbde/* Strings are _not_ GCed, but this routine exists so that a separate
17824750Sbde   roots table isn't needed for the few global variables that refer
17942915Sjdp   to strings.  */
18031809Sbde
18142915Sjdpvoid
18227910Sasamigt_ggc_m_S (void *x ATTRIBUTE_UNUSED)
18328945Speter{
1841638Srgrimes}
1851638Srgrimes
1861638Srgrimes/* Pointer-walking routine for strings (not very interesting, since
18748204Sjmg   strings don't contain pointers).  */
1882298Swollman
1892298Swollmanvoid
1902298Swollmangt_pch_p_S (void *obj ATTRIBUTE_UNUSED, void *x ATTRIBUTE_UNUSED,
19149328Shoek	    gt_pointer_operator op ATTRIBUTE_UNUSED,
19249328Shoek	    void *cookie ATTRIBUTE_UNUSED)
19349328Shoek{
19449328Shoek}
19556971Sru
19649328Shoek/* PCH pointer-walking routine for strings.  */
19749328Shoek
19849328Shoekvoid
19949328Shoekgt_pch_n_S (const void *x)
20099362Sru{
20195306Sru  gt_pch_note_object ((void *)x, (void *)x, &gt_pch_p_S,
20299343Sru		      gt_types_enum_last);
20395306Sru}
20499362Sru
20592980Sdes/* Handle saving and restoring the string pool for PCH.  */
20649328Shoek
20796512Sru/* SPD is saved in the PCH file and holds the information needed
20899362Sru   to restore the string pool.  */
20992980Sdes
21049328Shoekstruct string_pool_data GTY(())
2111638Srgrimes{
212116144Sobrien  struct ht_identifier * *
213100872Sru    GTY((length ("%h.nslots"),
21449328Shoek	 nested_ptr (union tree_node, "%h ? GCC_IDENT_TO_HT_IDENT (%h) : NULL",
21542915Sjdp		     "%h ? HT_IDENT_TO_GCC_IDENT (%h) : NULL")))
21642915Sjdp    entries;
217119846Sru  unsigned int nslots;
218119846Sru  unsigned int nelements;
219119846Sru};
220119846Sru
221119730Speterstatic GTY(()) struct string_pool_data * spd;
222119846Sru
223119846Sru/* Save the stringpool data in SPD.  */
224119846Sru
2251844Swollmanvoid
22628945Spetergt_pch_save_stringpool (void)
227119730Speter{
228119846Sru  spd = ggc_alloc (sizeof (*spd));
22999362Sru  spd->nslots = ident_hash->nslots;
230100872Sru  spd->nelements = ident_hash->nelements;
23149328Shoek  spd->entries = ggc_alloc (sizeof (spd->entries[0]) * spd->nslots);
2321844Swollman  memcpy (spd->entries, ident_hash->entries,
233103713Smarkm	  spd->nslots * sizeof (spd->entries[0]));
234100872Sru}
23596462Sru
23696462Sru/* Return the stringpool to its state before gt_pch_save_stringpool
23799362Sru   was called.  */
23896462Sru
23997769Sruvoid
24096668Srugt_pch_fixup_stringpool (void)
24199256Sru{
24296462Sru}
24396162Sru
24496164Sru/* A PCH file has been restored, which loaded SPD; fill the real hash table
24599343Sru   from SPD.  */
24696162Sru
24796162Sruvoid
2481638Srgrimesgt_pch_restore_stringpool (void)
2491638Srgrimes{
2501638Srgrimes  ht_load (ident_hash, spd->entries, spd->nslots, spd->nelements, false);
25195306Sru  spd = NULL;
252103713Smarkm}
2531638Srgrimes
2541638Srgrimes#include "gt-stringpool.h"
2551844Swollman