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