]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/stringpool.c
utils.c (init_gnat_to_gnu): Use typed GC allocation.
[thirdparty/gcc.git] / gcc / stringpool.c
CommitLineData
520a57c8 1/* String pool for GCC.
a9429e29 2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
a2130901 3 Free Software Foundation, Inc.
520a57c8 4
1322177d 5This file is part of GCC.
520a57c8 6
1322177d
LB
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9dcd6f09 9Software Foundation; either version 3, or (at your option) any later
1322177d 10version.
520a57c8 11
1322177d
LB
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
520a57c8
ZW
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
9dcd6f09
NC
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
520a57c8 20
d1f43464
TT
21/* String text, identifier text and identifier node allocator.
22 Identifiers are uniquely stored in a hash table.
520a57c8 23
4f4e53dd 24 We use cpplib's hash table implementation. libiberty's
2a967f3d
NB
25 hashtab.c is not used because it requires 100% average space
26 overhead per string, which is unacceptable. Also, this algorithm
27 is faster. */
520a57c8
ZW
28
29#include "config.h"
30#include "system.h"
4977bab6
ZW
31#include "coretypes.h"
32#include "tm.h"
520a57c8 33#include "ggc.h"
a9429e29 34#include "ggc-internal.h"
520a57c8 35#include "tree.h"
4f4e53dd 36#include "symtab.h"
d24ecd21 37#include "cpplib.h"
520a57c8
ZW
38
39/* The "" allocated string. */
40const char empty_string[] = "";
41
a8a05998
ZW
42/* Character strings, each containing a single decimal digit.
43 Written this way to save space. */
a9429e29 44static const char digit_vector[] = {
a8a05998
ZW
45 '0', 0, '1', 0, '2', 0, '3', 0, '4', 0,
46 '5', 0, '6', 0, '7', 0, '8', 0, '9', 0
47};
48
a9429e29
LB
49#define digit_string(d) (digit_vector + ((d) * 2))
50
2a967f3d 51struct ht *ident_hash;
520a57c8 52
46c5ad27
AJ
53static hashnode alloc_node (hash_table *);
54static int mark_ident (struct cpp_reader *, hashnode, const void *);
d8044160
GK
55
56static void *
57stringpool_ggc_alloc (size_t x)
58{
a9429e29 59 return ggc_alloc_atomic (x);
d8044160 60}
2a967f3d 61
520a57c8
ZW
62/* Initialize the string pool. */
63void
46c5ad27 64init_stringpool (void)
520a57c8 65{
2a967f3d
NB
66 /* Create with 16K (2^14) entries. */
67 ident_hash = ht_create (14);
68 ident_hash->alloc_node = alloc_node;
d8044160 69 ident_hash->alloc_subobject = stringpool_ggc_alloc;
520a57c8
ZW
70}
71
2a967f3d
NB
72/* Allocate a hash node. */
73static hashnode
46c5ad27 74alloc_node (hash_table *table ATTRIBUTE_UNUSED)
520a57c8 75{
2a967f3d 76 return GCC_IDENT_TO_HT_IDENT (make_node (IDENTIFIER_NODE));
520a57c8
ZW
77}
78
79/* Allocate and return a string constant of length LENGTH, containing
80 CONTENTS. If LENGTH is -1, CONTENTS is assumed to be a
d1f43464 81 nul-terminated string, and the length is calculated using strlen. */
520a57c8
ZW
82
83const char *
a9429e29 84ggc_alloc_string_stat (const char *contents, int length MEM_STAT_DECL)
520a57c8 85{
dae4174e
TT
86 char *result;
87
520a57c8
ZW
88 if (length == -1)
89 length = strlen (contents);
90
91 if (length == 0)
92 return empty_string;
0df6c2c7 93 if (length == 1 && ISDIGIT (contents[0]))
a8a05998 94 return digit_string (contents[0] - '0');
520a57c8 95
a9429e29 96 result = (char *) ggc_alloc_atomic_stat (length + 1 PASS_MEM_STAT);
d1f43464
TT
97 memcpy (result, contents, length);
98 result[length] = '\0';
dae4174e 99 return (const char *) result;
520a57c8
ZW
100}
101
102/* Return an IDENTIFIER_NODE whose name is TEXT (a null-terminated string).
103 If an identifier with that name has previously been referred to,
104 the same node is returned this time. */
2a967f3d 105
7bb3fbbb
RS
106#undef get_identifier
107
520a57c8 108tree
46c5ad27 109get_identifier (const char *text)
520a57c8 110{
2a967f3d
NB
111 hashnode ht_node = ht_lookup (ident_hash,
112 (const unsigned char *) text,
113 strlen (text), HT_ALLOC);
4c521bad 114
2a967f3d
NB
115 /* ht_node can't be NULL here. */
116 return HT_IDENT_TO_GCC_IDENT (ht_node);
520a57c8
ZW
117}
118
4bad9e39
APB
119/* Identical to get_identifier, except that the length is assumed
120 known. */
786de7eb 121
4bad9e39 122tree
7bb3fbbb 123get_identifier_with_length (const char *text, size_t length)
4bad9e39
APB
124{
125 hashnode ht_node = ht_lookup (ident_hash,
126 (const unsigned char *) text,
127 length, HT_ALLOC);
128
129 /* ht_node can't be NULL here. */
130 return HT_IDENT_TO_GCC_IDENT (ht_node);
131}
132
520a57c8
ZW
133/* If an identifier with the name TEXT (a null-terminated string) has
134 previously been referred to, return that node; otherwise return
135 NULL_TREE. */
136
137tree
46c5ad27 138maybe_get_identifier (const char *text)
520a57c8 139{
2a967f3d 140 hashnode ht_node;
520a57c8 141
2a967f3d 142 ht_node = ht_lookup (ident_hash, (const unsigned char *) text,
083e9f92 143 strlen (text), HT_NO_INSERT);
2a967f3d 144 if (ht_node)
083e9f92 145 return HT_IDENT_TO_GCC_IDENT (ht_node);
520a57c8 146
4c521bad 147 return NULL_TREE;
71b7be38
ZW
148}
149
520a57c8
ZW
150/* Report some basic statistics about the string pool. */
151
152void
46c5ad27 153stringpool_statistics (void)
520a57c8 154{
2a967f3d 155 ht_dump_statistics (ident_hash);
520a57c8 156}
4bb4ae96 157\f
2a967f3d 158/* Mark an identifier for GC. */
520a57c8 159
2a967f3d 160static int
46c5ad27
AJ
161mark_ident (struct cpp_reader *pfile ATTRIBUTE_UNUSED, hashnode h,
162 const void *v ATTRIBUTE_UNUSED)
520a57c8 163{
17211ab5 164 gt_ggc_m_9tree_node (HT_IDENT_TO_GCC_IDENT (h));
2a967f3d
NB
165 return 1;
166}
520a57c8 167
dae4174e
TT
168/* Return true if an identifier should be removed from the table. */
169
170static int
171maybe_delete_ident (struct cpp_reader *pfile ATTRIBUTE_UNUSED, hashnode h,
172 const void *v ATTRIBUTE_UNUSED)
173{
174 return !ggc_marked_p (HT_IDENT_TO_GCC_IDENT (h));
175}
176
17211ab5 177/* Mark the trees hanging off the identifier node for GGC. These are
dae4174e
TT
178 handled specially (not using gengtype) because identifiers are only
179 roots during one part of compilation. */
2a967f3d 180
17211ab5 181void
46c5ad27 182ggc_mark_stringpool (void)
2a967f3d
NB
183{
184 ht_forall (ident_hash, mark_ident, NULL);
520a57c8 185}
17211ab5 186
dae4174e
TT
187/* Purge the identifier hash of identifiers which are no longer
188 referenced. */
17211ab5
GK
189
190void
dae4174e 191ggc_purge_stringpool (void)
17211ab5 192{
dae4174e 193 ht_purge (ident_hash, maybe_delete_ident, NULL);
17211ab5
GK
194}
195
196/* Pointer-walking routine for strings (not very interesting, since
197 strings don't contain pointers). */
198
199void
46c5ad27
AJ
200gt_pch_p_S (void *obj ATTRIBUTE_UNUSED, void *x ATTRIBUTE_UNUSED,
201 gt_pointer_operator op ATTRIBUTE_UNUSED,
202 void *cookie ATTRIBUTE_UNUSED)
17211ab5
GK
203{
204}
205
206/* PCH pointer-walking routine for strings. */
207
208void
46c5ad27 209gt_pch_n_S (const void *x)
17211ab5 210{
1634b18f
KG
211 gt_pch_note_object (CONST_CAST (void *, x), CONST_CAST (void *, x),
212 &gt_pch_p_S, gt_types_enum_last);
17211ab5 213}
4bb4ae96 214\f
17211ab5
GK
215/* Handle saving and restoring the string pool for PCH. */
216
4bb4ae96
GK
217/* SPD is saved in the PCH file and holds the information needed
218 to restore the string pool. */
219
d1b38208 220struct GTY(()) string_pool_data {
a9429e29 221 ht_identifier_ptr *
b453c95f
GK
222 GTY((length ("%h.nslots"),
223 nested_ptr (union tree_node, "%h ? GCC_IDENT_TO_HT_IDENT (%h) : NULL",
224 "%h ? HT_IDENT_TO_GCC_IDENT (%h) : NULL")))
225 entries;
17211ab5
GK
226 unsigned int nslots;
227 unsigned int nelements;
228};
229
230static GTY(()) struct string_pool_data * spd;
231
d8044160 232/* Save the stringpool data in SPD. */
4bb4ae96 233
17211ab5 234void
46c5ad27 235gt_pch_save_stringpool (void)
17211ab5 236{
a9429e29 237 spd = ggc_alloc_string_pool_data ();
17211ab5
GK
238 spd->nslots = ident_hash->nslots;
239 spd->nelements = ident_hash->nelements;
a9429e29 240 spd->entries = ggc_alloc_vec_ht_identifier_ptr (spd->nslots);
b453c95f
GK
241 memcpy (spd->entries, ident_hash->entries,
242 spd->nslots * sizeof (spd->entries[0]));
d24ecd21
MA
243}
244
4bb4ae96
GK
245/* Return the stringpool to its state before gt_pch_save_stringpool
246 was called. */
247
d24ecd21 248void
46c5ad27 249gt_pch_fixup_stringpool (void)
d24ecd21 250{
17211ab5
GK
251}
252
4bb4ae96 253/* A PCH file has been restored, which loaded SPD; fill the real hash table
b453c95f 254 from SPD. */
4bb4ae96 255
17211ab5 256void
46c5ad27 257gt_pch_restore_stringpool (void)
17211ab5 258{
b453c95f 259 ht_load (ident_hash, spd->entries, spd->nslots, spd->nelements, false);
17211ab5
GK
260 spd = NULL;
261}
262
263#include "gt-stringpool.h"