2008-08-12 Michael Snyder <msnyder@vmware.com>
[deliverable/binutils-gdb.git] / gas / hash.c
CommitLineData
54d22525 1/* hash.c -- gas hash table code
f7e42eb4 2 Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999,
818236e5 3 2000, 2001, 2002, 2003, 2005, 2007, 2008
252b5132
RH
4 Free Software Foundation, Inc.
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
ec2655a6 10 the Free Software Foundation; either version 3, or (at your option)
252b5132
RH
11 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
54d22525 19 along with GAS; see the file COPYING. If not, write to the Free
4b4da160
NC
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
54d22525
ILT
22
23/* This version of the hash table code is a wholescale replacement of
24 the old hash table code, which was fairly bad. This is based on
25 the hash table code in BFD, but optimized slightly for the
436d9e46 26 assembler. The assembler does not need to derive structures that
54d22525
ILT
27 are stored in the hash table. Instead, it always stores a pointer.
28 The assembler uses the hash table mostly to store symbols, and we
29 don't need to confuse the symbol structure with a hash table
30 structure. */
252b5132
RH
31
32#include "as.h"
3882b010 33#include "safe-ctype.h"
54d22525 34#include "obstack.h"
252b5132 35
54d22525 36/* An entry in a hash table. */
252b5132 37
b041f888 38struct hash_entry {
54d22525
ILT
39 /* Next entry for this hash code. */
40 struct hash_entry *next;
41 /* String being hashed. */
42 const char *string;
43 /* Hash code. This is the full hash code, not the index into the
44 table. */
45 unsigned long hash;
46 /* Pointer being stored in the hash table. */
818236e5 47 void *data;
252b5132
RH
48};
49
54d22525
ILT
50/* A hash table. */
51
b041f888 52struct hash_control {
54d22525
ILT
53 /* The hash array. */
54 struct hash_entry **table;
55 /* The number of slots in the hash table. */
56 unsigned int size;
57 /* An obstack for this hash table. */
58 struct obstack memory;
59
60#ifdef HASH_STATISTICS
61 /* Statistics. */
62 unsigned long lookups;
63 unsigned long hash_compares;
64 unsigned long string_compares;
65 unsigned long insertions;
66 unsigned long replacements;
67 unsigned long deletions;
68#endif /* HASH_STATISTICS */
252b5132 69};
54d22525 70
4bdd3565
NC
71/* The default number of entries to use when creating a hash table.
72 Note this value can be reduced to 4051 by using the command line
73 switch --reduce-memory-overheads, or set to other values by using
74 the --hash-size=<NUMBER> switch. */
75
f7a568ea 76static unsigned long gas_hash_table_size = 65537;
4bdd3565
NC
77
78void
f7a568ea 79set_gas_hash_table_size (unsigned long size)
4bdd3565
NC
80{
81 gas_hash_table_size = size;
82}
83
84/* FIXME: This function should be amalgmated with bfd/hash.c:bfd_hash_set_default_size(). */
f7a568ea 85static unsigned long
4bdd3565
NC
86get_gas_hash_table_size (void)
87{
88 /* Extend this prime list if you want more granularity of hash table size. */
f7a568ea 89 static const unsigned long hash_size_primes[] =
4bdd3565
NC
90 {
91 1021, 4051, 8599, 16699, 65537
92 };
93 unsigned int index;
94
95 /* Work out the best prime number near the hash_size.
96 FIXME: This could be a more sophisticated algorithm,
97 but is it really worth implementing it ? */
98 for (index = 0; index < ARRAY_SIZE (hash_size_primes) - 1; ++index)
99 if (gas_hash_table_size <= hash_size_primes[index])
100 break;
101
102 return hash_size_primes[index];
103}
104
54d22525
ILT
105/* Create a hash table. This return a control block. */
106
252b5132 107struct hash_control *
b1f1fa96 108hash_new (void)
252b5132 109{
f7a568ea
NC
110 unsigned long size;
111 unsigned long alloc;
54d22525 112 struct hash_control *ret;
54d22525 113
4bdd3565 114 size = get_gas_hash_table_size ();
54d22525 115
4bdd3565 116 ret = xmalloc (sizeof *ret);
54d22525
ILT
117 obstack_begin (&ret->memory, chunksize);
118 alloc = size * sizeof (struct hash_entry *);
4bdd3565 119 ret->table = obstack_alloc (&ret->memory, alloc);
54d22525
ILT
120 memset (ret->table, 0, alloc);
121 ret->size = size;
122
123#ifdef HASH_STATISTICS
124 ret->lookups = 0;
125 ret->hash_compares = 0;
126 ret->string_compares = 0;
127 ret->insertions = 0;
128 ret->replacements = 0;
129 ret->deletions = 0;
130#endif
131
8fc2faa7 132 return ret;
252b5132
RH
133}
134
54d22525
ILT
135/* Delete a hash table, freeing all allocated memory. */
136
252b5132 137void
b1f1fa96 138hash_die (struct hash_control *table)
252b5132 139{
54d22525
ILT
140 obstack_free (&table->memory, 0);
141 free (table);
252b5132 142}
54d22525
ILT
143
144/* Look up a string in a hash table. This returns a pointer to the
145 hash_entry, or NULL if the string is not in the table. If PLIST is
146 not NULL, this sets *PLIST to point to the start of the list which
147 would hold this hash entry. If PHASH is not NULL, this sets *PHASH
148 to the hash code for KEY.
149
150 Each time we look up a string, we move it to the start of the list
151 for its hash code, to take advantage of referential locality. */
152
54d22525 153static struct hash_entry *
c19d1205 154hash_lookup (struct hash_control *table, const char *key, size_t len,
b1f1fa96 155 struct hash_entry ***plist, unsigned long *phash)
252b5132 156{
c19d1205
ZW
157 unsigned long hash;
158 size_t n;
159 unsigned int c;
54d22525
ILT
160 unsigned int index;
161 struct hash_entry **list;
162 struct hash_entry *p;
163 struct hash_entry *prev;
164
165#ifdef HASH_STATISTICS
166 ++table->lookups;
167#endif
252b5132 168
54d22525 169 hash = 0;
c19d1205 170 for (n = 0; n < len; n++)
252b5132 171 {
c19d1205 172 c = key[n];
54d22525
ILT
173 hash += c + (c << 17);
174 hash ^= hash >> 2;
252b5132 175 }
54d22525
ILT
176 hash += len + (len << 17);
177 hash ^= hash >> 2;
178
179 if (phash != NULL)
180 *phash = hash;
181
182 index = hash % table->size;
183 list = table->table + index;
252b5132 184
54d22525
ILT
185 if (plist != NULL)
186 *plist = list;
187
188 prev = NULL;
189 for (p = *list; p != NULL; p = p->next)
252b5132 190 {
54d22525
ILT
191#ifdef HASH_STATISTICS
192 ++table->hash_compares;
193#endif
194
195 if (p->hash == hash)
252b5132 196 {
54d22525
ILT
197#ifdef HASH_STATISTICS
198 ++table->string_compares;
199#endif
200
c19d1205 201 if (strncmp (p->string, key, len) == 0 && p->string[len] == '\0')
54d22525
ILT
202 {
203 if (prev != NULL)
204 {
205 prev->next = p->next;
206 p->next = *list;
207 *list = p;
208 }
209
210 return p;
211 }
252b5132 212 }
252b5132 213
54d22525 214 prev = p;
252b5132 215 }
54d22525
ILT
216
217 return NULL;
252b5132 218}
54d22525
ILT
219
220/* Insert an entry into a hash table. This returns NULL on success.
221 On error, it returns a printable string indicating the error. It
222 is considered to be an error if the entry already exists in the
223 hash table. */
224
225const char *
818236e5 226hash_insert (struct hash_control *table, const char *key, void *value)
252b5132 227{
54d22525
ILT
228 struct hash_entry *p;
229 struct hash_entry **list;
230 unsigned long hash;
252b5132 231
c19d1205 232 p = hash_lookup (table, key, strlen (key), &list, &hash);
54d22525
ILT
233 if (p != NULL)
234 return "exists";
235
236#ifdef HASH_STATISTICS
237 ++table->insertions;
238#endif
239
8fc2faa7 240 p = (struct hash_entry *) obstack_alloc (&table->memory, sizeof (*p));
54d22525
ILT
241 p->string = key;
242 p->hash = hash;
243 p->data = value;
244
245 p->next = *list;
246 *list = p;
247
248 return NULL;
252b5132 249}
54d22525
ILT
250
251/* Insert or replace an entry in a hash table. This returns NULL on
252 success. On error, it returns a printable string indicating the
253 error. If an entry already exists, its value is replaced. */
254
252b5132 255const char *
818236e5 256hash_jam (struct hash_control *table, const char *key, void *value)
252b5132 257{
54d22525
ILT
258 struct hash_entry *p;
259 struct hash_entry **list;
260 unsigned long hash;
252b5132 261
c19d1205 262 p = hash_lookup (table, key, strlen (key), &list, &hash);
54d22525 263 if (p != NULL)
252b5132 264 {
54d22525
ILT
265#ifdef HASH_STATISTICS
266 ++table->replacements;
267#endif
268
269 p->data = value;
252b5132 270 }
54d22525 271 else
252b5132 272 {
54d22525
ILT
273#ifdef HASH_STATISTICS
274 ++table->insertions;
275#endif
276
8fc2faa7 277 p = (struct hash_entry *) obstack_alloc (&table->memory, sizeof (*p));
54d22525
ILT
278 p->string = key;
279 p->hash = hash;
280 p->data = value;
281
282 p->next = *list;
283 *list = p;
252b5132 284 }
54d22525
ILT
285
286 return NULL;
252b5132
RH
287}
288
7e70f1af
L
289/* Replace an existing entry in a hash table. This returns the old
290 value stored for the entry. If the entry is not found in the hash
291 table, this does nothing and returns NULL. */
292
293PTR
818236e5 294hash_replace (struct hash_control *table, const char *key, void *value)
7e70f1af
L
295{
296 struct hash_entry *p;
818236e5 297 void *ret;
7e70f1af 298
c19d1205 299 p = hash_lookup (table, key, strlen (key), NULL, NULL);
7e70f1af
L
300 if (p == NULL)
301 return NULL;
302
303#ifdef HASH_STATISTICS
304 ++table->replacements;
305#endif
306
307 ret = p->data;
308
309 p->data = value;
310
311 return ret;
312}
313
54d22525
ILT
314/* Find an entry in a hash table, returning its value. Returns NULL
315 if the entry is not found. */
316
252b5132 317PTR
b1f1fa96 318hash_find (struct hash_control *table, const char *key)
252b5132 319{
54d22525 320 struct hash_entry *p;
252b5132 321
c19d1205
ZW
322 p = hash_lookup (table, key, strlen (key), NULL, NULL);
323 if (p == NULL)
324 return NULL;
325
326 return p->data;
327}
328
329/* As hash_find, but KEY is of length LEN and is not guaranteed to be
330 NUL-terminated. */
331
332PTR
333hash_find_n (struct hash_control *table, const char *key, size_t len)
334{
335 struct hash_entry *p;
336
337 p = hash_lookup (table, key, len, NULL, NULL);
54d22525 338 if (p == NULL)
252b5132 339 return NULL;
54d22525
ILT
340
341 return p->data;
252b5132 342}
54d22525 343
7e70f1af
L
344/* Delete an entry from a hash table. This returns the value stored
345 for that entry, or NULL if there is no such entry. */
346
347PTR
818236e5 348hash_delete (struct hash_control *table, const char *key, int freeme)
7e70f1af
L
349{
350 struct hash_entry *p;
351 struct hash_entry **list;
352
c19d1205 353 p = hash_lookup (table, key, strlen (key), &list, NULL);
7e70f1af
L
354 if (p == NULL)
355 return NULL;
356
357 if (p != *list)
358 abort ();
359
360#ifdef HASH_STATISTICS
361 ++table->deletions;
362#endif
363
364 *list = p->next;
365
818236e5
AM
366 if (freeme)
367 obstack_free (&table->memory, p);
7e70f1af
L
368
369 return p->data;
370}
371
54d22525
ILT
372/* Traverse a hash table. Call the function on every entry in the
373 hash table. */
374
252b5132 375void
b1f1fa96 376hash_traverse (struct hash_control *table,
818236e5 377 void (*pfn) (const char *key, void *value))
252b5132 378{
54d22525 379 unsigned int i;
252b5132 380
54d22525
ILT
381 for (i = 0; i < table->size; ++i)
382 {
383 struct hash_entry *p;
252b5132 384
54d22525
ILT
385 for (p = table->table[i]; p != NULL; p = p->next)
386 (*pfn) (p->string, p->data);
387 }
388}
252b5132 389
54d22525
ILT
390/* Print hash table statistics on the specified file. NAME is the
391 name of the hash table, used for printing a header. */
252b5132 392
54d22525 393void
b1f1fa96
KH
394hash_print_statistics (FILE *f ATTRIBUTE_UNUSED,
395 const char *name ATTRIBUTE_UNUSED,
396 struct hash_control *table ATTRIBUTE_UNUSED)
54d22525
ILT
397{
398#ifdef HASH_STATISTICS
399 unsigned int i;
400 unsigned long total;
401 unsigned long empty;
402
403 fprintf (f, "%s hash statistics:\n", name);
404 fprintf (f, "\t%lu lookups\n", table->lookups);
405 fprintf (f, "\t%lu hash comparisons\n", table->hash_compares);
406 fprintf (f, "\t%lu string comparisons\n", table->string_compares);
407 fprintf (f, "\t%lu insertions\n", table->insertions);
408 fprintf (f, "\t%lu replacements\n", table->replacements);
409 fprintf (f, "\t%lu deletions\n", table->deletions);
410
411 total = 0;
412 empty = 0;
413 for (i = 0; i < table->size; ++i)
414 {
415 struct hash_entry *p;
252b5132 416
54d22525
ILT
417 if (table->table[i] == NULL)
418 ++empty;
419 else
420 {
421 for (p = table->table[i]; p != NULL; p = p->next)
422 ++total;
423 }
424 }
252b5132 425
54d22525
ILT
426 fprintf (f, "\t%g average chain length\n", (double) total / table->size);
427 fprintf (f, "\t%lu empty slots\n", empty);
428#endif
252b5132
RH
429}
430\f
252b5132
RH
431#ifdef TEST
432
54d22525
ILT
433/* This test program is left over from the old hash table code. */
434
8fc2faa7
KH
435/* Number of hash tables to maintain (at once) in any testing. */
436#define TABLES (6)
437
438/* We can have 12 statistics. */
439#define STATBUFSIZE (12)
440
441/* Display statistics here. */
442int statbuf[STATBUFSIZE];
443
444/* Human farts here. */
445char answer[100];
446
447/* We test many hash tables at once. */
448char *hashtable[TABLES];
252b5132 449
47eebc20 450/* Points to current hash_control. */
8fc2faa7 451char *h;
252b5132
RH
452char **pp;
453char *p;
454char *name;
455char *value;
456int size;
457int used;
458char command;
8fc2faa7
KH
459
460/* Number 0:TABLES-1 of current hashed symbol table. */
461int number;
252b5132 462
54d22525 463int
252b5132
RH
464main ()
465{
466 void applicatee ();
467 void destroy ();
468 char *what ();
469 int *ip;
470
471 number = 0;
472 h = 0;
473 printf ("type h <RETURN> for help\n");
474 for (;;)
475 {
476 printf ("hash_test command: ");
477 gets (answer);
478 command = answer[0];
3882b010 479 command = TOLOWER (command); /* Ecch! */
252b5132
RH
480 switch (command)
481 {
482 case '#':
483 printf ("old hash table #=%d.\n", number);
484 whattable ();
485 break;
486 case '?':
487 for (pp = hashtable; pp < hashtable + TABLES; pp++)
488 {
8fc2faa7
KH
489 printf ("address of hash table #%d control block is %xx\n",
490 pp - hashtable, *pp);
252b5132
RH
491 }
492 break;
493 case 'a':
54d22525 494 hash_traverse (h, applicatee);
252b5132
RH
495 break;
496 case 'd':
54d22525 497 hash_traverse (h, destroy);
252b5132
RH
498 hash_die (h);
499 break;
500 case 'f':
501 p = hash_find (h, name = what ("symbol"));
502 printf ("value of \"%s\" is \"%s\"\n", name, p ? p : "NOT-PRESENT");
503 break;
504 case 'h':
505 printf ("# show old, select new default hash table number\n");
506 printf ("? display all hashtable control block addresses\n");
507 printf ("a apply a simple display-er to each symbol in table\n");
508 printf ("d die: destroy hashtable\n");
509 printf ("f find value of nominated symbol\n");
510 printf ("h this help\n");
511 printf ("i insert value into symbol\n");
512 printf ("j jam value into symbol\n");
513 printf ("n new hashtable\n");
514 printf ("r replace a value with another\n");
515 printf ("s say what %% of table is used\n");
516 printf ("q exit this program\n");
517 printf ("x delete a symbol from table, report its value\n");
518 break;
519 case 'i':
520 p = hash_insert (h, name = what ("symbol"), value = what ("value"));
521 if (p)
522 {
523 printf ("symbol=\"%s\" value=\"%s\" error=%s\n", name, value,
524 p);
525 }
526 break;
527 case 'j':
528 p = hash_jam (h, name = what ("symbol"), value = what ("value"));
529 if (p)
530 {
531 printf ("symbol=\"%s\" value=\"%s\" error=%s\n", name, value, p);
532 }
533 break;
534 case 'n':
535 h = hashtable[number] = (char *) hash_new ();
536 break;
537 case 'q':
538 exit (EXIT_SUCCESS);
539 case 'r':
540 p = hash_replace (h, name = what ("symbol"), value = what ("value"));
541 printf ("old value was \"%s\"\n", p ? p : "{}");
542 break;
543 case 's':
544 hash_say (h, statbuf, STATBUFSIZE);
545 for (ip = statbuf; ip < statbuf + STATBUFSIZE; ip++)
546 {
547 printf ("%d ", *ip);
548 }
549 printf ("\n");
550 break;
551 case 'x':
552 p = hash_delete (h, name = what ("symbol"));
553 printf ("old value was \"%s\"\n", p ? p : "{}");
554 break;
555 default:
556 printf ("I can't understand command \"%c\"\n", command);
557 break;
558 }
559 }
560}
561
562char *
563what (description)
564 char *description;
565{
252b5132
RH
566 printf (" %s : ", description);
567 gets (answer);
a2c36061 568 return xstrdup (answer);
252b5132
RH
569}
570
571void
572destroy (string, value)
573 char *string;
574 char *value;
575{
576 free (string);
577 free (value);
578}
579
252b5132
RH
580void
581applicatee (string, value)
582 char *string;
583 char *value;
584{
585 printf ("%.20s-%.20s\n", string, value);
586}
587
8fc2faa7
KH
588/* Determine number: what hash table to use.
589 Also determine h: points to hash_control. */
590
54d22525 591void
8fc2faa7 592whattable ()
252b5132 593{
252b5132
RH
594 for (;;)
595 {
596 printf (" what hash table (%d:%d) ? ", 0, TABLES - 1);
597 gets (answer);
598 sscanf (answer, "%d", &number);
599 if (number >= 0 && number < TABLES)
600 {
601 h = hashtable[number];
602 if (!h)
603 {
604 printf ("warning: current hash-table-#%d. has no hash-control\n", number);
605 }
606 return;
607 }
608 else
609 {
610 printf ("invalid hash table number: %d\n", number);
611 }
612 }
613}
614
8fc2faa7 615#endif /* TEST */
This page took 0.398238 seconds and 4 git commands to generate.