stringpool.c revision 117395
1/* String pool for GCC. 2 Copyright (C) 2000, 2001 Free Software Foundation, Inc. 3 4This file is part of GCC. 5 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 8Software Foundation; either version 2, or (at your option) any later 9version. 10 11GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12WARRANTY; without even the implied warranty of MERCHANTABILITY or 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 17along with GCC; see the file COPYING. If not, write to the Free 18Software Foundation, 59 Temple Place - Suite 330, Boston, MA 1902111-1307, USA. */ 20 21/* String text, identifier text and identifier node allocator. Strings 22 allocated by ggc_alloc_string are stored in an obstack which is 23 never shrunk. Identifiers are uniquely stored in a hash table. 24 25 We have our own private hash table implementation. libiberty's 26 hashtab.c is not used because it requires 100% average space 27 overhead per string, which is unacceptable. Also, this algorithm 28 is faster. */ 29 30#include "config.h" 31#include "system.h" 32#include "ggc.h" 33#include "tree.h" 34#include "hashtable.h" 35 36/* The "" allocated string. */ 37const char empty_string[] = ""; 38 39/* Character strings, each containing a single decimal digit. 40 Written this way to save space. */ 41const char digit_vector[] = { 42 '0', 0, '1', 0, '2', 0, '3', 0, '4', 0, 43 '5', 0, '6', 0, '7', 0, '8', 0, '9', 0 44}; 45 46struct ht *ident_hash; 47static struct obstack string_stack; 48 49static hashnode alloc_node PARAMS ((hash_table *)); 50static int mark_ident PARAMS ((struct cpp_reader *, hashnode, const PTR)); 51static void mark_ident_hash PARAMS ((void *)); 52 53/* Initialize the string pool. */ 54void 55init_stringpool () 56{ 57 /* Create with 16K (2^14) entries. */ 58 ident_hash = ht_create (14); 59 ident_hash->alloc_node = alloc_node; 60 gcc_obstack_init (&string_stack); 61 ggc_add_root (&ident_hash, 1, sizeof ident_hash, mark_ident_hash); 62} 63 64/* Allocate a hash node. */ 65static hashnode 66alloc_node (table) 67 hash_table *table ATTRIBUTE_UNUSED; 68{ 69 return GCC_IDENT_TO_HT_IDENT (make_node (IDENTIFIER_NODE)); 70} 71 72/* Allocate and return a string constant of length LENGTH, containing 73 CONTENTS. If LENGTH is -1, CONTENTS is assumed to be a 74 nul-terminated string, and the length is calculated using strlen. 75 If the same string constant has been allocated before, that copy is 76 returned this time too. */ 77 78const char * 79ggc_alloc_string (contents, length) 80 const char *contents; 81 int length; 82{ 83 if (length == -1) 84 length = strlen (contents); 85 86 if (length == 0) 87 return empty_string; 88 if (length == 1 && ISDIGIT (contents[0])) 89 return digit_string (contents[0] - '0'); 90 91 obstack_grow0 (&string_stack, contents, length); 92 return obstack_finish (&string_stack); 93} 94 95/* Return an IDENTIFIER_NODE whose name is TEXT (a null-terminated string). 96 If an identifier with that name has previously been referred to, 97 the same node is returned this time. */ 98 99tree 100get_identifier (text) 101 const char *text; 102{ 103 hashnode ht_node = ht_lookup (ident_hash, 104 (const unsigned char *) text, 105 strlen (text), HT_ALLOC); 106 107 /* ht_node can't be NULL here. */ 108 return HT_IDENT_TO_GCC_IDENT (ht_node); 109} 110 111/* Identical to get_identifier, except that the length is assumed 112 known. */ 113 114tree 115get_identifier_with_length (text, length) 116 const char *text; 117 unsigned int length; 118{ 119 hashnode ht_node = ht_lookup (ident_hash, 120 (const unsigned char *) text, 121 length, HT_ALLOC); 122 123 /* ht_node can't be NULL here. */ 124 return HT_IDENT_TO_GCC_IDENT (ht_node); 125} 126 127/* If an identifier with the name TEXT (a null-terminated string) has 128 previously been referred to, return that node; otherwise return 129 NULL_TREE. */ 130 131tree 132maybe_get_identifier (text) 133 const char *text; 134{ 135 hashnode ht_node; 136 137 ht_node = ht_lookup (ident_hash, (const unsigned char *) text, 138 strlen (text), HT_NO_INSERT); 139 if (ht_node) 140 return HT_IDENT_TO_GCC_IDENT (ht_node); 141 142 return NULL_TREE; 143} 144 145/* Report some basic statistics about the string pool. */ 146 147void 148stringpool_statistics () 149{ 150 ht_dump_statistics (ident_hash); 151} 152 153/* Mark an identifier for GC. */ 154 155static int 156mark_ident (pfile, h, v) 157 struct cpp_reader *pfile ATTRIBUTE_UNUSED; 158 hashnode h; 159 const PTR v ATTRIBUTE_UNUSED; 160{ 161 ggc_mark_tree (HT_IDENT_TO_GCC_IDENT (h)); 162 return 1; 163} 164 165/* Mark all identifiers for GC. */ 166 167static void 168mark_ident_hash (arg) 169 PTR arg ATTRIBUTE_UNUSED; 170{ 171 ht_forall (ident_hash, mark_ident, NULL); 172} 173