190075Sobrien/* String pool for GCC. 2169689Skan Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 3169689Skan Free Software Foundation, Inc. 490075Sobrien 590075SobrienThis file is part of GCC. 690075Sobrien 790075SobrienGCC is free software; you can redistribute it and/or modify it under 890075Sobrienthe terms of the GNU General Public License as published by the Free 990075SobrienSoftware Foundation; either version 2, or (at your option) any later 1090075Sobrienversion. 1190075Sobrien 1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1490075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1590075Sobrienfor more details. 1690075Sobrien 1790075SobrienYou should have received a copy of the GNU General Public License 1890075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 20169689Skan02110-1301, USA. */ 2190075Sobrien 2290075Sobrien/* String text, identifier text and identifier node allocator. Strings 2390075Sobrien allocated by ggc_alloc_string are stored in an obstack which is 2490075Sobrien never shrunk. Identifiers are uniquely stored in a hash table. 2590075Sobrien 26169689Skan We use cpplib's hash table implementation. libiberty's 2790075Sobrien hashtab.c is not used because it requires 100% average space 2890075Sobrien overhead per string, which is unacceptable. Also, this algorithm 2990075Sobrien is faster. */ 3090075Sobrien 3190075Sobrien#include "config.h" 3290075Sobrien#include "system.h" 33132718Skan#include "coretypes.h" 34132718Skan#include "tm.h" 3590075Sobrien#include "ggc.h" 3690075Sobrien#include "tree.h" 37169689Skan#include "symtab.h" 38132718Skan#include "cpplib.h" 3990075Sobrien 4090075Sobrien/* The "" allocated string. */ 4190075Sobrienconst char empty_string[] = ""; 4290075Sobrien 4390075Sobrien/* Character strings, each containing a single decimal digit. 4490075Sobrien Written this way to save space. */ 4590075Sobrienconst char digit_vector[] = { 4690075Sobrien '0', 0, '1', 0, '2', 0, '3', 0, '4', 0, 4790075Sobrien '5', 0, '6', 0, '7', 0, '8', 0, '9', 0 4890075Sobrien}; 4990075Sobrien 5090075Sobrienstruct ht *ident_hash; 5190075Sobrienstatic struct obstack string_stack; 5290075Sobrien 53132718Skanstatic hashnode alloc_node (hash_table *); 54132718Skanstatic int mark_ident (struct cpp_reader *, hashnode, const void *); 5590075Sobrien 56169689Skanstatic void * 57169689Skanstringpool_ggc_alloc (size_t x) 58169689Skan{ 59169689Skan return ggc_alloc (x); 60169689Skan} 61169689Skan 6290075Sobrien/* Initialize the string pool. */ 6390075Sobrienvoid 64132718Skaninit_stringpool (void) 6590075Sobrien{ 6690075Sobrien /* Create with 16K (2^14) entries. */ 6790075Sobrien ident_hash = ht_create (14); 6890075Sobrien ident_hash->alloc_node = alloc_node; 69169689Skan ident_hash->alloc_subobject = stringpool_ggc_alloc; 7090075Sobrien gcc_obstack_init (&string_stack); 7190075Sobrien} 7290075Sobrien 7390075Sobrien/* Allocate a hash node. */ 7490075Sobrienstatic hashnode 75132718Skanalloc_node (hash_table *table ATTRIBUTE_UNUSED) 7690075Sobrien{ 7790075Sobrien return GCC_IDENT_TO_HT_IDENT (make_node (IDENTIFIER_NODE)); 7890075Sobrien} 7990075Sobrien 8090075Sobrien/* Allocate and return a string constant of length LENGTH, containing 8190075Sobrien CONTENTS. If LENGTH is -1, CONTENTS is assumed to be a 8290075Sobrien nul-terminated string, and the length is calculated using strlen. 8390075Sobrien If the same string constant has been allocated before, that copy is 8490075Sobrien returned this time too. */ 8590075Sobrien 8690075Sobrienconst char * 87132718Skanggc_alloc_string (const char *contents, int length) 8890075Sobrien{ 8990075Sobrien if (length == -1) 9090075Sobrien length = strlen (contents); 9190075Sobrien 9290075Sobrien if (length == 0) 9390075Sobrien return empty_string; 9490075Sobrien if (length == 1 && ISDIGIT (contents[0])) 9590075Sobrien return digit_string (contents[0] - '0'); 9690075Sobrien 9790075Sobrien obstack_grow0 (&string_stack, contents, length); 98169689Skan return XOBFINISH (&string_stack, const char *); 9990075Sobrien} 10090075Sobrien 10190075Sobrien/* Return an IDENTIFIER_NODE whose name is TEXT (a null-terminated string). 10290075Sobrien If an identifier with that name has previously been referred to, 10390075Sobrien the same node is returned this time. */ 10490075Sobrien 105132718Skan#undef get_identifier 106132718Skan 10790075Sobrientree 108132718Skanget_identifier (const char *text) 10990075Sobrien{ 11090075Sobrien hashnode ht_node = ht_lookup (ident_hash, 11190075Sobrien (const unsigned char *) text, 11290075Sobrien strlen (text), HT_ALLOC); 11390075Sobrien 11490075Sobrien /* ht_node can't be NULL here. */ 11590075Sobrien return HT_IDENT_TO_GCC_IDENT (ht_node); 11690075Sobrien} 11790075Sobrien 11890075Sobrien/* Identical to get_identifier, except that the length is assumed 11990075Sobrien known. */ 120117395Skan 12190075Sobrientree 122132718Skanget_identifier_with_length (const char *text, size_t length) 12390075Sobrien{ 12490075Sobrien hashnode ht_node = ht_lookup (ident_hash, 12590075Sobrien (const unsigned char *) text, 12690075Sobrien length, HT_ALLOC); 12790075Sobrien 12890075Sobrien /* ht_node can't be NULL here. */ 12990075Sobrien return HT_IDENT_TO_GCC_IDENT (ht_node); 13090075Sobrien} 13190075Sobrien 13290075Sobrien/* If an identifier with the name TEXT (a null-terminated string) has 13390075Sobrien previously been referred to, return that node; otherwise return 13490075Sobrien NULL_TREE. */ 13590075Sobrien 13690075Sobrientree 137132718Skanmaybe_get_identifier (const char *text) 13890075Sobrien{ 13990075Sobrien hashnode ht_node; 14090075Sobrien 14190075Sobrien ht_node = ht_lookup (ident_hash, (const unsigned char *) text, 14290075Sobrien strlen (text), HT_NO_INSERT); 14390075Sobrien if (ht_node) 14490075Sobrien return HT_IDENT_TO_GCC_IDENT (ht_node); 14590075Sobrien 14690075Sobrien return NULL_TREE; 14790075Sobrien} 14890075Sobrien 14990075Sobrien/* Report some basic statistics about the string pool. */ 15090075Sobrien 15190075Sobrienvoid 152132718Skanstringpool_statistics (void) 15390075Sobrien{ 15490075Sobrien ht_dump_statistics (ident_hash); 15590075Sobrien} 156169689Skan 15790075Sobrien/* Mark an identifier for GC. */ 15890075Sobrien 15990075Sobrienstatic int 160132718Skanmark_ident (struct cpp_reader *pfile ATTRIBUTE_UNUSED, hashnode h, 161132718Skan const void *v ATTRIBUTE_UNUSED) 16290075Sobrien{ 163132718Skan gt_ggc_m_9tree_node (HT_IDENT_TO_GCC_IDENT (h)); 16490075Sobrien return 1; 16590075Sobrien} 16690075Sobrien 167132718Skan/* Mark the trees hanging off the identifier node for GGC. These are 168132718Skan handled specially (not using gengtype) because of the special 169132718Skan treatment for strings. */ 17090075Sobrien 171132718Skanvoid 172132718Skanggc_mark_stringpool (void) 17390075Sobrien{ 17490075Sobrien ht_forall (ident_hash, mark_ident, NULL); 17590075Sobrien} 176132718Skan 177132718Skan/* Strings are _not_ GCed, but this routine exists so that a separate 178132718Skan roots table isn't needed for the few global variables that refer 179132718Skan to strings. */ 180132718Skan 181132718Skanvoid 182132718Skangt_ggc_m_S (void *x ATTRIBUTE_UNUSED) 183132718Skan{ 184132718Skan} 185132718Skan 186132718Skan/* Pointer-walking routine for strings (not very interesting, since 187132718Skan strings don't contain pointers). */ 188132718Skan 189132718Skanvoid 190132718Skangt_pch_p_S (void *obj ATTRIBUTE_UNUSED, void *x ATTRIBUTE_UNUSED, 191132718Skan gt_pointer_operator op ATTRIBUTE_UNUSED, 192132718Skan void *cookie ATTRIBUTE_UNUSED) 193132718Skan{ 194132718Skan} 195132718Skan 196132718Skan/* PCH pointer-walking routine for strings. */ 197132718Skan 198132718Skanvoid 199132718Skangt_pch_n_S (const void *x) 200132718Skan{ 201169689Skan gt_pch_note_object ((void *)x, (void *)x, >_pch_p_S, 202169689Skan gt_types_enum_last); 203132718Skan} 204169689Skan 205132718Skan/* Handle saving and restoring the string pool for PCH. */ 206132718Skan 207169689Skan/* SPD is saved in the PCH file and holds the information needed 208169689Skan to restore the string pool. */ 209169689Skan 210132718Skanstruct string_pool_data GTY(()) 211132718Skan{ 212169689Skan struct ht_identifier * * 213169689Skan GTY((length ("%h.nslots"), 214169689Skan nested_ptr (union tree_node, "%h ? GCC_IDENT_TO_HT_IDENT (%h) : NULL", 215169689Skan "%h ? HT_IDENT_TO_GCC_IDENT (%h) : NULL"))) 216169689Skan entries; 217132718Skan unsigned int nslots; 218132718Skan unsigned int nelements; 219132718Skan}; 220132718Skan 221132718Skanstatic GTY(()) struct string_pool_data * spd; 222132718Skan 223169689Skan/* Save the stringpool data in SPD. */ 224132718Skan 225132718Skanvoid 226132718Skangt_pch_save_stringpool (void) 227132718Skan{ 228132718Skan spd = ggc_alloc (sizeof (*spd)); 229132718Skan spd->nslots = ident_hash->nslots; 230132718Skan spd->nelements = ident_hash->nelements; 231169689Skan spd->entries = ggc_alloc (sizeof (spd->entries[0]) * spd->nslots); 232169689Skan memcpy (spd->entries, ident_hash->entries, 233169689Skan spd->nslots * sizeof (spd->entries[0])); 234132718Skan} 235132718Skan 236169689Skan/* Return the stringpool to its state before gt_pch_save_stringpool 237169689Skan was called. */ 238169689Skan 239132718Skanvoid 240132718Skangt_pch_fixup_stringpool (void) 241132718Skan{ 242132718Skan} 243132718Skan 244169689Skan/* A PCH file has been restored, which loaded SPD; fill the real hash table 245169689Skan from SPD. */ 246169689Skan 247132718Skanvoid 248132718Skangt_pch_restore_stringpool (void) 249132718Skan{ 250169689Skan ht_load (ident_hash, spd->entries, spd->nslots, spd->nelements, false); 251132718Skan spd = NULL; 252132718Skan} 253132718Skan 254132718Skan#include "gt-stringpool.h" 255