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, >_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