]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/stringpool.c
Update Copyright years for files modified in 2011 and/or 2012.
[thirdparty/gcc.git] / gcc / stringpool.c
CommitLineData
44acf429 1/* String pool for GCC.
71e45bc2 2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010,
3 2012 Free Software Foundation, Inc.
44acf429 4
f12b58b3 5This file is part of GCC.
44acf429 6
f12b58b3 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
8c4c00c1 9Software Foundation; either version 3, or (at your option) any later
f12b58b3 10version.
44acf429 11
f12b58b3 12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
44acf429 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
8c4c00c1 18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
44acf429 20
83f43f36 21/* String text, identifier text and identifier node allocator.
22 Identifiers are uniquely stored in a hash table.
44acf429 23
d856c8a6 24 We use cpplib's hash table implementation. libiberty's
0d086e18 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. */
44acf429 28
29#include "config.h"
30#include "system.h"
805e22b2 31#include "coretypes.h"
44acf429 32#include "ggc.h"
ba72912a 33#include "ggc-internal.h"
44acf429 34#include "tree.h"
d856c8a6 35#include "symtab.h"
78e9fc50 36#include "cpplib.h"
44acf429 37
38/* The "" allocated string. */
39const char empty_string[] = "";
40
ec6cb94a 41/* Character strings, each containing a single decimal digit.
42 Written this way to save space. */
ba72912a 43static const char digit_vector[] = {
ec6cb94a 44 '0', 0, '1', 0, '2', 0, '3', 0, '4', 0,
45 '5', 0, '6', 0, '7', 0, '8', 0, '9', 0
46};
47
ba72912a 48#define digit_string(d) (digit_vector + ((d) * 2))
49
0d086e18 50struct ht *ident_hash;
44acf429 51
2b15d2ba 52static hashnode alloc_node (cpp_hash_table *);
60b8c5b3 53static int mark_ident (struct cpp_reader *, hashnode, const void *);
c39ed964 54
55static void *
56stringpool_ggc_alloc (size_t x)
57{
ba72912a 58 return ggc_alloc_atomic (x);
c39ed964 59}
0d086e18 60
44acf429 61/* Initialize the string pool. */
62void
60b8c5b3 63init_stringpool (void)
44acf429 64{
0d086e18 65 /* Create with 16K (2^14) entries. */
66 ident_hash = ht_create (14);
67 ident_hash->alloc_node = alloc_node;
c39ed964 68 ident_hash->alloc_subobject = stringpool_ggc_alloc;
44acf429 69}
70
0d086e18 71/* Allocate a hash node. */
72static hashnode
2b15d2ba 73alloc_node (cpp_hash_table *table ATTRIBUTE_UNUSED)
44acf429 74{
0d086e18 75 return GCC_IDENT_TO_HT_IDENT (make_node (IDENTIFIER_NODE));
44acf429 76}
77
78/* Allocate and return a string constant of length LENGTH, containing
79 CONTENTS. If LENGTH is -1, CONTENTS is assumed to be a
83f43f36 80 nul-terminated string, and the length is calculated using strlen. */
44acf429 81
82const char *
ba72912a 83ggc_alloc_string_stat (const char *contents, int length MEM_STAT_DECL)
44acf429 84{
dfecde36 85 char *result;
86
44acf429 87 if (length == -1)
88 length = strlen (contents);
89
90 if (length == 0)
91 return empty_string;
66a33570 92 if (length == 1 && ISDIGIT (contents[0]))
ec6cb94a 93 return digit_string (contents[0] - '0');
44acf429 94
ba72912a 95 result = (char *) ggc_alloc_atomic_stat (length + 1 PASS_MEM_STAT);
83f43f36 96 memcpy (result, contents, length);
97 result[length] = '\0';
dfecde36 98 return (const char *) result;
44acf429 99}
100
101/* Return an IDENTIFIER_NODE whose name is TEXT (a null-terminated string).
102 If an identifier with that name has previously been referred to,
103 the same node is returned this time. */
0d086e18 104
69642df2 105#undef get_identifier
106
44acf429 107tree
60b8c5b3 108get_identifier (const char *text)
44acf429 109{
0d086e18 110 hashnode ht_node = ht_lookup (ident_hash,
111 (const unsigned char *) text,
112 strlen (text), HT_ALLOC);
1e5bfc66 113
0d086e18 114 /* ht_node can't be NULL here. */
115 return HT_IDENT_TO_GCC_IDENT (ht_node);
44acf429 116}
117
82863d5e 118/* Identical to get_identifier, except that the length is assumed
119 known. */
40734805 120
82863d5e 121tree
69642df2 122get_identifier_with_length (const char *text, size_t length)
82863d5e 123{
124 hashnode ht_node = ht_lookup (ident_hash,
125 (const unsigned char *) text,
126 length, HT_ALLOC);
127
128 /* ht_node can't be NULL here. */
129 return HT_IDENT_TO_GCC_IDENT (ht_node);
130}
131
44acf429 132/* If an identifier with the name TEXT (a null-terminated string) has
133 previously been referred to, return that node; otherwise return
134 NULL_TREE. */
135
136tree
60b8c5b3 137maybe_get_identifier (const char *text)
44acf429 138{
0d086e18 139 hashnode ht_node;
44acf429 140
0d086e18 141 ht_node = ht_lookup (ident_hash, (const unsigned char *) text,
17822ef8 142 strlen (text), HT_NO_INSERT);
0d086e18 143 if (ht_node)
17822ef8 144 return HT_IDENT_TO_GCC_IDENT (ht_node);
44acf429 145
1e5bfc66 146 return NULL_TREE;
e2df8b81 147}
148
44acf429 149/* Report some basic statistics about the string pool. */
150
151void
60b8c5b3 152stringpool_statistics (void)
44acf429 153{
0d086e18 154 ht_dump_statistics (ident_hash);
44acf429 155}
5b916b55 156\f
0d086e18 157/* Mark an identifier for GC. */
44acf429 158
0d086e18 159static int
60b8c5b3 160mark_ident (struct cpp_reader *pfile ATTRIBUTE_UNUSED, hashnode h,
161 const void *v ATTRIBUTE_UNUSED)
44acf429 162{
573aba85 163 gt_ggc_m_9tree_node (HT_IDENT_TO_GCC_IDENT (h));
0d086e18 164 return 1;
165}
44acf429 166
dfecde36 167/* Return true if an identifier should be removed from the table. */
168
169static int
170maybe_delete_ident (struct cpp_reader *pfile ATTRIBUTE_UNUSED, hashnode h,
171 const void *v ATTRIBUTE_UNUSED)
172{
173 return !ggc_marked_p (HT_IDENT_TO_GCC_IDENT (h));
174}
175
573aba85 176/* Mark the trees hanging off the identifier node for GGC. These are
dfecde36 177 handled specially (not using gengtype) because identifiers are only
178 roots during one part of compilation. */
0d086e18 179
573aba85 180void
60b8c5b3 181ggc_mark_stringpool (void)
0d086e18 182{
183 ht_forall (ident_hash, mark_ident, NULL);
44acf429 184}
573aba85 185
dfecde36 186/* Purge the identifier hash of identifiers which are no longer
187 referenced. */
573aba85 188
189void
dfecde36 190ggc_purge_stringpool (void)
573aba85 191{
dfecde36 192 ht_purge (ident_hash, maybe_delete_ident, NULL);
573aba85 193}
194
195/* Pointer-walking routine for strings (not very interesting, since
196 strings don't contain pointers). */
197
198void
60b8c5b3 199gt_pch_p_S (void *obj ATTRIBUTE_UNUSED, void *x ATTRIBUTE_UNUSED,
200 gt_pointer_operator op ATTRIBUTE_UNUSED,
201 void *cookie ATTRIBUTE_UNUSED)
573aba85 202{
203}
204
205/* PCH pointer-walking routine for strings. */
206
207void
60b8c5b3 208gt_pch_n_S (const void *x)
573aba85 209{
f7f3687c 210 gt_pch_note_object (CONST_CAST (void *, x), CONST_CAST (void *, x),
211 &gt_pch_p_S, gt_types_enum_last);
573aba85 212}
2b15d2ba 213
214
215/* User-callable entry point for marking string X. */
216
217void
218gt_pch_nx (const char *& x)
219{
220 gt_pch_n_S (x);
221}
222
223void
224gt_pch_nx (unsigned char *& x)
225{
226 gt_pch_n_S (x);
227}
228
229void
230gt_pch_nx (unsigned char& x ATTRIBUTE_UNUSED)
231{
232}
233
234void
235gt_pch_nx (unsigned char *x, gt_pointer_operator op, void *cookie)
236{
237 op (x, cookie);
238}
5b916b55 239\f
573aba85 240/* Handle saving and restoring the string pool for PCH. */
241
5b916b55 242/* SPD is saved in the PCH file and holds the information needed
243 to restore the string pool. */
244
fb1e4f4a 245struct GTY(()) string_pool_data {
ba72912a 246 ht_identifier_ptr *
8ed01400 247 GTY((length ("%h.nslots"),
248 nested_ptr (union tree_node, "%h ? GCC_IDENT_TO_HT_IDENT (%h) : NULL",
249 "%h ? HT_IDENT_TO_GCC_IDENT (%h) : NULL")))
250 entries;
573aba85 251 unsigned int nslots;
252 unsigned int nelements;
253};
254
255static GTY(()) struct string_pool_data * spd;
256
c39ed964 257/* Save the stringpool data in SPD. */
5b916b55 258
573aba85 259void
60b8c5b3 260gt_pch_save_stringpool (void)
573aba85 261{
ba72912a 262 spd = ggc_alloc_string_pool_data ();
573aba85 263 spd->nslots = ident_hash->nslots;
264 spd->nelements = ident_hash->nelements;
ba72912a 265 spd->entries = ggc_alloc_vec_ht_identifier_ptr (spd->nslots);
8ed01400 266 memcpy (spd->entries, ident_hash->entries,
267 spd->nslots * sizeof (spd->entries[0]));
78e9fc50 268}
269
5b916b55 270/* Return the stringpool to its state before gt_pch_save_stringpool
271 was called. */
272
78e9fc50 273void
60b8c5b3 274gt_pch_fixup_stringpool (void)
78e9fc50 275{
573aba85 276}
277
5b916b55 278/* A PCH file has been restored, which loaded SPD; fill the real hash table
8ed01400 279 from SPD. */
5b916b55 280
573aba85 281void
60b8c5b3 282gt_pch_restore_stringpool (void)
573aba85 283{
8ed01400 284 ht_load (ident_hash, spd->entries, spd->nslots, spd->nelements, false);
573aba85 285 spd = NULL;
286}
287
288#include "gt-stringpool.h"