diff options
author | obrien <obrien@FreeBSD.org> | 2002-02-01 18:16:02 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2002-02-01 18:16:02 +0000 |
commit | c9ab9ae440a8066b2c2b85b157b1fdadcf09916a (patch) | |
tree | 086d9d6c8fbd4fc8fe4495059332f66bc0f8d12b /contrib/gcc/stringpool.c | |
parent | 2ecfd8bd04b63f335c1ec6295740a4bfd97a4fa6 (diff) | |
download | FreeBSD-src-c9ab9ae440a8066b2c2b85b157b1fdadcf09916a.zip FreeBSD-src-c9ab9ae440a8066b2c2b85b157b1fdadcf09916a.tar.gz |
Enlist the FreeBSD-CURRENT users as testers of what is to become Gcc 3.1.0.
These bits are taken from the FSF anoncvs repo on 1-Feb-2002 08:20 PST.
Diffstat (limited to 'contrib/gcc/stringpool.c')
-rw-r--r-- | contrib/gcc/stringpool.c | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/contrib/gcc/stringpool.c b/contrib/gcc/stringpool.c new file mode 100644 index 0000000..e5b674a --- /dev/null +++ b/contrib/gcc/stringpool.c @@ -0,0 +1,172 @@ +/* String pool for GCC. + Copyright (C) 2000, 2001 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +/* String text, identifier text and identifier node allocator. Strings + allocated by ggc_alloc_string are stored in an obstack which is + never shrunk. Identifiers are uniquely stored in a hash table. + + We have our own private hash table implementation. libiberty's + hashtab.c is not used because it requires 100% average space + overhead per string, which is unacceptable. Also, this algorithm + is faster. */ + +#include "config.h" +#include "system.h" +#include "ggc.h" +#include "tree.h" +#include "hashtable.h" + +/* The "" allocated string. */ +const char empty_string[] = ""; + +/* Character strings, each containing a single decimal digit. + Written this way to save space. */ +const char digit_vector[] = { + '0', 0, '1', 0, '2', 0, '3', 0, '4', 0, + '5', 0, '6', 0, '7', 0, '8', 0, '9', 0 +}; + +struct ht *ident_hash; +static struct obstack string_stack; + +static hashnode alloc_node PARAMS ((hash_table *)); +static int mark_ident PARAMS ((struct cpp_reader *, hashnode, const PTR)); +static void mark_ident_hash PARAMS ((void *)); + +/* Initialize the string pool. */ +void +init_stringpool () +{ + /* Create with 16K (2^14) entries. */ + ident_hash = ht_create (14); + ident_hash->alloc_node = alloc_node; + gcc_obstack_init (&string_stack); + ggc_add_root (&ident_hash, 1, sizeof ident_hash, mark_ident_hash); +} + +/* Allocate a hash node. */ +static hashnode +alloc_node (table) + hash_table *table ATTRIBUTE_UNUSED; +{ + return GCC_IDENT_TO_HT_IDENT (make_node (IDENTIFIER_NODE)); +} + +/* Allocate and return a string constant of length LENGTH, containing + CONTENTS. If LENGTH is -1, CONTENTS is assumed to be a + nul-terminated string, and the length is calculated using strlen. + If the same string constant has been allocated before, that copy is + returned this time too. */ + +const char * +ggc_alloc_string (contents, length) + const char *contents; + int length; +{ + if (length == -1) + length = strlen (contents); + + if (length == 0) + return empty_string; + if (length == 1 && ISDIGIT (contents[0])) + return digit_string (contents[0] - '0'); + + obstack_grow0 (&string_stack, contents, length); + return obstack_finish (&string_stack); +} + +/* Return an IDENTIFIER_NODE whose name is TEXT (a null-terminated string). + If an identifier with that name has previously been referred to, + the same node is returned this time. */ + +tree +get_identifier (text) + const char *text; +{ + hashnode ht_node = ht_lookup (ident_hash, + (const unsigned char *) text, + strlen (text), HT_ALLOC); + + /* ht_node can't be NULL here. */ + return HT_IDENT_TO_GCC_IDENT (ht_node); +} + +/* Identical to get_identifier, except that the length is assumed + known. */ + +tree +get_identifier_with_length (text, length) + const char *text; + unsigned int length; +{ + hashnode ht_node = ht_lookup (ident_hash, + (const unsigned char *) text, + length, HT_ALLOC); + + /* ht_node can't be NULL here. */ + return HT_IDENT_TO_GCC_IDENT (ht_node); +} + +/* If an identifier with the name TEXT (a null-terminated string) has + previously been referred to, return that node; otherwise return + NULL_TREE. */ + +tree +maybe_get_identifier (text) + const char *text; +{ + hashnode ht_node; + + ht_node = ht_lookup (ident_hash, (const unsigned char *) text, + strlen (text), HT_NO_INSERT); + if (ht_node) + return HT_IDENT_TO_GCC_IDENT (ht_node); + + return NULL_TREE; +} + +/* Report some basic statistics about the string pool. */ + +void +stringpool_statistics () +{ + ht_dump_statistics (ident_hash); +} + +/* Mark an identifier for GC. */ + +static int +mark_ident (pfile, h, v) + struct cpp_reader *pfile ATTRIBUTE_UNUSED; + hashnode h; + const PTR v ATTRIBUTE_UNUSED; +{ + ggc_mark_nonnull_tree (HT_IDENT_TO_GCC_IDENT (h)); + return 1; +} + +/* Mark all identifiers for GC. */ + +static void +mark_ident_hash (arg) + PTR arg ATTRIBUTE_UNUSED; +{ + ht_forall (ident_hash, mark_ident, NULL); +} |